2012-02-06 31 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