2011-03-05 43 views
4

我想覆盖jquery ui自动完成功能。“这个”问题在jquery

当我做

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

我得到的this._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

_value? 或 val? – 2011-03-05 06:26:47

+4

1)为什么你用','而不是'''结束你的行? 2)你的'self'应该在函数之外声明是有用的。 3)什么是_value?它在哪里定义? 4)你想完成什么? – 2011-03-05 06:27:08

+1

你可以添加更多的代码 – 2011-03-05 06:30:05

回答

1

而不是试图扩展这样的创建功能,我推荐去这里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定义=函数(){this._value ..})

但是,如果我这样做:

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

我会得到_value错误。我的jquery.ui.js基本上是jquery ui的压缩版本,所有组件都是1.8.10。

什么可能是这个问题的来源?

+0

我们已经注意到在所有组件中使用jquery ui文件时出现问题......还没有弄清楚。 – 2011-08-16 01:40:51