我试图在
jquery ui自动完成中覆盖一个函数.
当我做
$.ui.autocomplete.prototype._create = function() { var self = this,doc = this.element[ 0 ].ownerDocument,suppressKeyPress; this._value( ... ) ;
我收到了错误._value未定义.
我知道这个背景搞砸了.我该如何解决?
我尝试使用$.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,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",{ 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
解决方法
而不是试图像这样扩展创建功能,我建议去这里
http://jqueryui.com/demos/autocomplete/#custom-data并查看源.它显示了自定义选择事件,这些事件听起来更符合您的需求并且更容易实现.如果所选元素的值为“按Enter键创建此标记”,则只能在select事件中返回false.