«Эта» проблема в jquery

4

Я пытаюсь перезаписать функцию в 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

  • 0
    _значение ? или вал?
  • 4
    1) Почему вы прекращаете свои линии с А , а ; ? 2) Ваша self должна быть объявлена вне функции, чтобы быть полезной вообще. 3) Что такое _value ? Где это определено? 4) Чего вы пытаетесь достичь?
Показать ещё 7 комментариев
Теги:

2 ответа

1

Вместо того, чтобы пытаться расширить функцию create, как это, я рекомендую перейти сюда http://jqueryui.com/demos/autocomplete/#custom-data и просмотреть исходный код. Он показывает пользовательские события выбора, которые звучат больше в соответствии с тем, что вам нужно, и их легче вставить. Если значение выбранного элемента "Нажмите enter, чтобы создать этот тег", вы можете просто вернуть false в выбранное событие.

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.

Что может быть источником этой проблемы?

  • 0
    Мы заметили проблему при использовании файла jquery ui со всеми компонентами ... еще не разобрались.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню