zoukankan      html  css  js  c++  java
  • autocomplete

    html文件:

    1
    <input id="theInput"type="text" autocomplete="off">
    js文件:

    1
    this.initAutoComplete = function () { 2 $("#theInput").autocomplete({                        //将$("#theInput")绑上autocomplete 3 source: function (request, response) {                 //source 参数 4 $.ajax({ 5 type: 'post', 6 url: "/CustomAccount/GetADUsers", 7 dataType: "json", 8 data: { mail: request.term,isall:false }, //mail:request.term 传进去的是在#theInput中输入的值 9 success: function (data) { 10 response($.map(data, function (item) { 11 return { 12 displayname: item 13 }; 14 })); 15 } 16 }); 17 }, 18 select: function (event, ui) {         //select参数 19 $(this).val(ui.item.displayname); 20 return false; 21 }, 22 max: 10, 23 }).each(function () { 24 $(this).data("autocomplete")._renderItem = function (ul, item) { //重写了autocomplete里面的_renderItem函数 25 return $("<li>") 26 .data("item.autocomplete", item) 27 .append("<a data-type='autocomplete-item'>" + item.displayname + "</a>").attr('title', item.displayname) 28 .appendTo(ul); 29 }; 30 }); 31 };

    前台js调用这个initAutoComplete 函数,利用ajax在controller里面取值,controller

    
    
    CustomAccountController里面的GetADUsers方法:
    1  [HttpPost]
    2  public ActionResult GetADUsers(string mail, Boolean isall)
    3 {
    4   var results = this.systemUserService.FindADUsers(mail, isall);                           //return 一个list<String>,是根据传进来的mail值过滤的
    5   results.AddRange(this.systemUserService.FindADGroups(mail, isall).Select(g => g.Email));//在原来的results里加上另一个根据传进来的mail值过滤的的List<> 
    6
    results.Sort(); //排序
    7
    return this.Json(results, JsonRequestBehavior.AllowGet);
    8
    }

     附件jQuery UI Autocomplete 1.9.1:

      1 /*!
      2  * jQuery UI Autocomplete 1.9.1
      3  * http://jqueryui.com
      4  *
      5  * Copyright 2012 jQuery Foundation and other contributors
      6  * Released under the MIT license.
      7  * http://jquery.org/license
      8  *
      9  * http://api.jqueryui.com/autocomplete/
     10  *
     11  * Depends:
     12  *    jquery.ui.core.js
     13  *    jquery.ui.widget.js
     14  *    jquery.ui.position.js
     15  *    jquery.ui.menu.js
     16  */
     17 (function ($, undefined) {
     18 
     19     // used to prevent race conditions with remote data sources
     20     var requestIndex = 0;
     21 
     22     $.widget("ui.autocomplete", {
     23         version: "1.9.1",
     24         defaultElement: "<input>",
     25         options: {
     26             appendTo: "body",
     27             autoFocus: false,
     28             delay: 300,
     29             minLength: 1,
     30             position: {
     31                 my: "left top",
     32                 at: "left bottom",
     33                 collision: "none"
     34             },
     35             source: null,            
     36             // callbacks
     37             change: null,
     38             close: null,
     39             focus: null,
     40             open: null,
     41             response: null,
     42             search: null,
     43             select: null,
     44              0,
     45             max: 10,
     46 
     47         },
     48 
     49         pending: 0,
     50 
     51         _create: function () {
     52             // Some browsers only repeat keydown events, not keypress events,
     53             // so we use the suppressKeyPress flag to determine if we've already
     54             // handled the keydown event. #7269
     55             // Unfortunately the code for & in keypress is the same as the up arrow,
     56             // so we use the suppressKeyPressRepeat flag to avoid handling keypress
     57             // events when we know the keydown event was used to modify the
     58             // search term. #7799
     59             var suppressKeyPress, suppressKeyPressRepeat, suppressInput;
     60 
     61             this.isMultiLine = this._isMultiLine();
     62             this.valueMethod = this.element[this.element.is("input,textarea") ? "val" : "text"];
     63             this.isNewMenu = true;
     64 
     65             this.element
     66                 .addClass("ui-autocomplete-input")
     67                 .attr("autocomplete", "off");
     68 
     69             this._on(this.element, {
     70                 keydown: function (event) {
     71                     if (this.element.prop("readOnly")) {
     72                         suppressKeyPress = true;
     73                         suppressInput = true;
     74                         suppressKeyPressRepeat = true;
     75                         return;
     76                     }
     77 
     78                     suppressKeyPress = false;
     79                     suppressInput = false;
     80                     suppressKeyPressRepeat = false;
     81                     var keyCode = $.ui.keyCode;
     82                     switch (event.keyCode) {
     83                         case keyCode.PAGE_UP:
     84                             suppressKeyPress = true;
     85                             this._move("previousPage", event);
     86                             break;
     87                         case keyCode.PAGE_DOWN:
     88                             suppressKeyPress = true;
     89                             this._move("nextPage", event);
     90                             break;
     91                         case keyCode.UP:
     92                             suppressKeyPress = true;
     93                             this._keyEvent("previous", event);
     94                             break;
     95                         case keyCode.DOWN:
     96                             suppressKeyPress = true;
     97                             this._keyEvent("next", event);
     98                             break;
     99                         case keyCode.ENTER:
    100                         case keyCode.NUMPAD_ENTER:
    101                             // when menu is open and has focus
    102                             if (this.menu.active) {
    103                                 // #6055 - Opera still allows the keypress to occur
    104                                 // which causes forms to submit
    105                                 suppressKeyPress = true;
    106                                 event.preventDefault();
    107                                 this.menu.select(event);
    108                             }
    109                             break;
    110                         case keyCode.TAB:
    111                             if (this.menu.active) {
    112                                 this.menu.select(event);
    113                             }
    114                             break;
    115                         case keyCode.ESCAPE:
    116                             if (this.menu.element.is(":visible")) {
    117                                 this._value(this.term);
    118                                 this.close(event);
    119                                 // Different browsers have different default behavior for escape
    120                                 // Single press can mean undo or clear
    121                                 // Double press in IE means clear the whole form
    122                                 event.preventDefault();
    123                             }
    124                             break;
    125                         default:
    126                             suppressKeyPressRepeat = true;
    127                             // search timeout should be triggered before the input value is changed
    128                             this._searchTimeout(event);
    129                             break;
    130                     }
    131                 },
    132                 keypress: function (event) {
    133                     if (suppressKeyPress) {
    134                         suppressKeyPress = false;
    135                         event.preventDefault();
    136                         return;
    137                     }
    138                     if (suppressKeyPressRepeat) {
    139                         return;
    140                     }
    141 
    142                     // replicate some key handlers to allow them to repeat in Firefox and Opera
    143                     var keyCode = $.ui.keyCode;
    144                     switch (event.keyCode) {
    145                         case keyCode.PAGE_UP:
    146                             this._move("previousPage", event);
    147                             break;
    148                         case keyCode.PAGE_DOWN:
    149                             this._move("nextPage", event);
    150                             break;
    151                         case keyCode.UP:
    152                             this._keyEvent("previous", event);
    153                             break;
    154                         case keyCode.DOWN:
    155                             this._keyEvent("next", event);
    156                             break;
    157                     }
    158                 },
    159                 input: function (event) {
    160                     if (suppressInput) {
    161                         suppressInput = false;
    162                         event.preventDefault();
    163                         return;
    164                     }
    165                     this._searchTimeout(event);
    166                 },
    167                 focus: function () {
    168                     this.selectedItem = null;
    169                     this.previous = this._value();
    170                 },
    171                 blur: function (event) {
    172                     if (this.cancelBlur) {
    173                         delete this.cancelBlur;
    174                         return;
    175                     }
    176 
    177                     clearTimeout(this.searching);
    178                     this.close(event);
    179                     this._change(event);
    180                 }
    181             });
    182 
    183             this._initSource();
    184             this.menu = $("<ul>")
    185                 .addClass("ui-autocomplete")
    186                 .appendTo(this.document.find(this.options.appendTo || "body")[0])
    187                 .menu({
    188                     // custom key handling for now
    189                     input: $(),
    190                     // disable ARIA support, the live region takes care of that
    191                     role: null
    192                 })
    193                 .zIndex(this.element.zIndex() + 1)
    194                 .hide()
    195                 .data("menu");
    196 
    197             this._on(this.menu.element, {
    198                 mousedown: function (event) {
    199                     // prevent moving focus out of the text field
    200                     event.preventDefault();
    201 
    202                     // IE doesn't prevent moving focus even with event.preventDefault()
    203                     // so we set a flag to know when we should ignore the blur event
    204                     this.cancelBlur = true;
    205                     this._delay(function () {
    206                         delete this.cancelBlur;
    207                     });
    208 
    209                     // clicking on the scrollbar causes focus to shift to the body
    210                     // but we can't detect a mouseup or a click immediately afterward
    211                     // so we have to track the next mousedown and close the menu if
    212                     // the user clicks somewhere outside of the autocomplete
    213                     var menuElement = this.menu.element[0];
    214                     if (!$(event.target).closest(".ui-menu-item").length) {
    215                         this._delay(function () {
    216                             var that = this;
    217                             this.document.one("mousedown", function (event) {
    218                                 if (event.target !== that.element[0] &&
    219                                         event.target !== menuElement &&
    220                                         !$.contains(menuElement, event.target)) {
    221                                     that.close();
    222                                 }
    223                             });
    224                         });
    225                     }
    226                 },
    227                 menufocus: function (event, ui) {
    228                     // #7024 - Prevent accidental activation of menu items in Firefox
    229                     if (this.isNewMenu) {
    230                         this.isNewMenu = false;
    231                         if (event.originalEvent && /^mouse/.test(event.originalEvent.type)) {
    232                             this.menu.blur();
    233 
    234                             this.document.one("mousemove", function () {
    235                                 $(event.target).trigger(event.originalEvent);
    236                             });
    237 
    238                             return;
    239                         }
    240                     }
    241 
    242                     // back compat for _renderItem using item.autocomplete, via #7810
    243                     // TODO remove the fallback, see #8156
    244                     var item = ui.item.data("ui-autocomplete-item") || ui.item.data("item.autocomplete");
    245                     if (false !== this._trigger("focus", event, { item: item })) {
    246                         // use value to match what will end up in the input, if it was a key event
    247                         if (event.originalEvent && /^key/.test(event.originalEvent.type)) {
    248                             this._value(item.value);
    249                         }
    250                     } else {
    251                         // Normally the input is populated with the item's value as the
    252                         // menu is navigated, causing screen readers to notice a change and
    253                         // announce the item. Since the focus event was canceled, this doesn't
    254                         // happen, so we update the live region so that screen readers can
    255                         // still notice the change and announce it.
    256                         this.liveRegion.text(item.value);
    257                     }
    258                 },
    259                 menuselect: function (event, ui) {
    260                     // back compat for _renderItem using item.autocomplete, via #7810
    261                     // TODO remove the fallback, see #8156
    262                     var item = ui.item.data("ui-autocomplete-item") || ui.item.data("item.autocomplete"),
    263                         previous = this.previous;
    264 
    265                     // only trigger when focus was lost (click on menu)
    266                     if (this.element[0] !== this.document[0].activeElement) {
    267                         this.element.focus();
    268                         this.previous = previous;
    269                         // #6109 - IE triggers two focus events and the second
    270                         // is asynchronous, so we need to reset the previous
    271                         // term synchronously and asynchronously :-(
    272                         this._delay(function () {
    273                             this.previous = previous;
    274                             this.selectedItem = item;
    275                         });
    276                     }
    277 
    278                     if (false !== this._trigger("select", event, { item: item })) {
    279                         this._value(item.value);
    280                     }
    281                     // reset the term after the select event
    282                     // this allows custom select handling to work properly
    283                     this.term = this._value();
    284 
    285                     this.close(event);
    286                     this.selectedItem = item;
    287                 }
    288             });
    289 
    290             this.liveRegion = $("<span>", {
    291                 role: "status",
    292                 "aria-live": "polite"
    293             })
    294                 .addClass("ui-helper-hidden-accessible");
    295                 //.insertAfter(this.element);
    296 
    297             if ($.fn.bgiframe) {
    298                 this.menu.element.bgiframe();
    299             }
    300 
    301             // turning off autocomplete prevents the browser from remembering the
    302             // value when navigating through history, so we re-enable autocomplete
    303             // if the page is unloaded before the widget is destroyed. #7790
    304             this._on(this.window, {
    305                 beforeunload: function () {
    306                     this.element.removeAttr("autocomplete");
    307                 }
    308             });
    309         },//end _create
    310 
    311         _destroy: function () {
    312             clearTimeout(this.searching);
    313             this.element
    314                 .removeClass("ui-autocomplete-input")
    315                 .removeAttr("autocomplete");
    316             this.menu.element.remove();
    317             this.liveRegion.remove();
    318         },
    319 
    320         _setOption: function (key, value) {
    321             this._super(key, value);
    322             if (key === "source") {
    323                 this._initSource();
    324             }
    325             if (key === "appendTo") {
    326                 this.menu.element.appendTo(this.document.find(value || "body")[0]);
    327             }
    328             if (key === "disabled" && value && this.xhr) {
    329                 this.xhr.abort();
    330             }
    331         },
    332 
    333         _isMultiLine: function () {
    334             // Textareas are always multi-line
    335             if (this.element.is("textarea")) {
    336                 return true;
    337             }
    338             // Inputs are always single-line, even if inside a contentEditable element
    339             // IE also treats inputs as contentEditable
    340             if (this.element.is("input")) {
    341                 return false;
    342             }
    343             // All other element types are determined by whether or not they're contentEditable
    344             return this.element.prop("isContentEditable");
    345         },
    346 
    347         _initSource: function () {
    348             var array, url,
    349                 that = this;
    350             if ($.isArray(this.options.source)) {
    351                 array = this.options.source;
    352                 this.source = function (request, response) {
    353                     response($.ui.autocomplete.filter(array, request.term));
    354                 };
    355             } else if (typeof this.options.source === "string") {
    356                 url = this.options.source;
    357                 this.source = function (request, response) {
    358                     if (that.xhr) {
    359                         that.xhr.abort();
    360                     }
    361                     that.xhr = $.ajax({
    362                         url: url,
    363                         data: request,
    364                         dataType: "json",
    365                         success: function (data) {
    366                             response(data);
    367                         },
    368                         error: function () {
    369                             response([]);
    370                         }
    371                     });
    372                 };
    373             } else {
    374                 this.source = this.options.source;
    375             }
    376         },
    377 
    378         _searchTimeout: function (event) {
    379             clearTimeout(this.searching);
    380             this.searching = this._delay(function () {
    381                 // only search if the value has changed
    382                 if (this.term !== this._value()) {
    383                     this.selectedItem = null;
    384                     this.search(null, event);
    385                 }
    386             }, this.options.delay);
    387         },
    388 
    389         search: function (value, event) {
    390             value = value != null ? value : this._value();
    391 
    392             // always save the actual value, not the one passed as an argument
    393             this.term = this._value();
    394 
    395             if (value.length < this.options.minLength) {
    396                 return this.close(event);
    397             }
    398 
    399             if (this._trigger("search", event) === false) {
    400                 return;
    401             }
    402 
    403             return this._search(value);
    404         },
    405 
    406         _search: function (value) {
    407             this.pending++;
    408             this.element.addClass("ui-autocomplete-loading");
    409             this.cancelSearch = false;
    410 
    411             this.source({ term: value }, this._response());
    412         },
    413 
    414         _response: function () {
    415             var that = this,
    416                 index = ++requestIndex;
    417 
    418             return function (content) {
    419                 if (index === requestIndex) {
    420                     that.__response(content);
    421                 }
    422 
    423                 that.pending--;
    424                 if (!that.pending) {
    425                     that.element.removeClass("ui-autocomplete-loading");
    426                 }
    427             };
    428         },
    429 
    430         __response: function (content) {
    431             if (content) {
    432                 content = this._normalize(content);
    433             }
    434             this._trigger("response", null, { content: content });
    435             //content && content.length && 
    436             if (!this.options.disabled && !this.cancelSearch) {
    437                 this._suggest(content);
    438                 this._trigger("open");
    439             } else {
    440                 // use ._close() instead of .close() so we don't cancel future searches
    441                 this._close();
    442             }
    443         },
    444 
    445         close: function (event) {
    446             this.cancelSearch = true;
    447             this._close(event);
    448         },
    449 
    450         _close: function (event) {
    451             if (this.menu.element.is(":visible")) {
    452                 this.menu.element.hide();
    453                 this.menu.blur();
    454                 this.isNewMenu = true;
    455                 this._trigger("close", event);
    456             }
    457         },
    458 
    459         _change: function (event) {
    460             if (this.previous !== this._value()) {
    461                 this._trigger("change", event, { item: this.selectedItem });
    462             }
    463         },
    464 
    465         _normalize: function (items) {
    466             // assume all items have the right format when the first item is complete
    467             if (items.length && items[0].label && items[0].value) {
    468                 return items;
    469             }
    470             return $.map(items, function (item) {
    471                 if (typeof item === "string") {
    472                     return {
    473                         label: item,
    474                         value: item
    475                     };
    476                 }
    477                 return $.extend({
    478                     label: item.label || item.value,
    479                     value: item.value || item.label
    480                 }, item);
    481             });
    482         },
    483 
    484         _suggest: function (items) {
    485             var ul = this.menu.element
    486                 .empty()
    487                 .zIndex(this.element.zIndex() + 1);
    488             this._renderMenu(ul, items);
    489             this.menu.refresh();
    490             // size and position menu
    491             ul.show();
    492             this._resizeMenu();
    493             ul.position($.extend({
    494                 of: this.element
    495             }, this.options.position));
    496 
    497             if (this.options.autoFocus) {
    498                 this.menu.next();
    499             }
    500         },
    501 
    502         _resizeMenu: function () {
    503             var that = this;
    504             var ul = this.menu.element;
    505             
    506             ul.outerWidth(                
    507                 this.element.outerWidth()
    508             );
    509             
    510             
    511         },
    512 
    513         _limitNumberOfItems:function(available) {
    514             return this.options.max && this.options.max < available
    515             ? this.options.max
    516             : available;
    517         },
    518 
    519         _renderMenu: function (ul, items) {
    520             var that = this;
    521             var max = that._limitNumberOfItems(items.length);
    522             var num = 0;
    523             for (var i = 0; i < max; i++) {      
    524                     that._renderItemData(ul, items[i]);
    525                     num++;  
    526             }
    527             //$.each(items, function (index, item) {
    528             //    that._renderItemData(ul, item);
    529             //    num++;
    530             //});           
    531             var bottomlist = "<span class='autocomplete_bottom'>" +
    532                                 "<span class='firstline'>Showing " +num+" Users</span>" +
    533                                 "<span class='secondline' >"+
    534                                     "<span class='sprite-icon sprite-icon-info-16x16'></span>"+
    535                                     "<span class='autocomplete_bottom_txt'>Please type in more characters to narrow down the results.</span>" +
    536                                 "</span></span>";
    537             ul.append(bottomlist);
    538             if (num == 0) {
    539                 $('.secondline').hide();
    540                 $('.firstline').text('No search results.');
    541             }
    542         },
    543 
    544         _renderItemData: function (ul, item) {
    545             return this._renderItem(ul, item).data("ui-autocomplete-item", item);
    546         },
    547 
    548         _renderItem: function (ul, item) {
    549             return $("<li>")
    550                 .append($("<a>").text(item.label))
    551                 .appendTo(ul);
    552         },
    553 
    554         _move: function (direction, event) {
    555             if (!this.menu.element.is(":visible")) {
    556                 this.search(null, event);
    557                 return;
    558             }
    559             if (this.menu.isFirstItem() && /^previous/.test(direction) ||
    560                     this.menu.isLastItem() && /^next/.test(direction)) {
    561                 this._value(this.term);
    562                 this.menu.blur();
    563                 return;
    564             }
    565             this.menu[direction](event);
    566         },
    567 
    568         widget: function () {
    569             return this.menu.element;
    570         },
    571 
    572         _value: function () {
    573             return this.valueMethod.apply(this.element, arguments);
    574         },
    575 
    576         _keyEvent: function (keyEvent, event) {
    577             if (!this.isMultiLine || this.menu.element.is(":visible")) {
    578                 this._move(keyEvent, event);
    579 
    580                 // prevents moving cursor to beginning/end of the text field in some browsers
    581                 event.preventDefault();
    582             }
    583         }
    584     });//end $.widget()
    585 
    586 
    587     $.extend($.ui.autocomplete, {
    588         escapeRegex: function (value) {
    589             return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
    590         },
    591         filter: function (array, term) {
    592             var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
    593             return $.grep(array, function (value) {
    594                 return matcher.test(value.label || value.value || value);
    595             });
    596         }
    597     });
    598 
    599     // live region extension, adding a `messages` option
    600     // NOTE: This is an experimental API. We are still investigating
    601     // a full solution for string manipulation and internationalization.
    602     $.widget("ui.autocomplete", $.ui.autocomplete, {
    603         options: {
    604             messages: {
    605                 noResults: "No search results.",
    606                 results: function (amount) {
    607                     return amount + (amount > 1 ? " results are" : " result is") +
    608                         " available, use up and down arrow keys to navigate.";
    609                 }
    610             }
    611         },
    612 
    613         __response: function (content) {
    614             var message;
    615             this._superApply(arguments);
    616             if (this.options.disabled || this.cancelSearch) {
    617                 return;
    618             }
    619             if (content && content.length) {
    620                 message = this.options.messages.results(content.length);
    621             } else {
    622                 message = this.options.messages.noResults;
    623             }
    624             this.liveRegion.text(message).css('position','');
    625         }
    626     });
    627 
    628 
    629 }(jQuery));
    View Code
  • 相关阅读:
    lvs+keepalived+DR搭建高可用集群
    mysql主从搭建
    按钮点击动态变化
    CSS Module
    CSS实现平行四边形布局
    CSS shapes布局
    SVG SMIL animation动画详解
    Ajax
    jQuery相关宽高
    CSSOM视图
  • 原文地址:https://www.cnblogs.com/mousehhq/p/4365987.html
Copyright © 2011-2022 走看看