我试图在jquery ui autocomplete中覆盖一个函数。
当我这样做时
$.ui.autocomplete.prototype._create = function() {
var self = this,
doc = this.element[ 0 ].ownerDocument,
suppressKeyPress;
this._value( ... ) ;
我收到了错误._value未定义。
我知道this
上下文搞砸了。我该如何解决?
我尝试使用$.proxy
,但后来我不知道如何引用原始$.ui.autocomplete
内部闭包的上下文。
编辑:
好的,让我打破这个。我想编辑jquery自动完成功能,这样当用户点击自定义内容时,它将忽略它而不是输入它。
原始问题来自:JQuery Autocomplete. If item cannot be found, display "Press Enter to insert into autocomplete"?
让我们分解问题:
我正在扩展这个功能:
$.ui.autocomplete.prototype._create = function() {
console.log(this, $.ui.autocomplete);
var self = this,
doc = this.element[ 0 ].ownerDocument,
suppressKeyPress;
this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ];
this.element
.addClass( "ui-autocomplete-input" )
.attr( "autocomplete", "off" )
// TODO verify these actually work as intended
.attr({
role: "textbox",
"aria-autocomplete": "list",
"aria-haspopup": "true"
})
.bind( "keydown.autocomplete", function( event ) {
if ( self.options.disabled || self.element.attr( "readonly" ) ) {
return;
}
suppressKeyPress = false;
var keyCode = $.ui.keyCode;
switch( event.keyCode ) {
case keyCode.PAGE_UP:
self._move( "previousPage", event );
break;
case keyCode.PAGE_DOWN:
self._move( "nextPage", event );
break;
case keyCode.UP:
self._move( "previous", event );
// prevent moving cursor to beginning of text field in some browsers
event.preventDefault();
break;
case keyCode.DOWN:
self._move( "next", event );
// prevent moving cursor to end of text field in some browsers
event.preventDefault();
break;
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
// when menu is open and has focus
if ( self.menu.active ) {
// #6055 - Opera still allows the keypress to occur
// which causes forms to submit
suppressKeyPress = true;
event.preventDefault();
}
//passthrough - ENTER and TAB both select the current element
case keyCode.TAB:
if ( !self.menu.active ) {
return;
}
self.menu.select( event );
break;
case keyCode.ESCAPE:
self._value( self.term );
self.close( event );
break;
default:
// keypress is triggered before the input value is changed
clearTimeout( self.searching );
self.searching = setTimeout(function() {
// only search if the value has changed
if ( self.term != self._value() ) {
self.selectedItem = null;
self.search( null, event );
}
}, self.options.delay );
break;
}
})
.bind( "keypress.autocomplete", function( event ) {
if ( suppressKeyPress ) {
suppressKeyPress = false;
event.preventDefault();
}
})
.bind( "focus.autocomplete", function() {
if ( self.options.disabled ) {
return;
}
self.selectedItem = null;
self.previous = self._value();
})
.bind( "blur.autocomplete", function( event ) {
if ( self.options.disabled ) {
return;
}
clearTimeout( self.searching );
// clicks on the menu (or a button to trigger a search) will cause a blur event
self.closing = setTimeout(function() {
self.close( event );
self._change( event );
}, 150 );
});
this._initSource();
this.response = function() {
return self._response.apply( self, arguments );
};
this.menu = $( "<ul></ul>" )
.addClass( "ui-autocomplete" )
.appendTo( $( this.options.appendTo || "body", doc )[0] )
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
.mousedown(function( event ) {
// clicking on the scrollbar causes focus to shift to the body
// but we can't detect a mouseup or a click immediately afterward
// so we have to track the next mousedown and close the menu if
// the user clicks somewhere outside of the autocomplete
var menuElement = self.menu.element[ 0 ];
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
setTimeout(function() {
$( document ).one( 'mousedown', function( event ) {
if ( event.target !== self.element[ 0 ] &&
event.target !== menuElement &&
!$.contains( menuElement, event.target ) ) {
self.close();
}
});
}, 1 );
}
// use another timeout to make sure the blur-event-handler on the input was already triggered
setTimeout(function() {
clearTimeout( self.closing );
}, 13);
})
.menu({
// custom key handling for now
input: $(),
focus: function( event, ui ) {
var item = ui.item.data( "item.autocomplete" );
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
// use value to match what will end up in the input, if it was a key event
if ( /^key/.test(event.originalEvent.type) ) {
self._value( item.value );
}
}
},
select: function( event, ui ) {
console.log(event, ui);
var item = ui.item.data( "item.autocomplete" ),
previous = self.previous;
// only trigger when focus was lost (click on menu)
if ( self.element[0] !== doc.activeElement ) {
self.element.focus();
self.previous = previous;
// #6109 - IE triggers two focus events and the second
// is asynchronous, so we need to reset the previous
// term synchronously and asynchronously :-(
setTimeout(function() {
self.previous = previous;
self.selectedItem = item;
}, 1);
}
if ( false !== self._trigger( "select", event, { item: item } ) ) {
self._value( item.value );
}
// reset the term after the select event
// this allows custom select handling to work properly
self.term = self._value();
self.close( event );
self.selectedItem = item;
},
blur: function( event, ui ) {
// don't set the value of the text field if it's already correct
// this prevents moving the cursor unnecessarily
if ( self.menu.element.is(":visible") &&
( self._value() !== self.term ) ) {
self._value( self.term );
}
}
})
.zIndex( this.element.zIndex() + 1 )
.hide()
.data( "menu" );
if ( $.fn.bgiframe ) {
this.menu.element.bgiframe();
}
};
直接从jquery.ui.autcomplete.js
复制为方便起见,找到了jquery自动填充https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js
答案 0 :(得分:1)
我没有尝试像这样扩展创建功能,而是建议去http://jqueryui.com/demos/autocomplete/#custom-data并查看来源。它显示了自定义选择事件,这些事件听起来更符合您的需求并且更容易实现。如果所选元素的值为“按Enter键创建此标记”,则只能在select事件中返回false。
答案 1 :(得分:0)
某种突破:
显然,如果我做以下事情:
<script src='/static/lib/ui-src/jquery.ui.core.js'></script>
<script src='/static/lib/ui-src/jquery.ui.widget.js'></script>
<script src='/static/lib/ui-src/jquery.ui.menu.js'></script>
<script src='/static/lib/ui-src/jquery.ui.autocomplete.js'></script>
我不会有任何错误。 (含义this._value在$ .ui.autocomplete.prototype._create = function(){this._value ..})中定义。
但是,如果我这样做:
<script src="/static/lib/jqueryui/jquery-ui.js"></script>
我会得到_value错误。我的jquery.ui.js基本上是jquery ui的压缩版本,所有组件都是1.8.10。
这个问题可能是什么原因?