"this" problem in jquery

I am trying to overwrite a function in jquery ui autocomplete.

When i do

$.ui.autocomplete.prototype._create = function() { var self = this, doc = this.element[ 0 ].ownerDocument, suppressKeyPress; this._value( ... ) ; 

I get this._value undefined error.

I know that this context is confused. How to fix it?

I am trying to use $.proxy , but then I do not know how to refer to the initial closing context of $.ui.autocomplete .

EDIT:

Ok, let me break it. I want to edit jquery autocomplete so that when a user clicks on user-generated content, he simply ignores it, and does not enter it.

The original question comes from this: JQuery autocomplete. If the item is not found, display "Press Enter to paste into autocomplete"?

So let's break the questions:

I am expanding this function:

 $.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 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(); } }; 

which is directly copied from jquery.ui.autcomplete.js

For your convenience, jquery autocomplete is found https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js

+4
source share
2 answers

Instead of trying to extend the create function like this, I recommend going here http://jqueryui.com/demos/autocomplete/#custom-data and looking at the source code. It features custom selection events that sound more according to what you need and are easier to insert. If the value of the selected item is "Press enter to create this tag", you can simply return false to the selected event.

+1
source

Some kind of breakthrough:

So, obviously, if I do the following:

 <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> 

I will not get any errors. (The value of this._value is defined inside $ .ui.autocomplete.prototype._create = function () {this._value ..})

However, if I do this:

 <script src="/static/lib/jqueryui/jquery-ui.js"></script> 

I will get the _value error. My jquery.ui.js is basically a compressed version of jquery ui with all 1.8.10 components.

What could be the source of this problem?

0
source

Source: https://habr.com/ru/post/1342391/


All Articles