Я пытаюсь перезаписать функцию в jquery ui autocomplete.
Когда я делаю
$.ui.autocomplete.prototype._create = function() {
var self = this,
doc = this.element[ 0 ].ownerDocument,
suppressKeyPress;
this._value( ... ) ;
Я получаю ошибку this._value undefined.
Я знаю, что контекст this
запутан. Как это исправить?
Я пытаюсь использовать $.proxy
, но тогда я не знаю, как ссылаться на контекст исходного закрытия $.ui.autocomplete
.
ИЗМЕНИТЬ:
Хорошо, позволь мне сломать это. Я хочу отредактировать автозаполнение jquery таким образом, что когда пользователь нажимает на пользовательский контент, он просто игнорирует его, а не вводит его.
Оригинальный вопрос исходит из этого: Автозаполнение JQuery. Если элемент не найден, отобразите "Нажмите Enter, чтобы вставить в автозаполнение" ?
Итак, давайте сломаем вопросы:
Я расширяю эту функцию:
$.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();
}
};
который непосредственно скопирован из jquery.ui.autcomplete.js
Для вашего удобства, автозаполнение jquery найдено https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.autocomplete.js
Вместо того, чтобы пытаться расширить функцию create, как это, я рекомендую перейти сюда http://jqueryui.com/demos/autocomplete/#custom-data и просмотреть исходный код. Он показывает пользовательские события выбора, которые звучат больше в соответствии с тем, что вам нужно, и их легче вставить. Если значение выбранного элемента "Нажмите enter, чтобы создать этот тег", вы можете просто вернуть false в выбранное событие.
Какой-то прорыв:
Таким образом, очевидно, если я сделаю следующее:
<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.
Что может быть источником этой проблемы?
,
а;
? 2) Вашаself
должна быть объявлена вне функции, чтобы быть полезной вообще. 3) Что такое_value
? Где это определено? 4) Чего вы пытаетесь достичь?