2012-02-06 38 views
1

我有玩過:自動完成觸發兩個特殊字符和兩個數據源

https://github.com/experteer/autocompleteTrigger/ 

如下:

(function ($, window, document, undefined) { 
$.widget("ui.autocompleteTrigger", { 

    //Options to be used as defaults 
    options: { 
     triggerStart: "%{", 
     triggerEnd: "}" 
    }, 


    _create: function() { 
     this.triggered = false; 
     this.triggered2 = false; 
     this.element.autocomplete($.extend({ 

      search: function() { 
       /** 
       * @description only make a request and suggest items if acTrigger.triggered is true 
       */ 
       var acTrigger = $(this).data("autocompleteTrigger"); 
       if (acTrigger.triggered == true || acTrigger.triggered2 == true) { 
        return true; 
       } else { 
        return false; 
       } 
      }, 
      select: function (event, ui) { 
       /** 
       * @description if a item is selected, insert the value between triggerStart and triggerEnd 
       */ 
       var acTrigger = $(this).data("autocompleteTrigger"); 
       var text = this.value; 
       var trigger = acTrigger.options.triggerStart; 
       var trigger2 = acTrigger.options.triggerStart2; 
       var cursorPosition = acTrigger.getCursorPosition(); 
       var lastTrigger1Position = text.substring(0, cursorPosition).lastIndexOf(trigger); 
       var lastTrigger2Position = text.substring(0, cursorPosition).lastIndexOf(trigger2); 
       var lastTriggerPosition; 
       if (lastTrigger1Position > lastTrigger2Position) { 
        lastTriggerPosition = lastTrigger1Position; 
       } else { 
        lastTriggerPosition = lastTrigger2Position; 
       } 

       var firstTextPart = text.substring(0, lastTriggerPosition + trigger.length) + ui.item.value + 
        acTrigger.options.triggerEnd; 
       this.value = firstTextPart + text.substring(cursorPosition, text.length); 

       acTrigger.triggered = false; 
       acTrigger.triggered2 = false; 

       // set cursor position after the autocompleted text 
       this.selectionStart = firstTextPart.length; 
       this.selectionEnd = firstTextPart.length; 

       return false; 
      }, 
      focus: function() { 
       /** 
       * @description prevent to replace the hole text, if a item is hovered 
       */ 

       return false; 
      }, 
      minLength: 0 
     }, this.options)) 

    .bind("keyup", function (event) { 
     /** 
     * @description Bind to keyup-events to detect text changes. 
     * If the trigger is found before the cursor, autocomplete will be called 
     */ 
     var acTrigger = $(this).data("autocompleteTrigger"); 

     if (event.keyCode != $.ui.keyCode.UP && event.keyCode != $.ui.keyCode.DOWN) { 
      var text = this.value; 
      var textLength = text.length; 
      var cursorPosition = acTrigger.getCursorPosition(); 
      var lastString; 
      var query; 
      var lastTriggerPosition; 
      var lastTriggerPosition2; 
      var trigger = acTrigger.options.triggerStart; 
      var trigger2 = acTrigger.options.triggerStart2; 

      if (acTrigger.triggered && text != "") { 
       // call autocomplete with the string after the trigger 
       // Example: triggerStart = @, string is '@foo' -> query string is 'foo' 
       $(this).autocomplete("option", "source", '/UITests/LookupFirst'); 
       lastTriggerPosition = text.substring(0, cursorPosition).lastIndexOf(trigger); 
       query = text.substring(lastTriggerPosition + trigger.length, cursorPosition); 
       $(this).autocomplete("search", query); 


      } 
      if (acTrigger.triggered2 && text != "") { 
       // call autocomplete with the string after the trigger 
       // Example: triggerStart = @, string is '@foo' -> query string is 'foo' 
       $(this).autocomplete("option", "source", '/UITests/LookupSec'); 
       lastTriggerPosition2 = text.substring(0, cursorPosition).lastIndexOf(trigger2); 
       query = text.substring(lastTriggerPosition2 + trigger2.length, cursorPosition); 
       $(this).autocomplete("search", query); 
      } 
      else if (textLength >= trigger.length) { 
       // set trigged to true, if the string before the cursor is triggerStart 
       lastString = text.substring(cursorPosition - trigger.length, cursorPosition); 
       acTrigger.triggered = (lastString === trigger); 
       acTrigger.triggered2 = (lastString === trigger2); 
      } 
     } 
    }); 
    }, 

    /** 
    * @description Destroy an instantiated plugin and clean up modifications the widget has made to the DOM 
    */ 
    destroy: function() { 

     // this.element.removeStuff(); 
     // For UI 1.8, destroy must be invoked from the 
     // base widget 
     $.Widget.prototype.destroy.call(this); 
     // For UI 1.9, define _destroy instead and don't 
     // worry about 
     // calling the base widget 
    }, 



    /** 
    * @description calculates the the current cursor position in the bound textfield, area,... 
    * @returns {int} the position of the cursor. 
    */ 
    getCursorPosition: function() { 
     var elem = this.element[0]; 
     var position = 0; 

     // dom 3 
     if (elem.selectionStart >= 0) { 
      position = elem.selectionStart; 
      // IE 
     } else if (elem.ownerDocument.selection) { 
      var r = elem.ownerDocument.selection.createRange(); 
      if (!r) return data; 
      var tr = elem.createTextRange(), ctr = tr.duplicate(); 

      tr.moveToBookmark(r.getBookmark()); 
      ctr.setEndPoint('EndToStart', tr); 
      position = ctr.text.length; 
     } 

     return position; 
    } 

}); 
})(jQuery, window, document); 

,並在視圖:

$('input,textarea').autocompleteTrigger({ 
    triggerStart: '#', 
    triggerEnd: '', 
    triggerStart2: '@@', 
    sourceOption1: '/UITests/LookupFirst', 
    sourceOption2: '/UITests/LookupSec' 

}); 

控制器的操作方法( LookupSec是相同的)是:

public ActionResult LookupFirst(string q) 
    { 
     var list = new List<string>() 
           { 
            "Asp", 
            "BASIC", 
            "COBOL", 
            "ColdFusion", 
            "Erlang", 
            "Fortran", 
            "Groovy", 
            "Java", 
            "JavaScript", 
            "Lisp", 
            "Perl", 
            "PHP", 
            "Python", 
            "Ruby", 
            "Scala", 
            "Scheme" 
           }; 
     IEnumerable<string> data; 
     if (q != null) 
     { 

      data = list.Where(x => x.StartsWith(q)); 
     } 
     else 
      data = list; 
     return Json(data, JsonRequestBehavior.AllowGet); 

    } 

現在它支持兩個觸發器@和#兩個數據源爲每一個...

問題是搜索犯規工作了,一切正常「幾乎」,但是當我輸入類似「@as」它應該過濾結果,但它不!

任何想法,爲什麼這不工作?

+0

你有沒有考慮到區分大小寫?即改變爲'data = list.Where(x => x.ToUpper()。StartsWith(q.ToUpper()));' – Smudge202 2012-02-06 08:25:44

+0

它只是一個概念證明,我試過大寫和小寫字母都沒有工作根本沒有,實際上操作方法從來沒有調用任何查詢(q始終爲空或空!) – Stacker 2012-02-06 08:29:04

回答

1

你似乎使用 LookupSec動作與 @字符,但在你的問題,你只顯示其與 #濾波特性相關的 LookupFirst行動進行過濾。我已測試過您的代碼,並且它適用於 #而不適用於 @,因爲 LookupSec不存在。

一旦我定義了 LookupSec控制器操作,它就可以用於兩者。現在你要小心,因爲你現在已經在widget中對這些動作名稱進行了硬編碼,所以 sourceOption1sourceOption2參數將被完全忽略。

的jQuery自動完成所使用的查詢字符串參數稱爲term,不q這樣,現在解決您的控制器的動作也沒有任何過濾:

public ActionResult LookupFirst(string term) 
{ 
    ... 
} 
+0

這兩個操作方法是相同的,這就是爲什麼我只顯示一個,但填充和顯示自動完成工作,搜索(過濾器)功能不會 – Stacker 2012-02-06 08:59:28

+1

@Stacker,好的,看看我更新的答案。 – 2012-02-06 09:02:48

+0

太棒了!,謝謝,這麼簡單,我不敢相信我沒有注意到這一點! – Stacker 2012-02-06 09:17:31