Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Sep 18th, 2012  |  syntax: None  |  size: 8.14 KB  |  hits: 21  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. (function($){
  2.     $.widget( "ui.combobox", $.ui.autocomplete,
  3.         {
  4.         options: {
  5.             /* override default values here */
  6.             minLength: 3,
  7.             /* the argument to pass to ajax to get the complete list */
  8.             ajaxGetAll: {get: "all"}
  9.         },
  10.  
  11.         _create: function(){
  12.             if (this.element.is("SELECT")){
  13.                 this._selectInit();
  14.                 return;
  15.             }
  16.  
  17.             $.ui.autocomplete.prototype._create.call(this);
  18.             var input = this.element;
  19.                                          
  20.                          var select=this.element.prev();
  21.                          
  22.             input.addClass( "ui-widget ui-widget-content ui-corner-left ui-state-default ui-combobox-input" );
  23.                         input.attr('id','input_'+select.attr('id'));
  24.                         input.wrap("<span  class='ui-combobox'></span>");
  25.                        
  26.                         $( "<a>" )
  27.                                         .attr( "tabIndex", -1 )
  28.                                         .attr( "title", "Show All Items" )
  29.                                         .insertAfter( input )
  30.                                         .button({
  31.                                                 icons: {
  32.                                                         primary: "ui-icon-triangle-1-s"
  33.                                                 },
  34.                                                 text: false
  35.                                         })
  36.                                         .removeClass( "ui-corner-all" )
  37.                                         .addClass( "ui-corner-right ui-combobox-toggle" )
  38.                                          .click(function(event) {
  39.                                                 // close if already visible
  40.                                                 if ( input.combobox( "widget" ).is( ":visible" ) ) {
  41.                                                         input.combobox( "close" );
  42.                                                         return;
  43.                                                 }
  44.                                                 // when user clicks the show all button, we display the cached full menu
  45.                                                 var data = input.data("combobox");
  46.                                                 clearTimeout( data.closing );
  47.                                                 if (!input.isFullMenu){
  48.                                                         data._swapMenu();
  49.                                                         input.isFullMenu = true;
  50.                                                 }
  51.                                                 /* input/select that are initially hidden (display=none, i.e. second level menus),
  52.                                                    will not have position cordinates until they are visible. */
  53.                                                 input.combobox( "widget" ).css( "display", "block" )
  54.                                                 .position($.extend({ of: input },
  55.                                                         data.options.position
  56.                                                         ));
  57.                                                 input.focus();
  58.                                                 data._trigger( "open" );
  59.                                         });
  60.  
  61.             /* to better handle large lists, put in a queue and process sequentially */
  62.             $(document).queue(function(){
  63.                 var data = input.data("combobox");
  64.                 if ($.isArray(data.options.source)){
  65.                     $.ui.combobox.prototype._renderFullMenu.call(data, data.options.source);
  66.                 }else if (typeof data.options.source === "string") {
  67.                     $.getJSON(data.options.source, data.options.ajaxGetAll , function(source){
  68.                         $.ui.combobox.prototype._renderFullMenu.call(data, source);
  69.                     });
  70.                 }else {
  71.                     $.ui.combobox.prototype._renderFullMenu.call(data, data.source());
  72.                 }
  73.             });
  74.         },
  75.  
  76.         /* initialize the full list of items, this menu will be reused whenever the user clicks the show all button */
  77.         _renderFullMenu: function(source){
  78.             var self = this,
  79.                 input = this.element,
  80.                 ul = input.data( "combobox" ).menu.element,
  81.                 lis = [];
  82.             source = this._normalize(source);
  83.             input.data( "combobox" ).menuAll = input.data( "combobox" ).menu.element.clone(true).appendTo("body");
  84.            
  85.                         for(var i=0; i<source.length; i++){
  86.                
  87.                                 lis[i] = "<li class=\"ui-menu-item "+source[i].option.className+"\" role=\"menuitem\" id=\"menuitem_"+source[i].option.id+"\"><a class=\"ui-corner-all\" tabindex=\"-1\">"+source[i].label+"</a></li>";
  88.             }
  89.             ul.append(lis.join(""));
  90.             this._resizeMenu();
  91.             // setup the rest of the data, and event stuff
  92.             setTimeout(function(){
  93.                 self._setupMenuItem.call(self, ul.children("li"), source );
  94.             }, 0);
  95.             input.isFullMenu = true;
  96.         },
  97.  
  98.         /* incrementally setup the menu items, so the browser can remains responsive when processing thousands of items */
  99.         _setupMenuItem: function( items, source ){
  100.             var self = this,
  101.                 itemsChunk = items.splice(0, 500),
  102.                 sourceChunk = source.splice(0, 500);
  103.             for(var i=0; i<itemsChunk.length; i++){
  104.                 $(itemsChunk[i])
  105.                 .data( "item.autocomplete", sourceChunk[i])
  106.                 .mouseenter(function( event ) {
  107.                     self.menu.activate( event, $(this));
  108.                 })
  109.                 .mouseleave(function() {
  110.                     self.menu.deactivate();
  111.                 });
  112.             }
  113.             if (items.length > 0){
  114.                 setTimeout(function(){
  115.                     self._setupMenuItem.call(self, items, source );
  116.                 }, 0);
  117.             }else { // renderFullMenu for the next combobox.
  118.                 $(document).dequeue();
  119.             }
  120.         },
  121.  
  122.         /* overwrite. make the matching string bold */
  123.         _renderItem: function( ul, item ) {
  124.             var label = item.label.replace( new RegExp(
  125.                 "(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) +
  126.                 ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>" );
  127.             return $( "<li></li>" )
  128.                 .data( "item.autocomplete", item )
  129.                 .append( "<a>" + label + "</a>" )
  130.                 .appendTo( ul );
  131.         },
  132.  
  133.         /* overwrite. to cleanup additional stuff that was added */
  134.         destroy: function() {
  135.             if (this.element.is("SELECT")){
  136.                 this.input.remove();
  137.                 this.element.removeData().show();
  138.                 return;
  139.             }
  140.             // super()
  141.             $.ui.autocomplete.prototype.destroy.call(this);
  142.             // clean up new stuff
  143.             this.element.removeClass( "ui-widget ui-widget-content ui-corner-left" );
  144.             this.button.remove();
  145.         },
  146.  
  147.         /* overwrite. to swap out and preserve the full menu */
  148.         search: function( value, event){
  149.             var input = this.element;
  150.             if (input.isFullMenu){
  151.                 this._swapMenu();
  152.                 input.isFullMenu = false;
  153.             }
  154.             // super()
  155.             $.ui.autocomplete.prototype.search.call(this, value, event);
  156.         },
  157.  
  158.         _change: function( event ){
  159.             abc = this;
  160.             if ( !this.selectedItem ) {
  161.                 var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( this.element.val() ) + "$", "i" ),
  162.                     match = $.grep( this.options.source, function(value) {
  163.                         return matcher.test( value.label );
  164.                     });
  165.                 if (match.length){
  166.                     match[0].option.selected = true;
  167.                 }else {
  168.                     // remove invalid value, as it didn't match anything
  169.                     this.element.val( "" );
  170.                     if (this.options.selectElement) {
  171.                         this.options.selectElement.val( "" );
  172.                     }
  173.                 }
  174.             }                
  175.             // super()
  176.             $.ui.autocomplete.prototype._change.call(this, event);
  177.         },
  178.  
  179.         _swapMenu: function(){
  180.             var input = this.element,
  181.                 data = input.data("combobox"),
  182.                 tmp = data.menuAll;
  183.             data.menuAll = data.menu.element.hide();
  184.             data.menu.element = tmp;
  185.         },
  186.  
  187.         /* build the source array from the options of the select element */
  188.         _selectInit: function(){
  189.             var select = this.element.hide(),
  190.             selected = select.children( ":selected" ),
  191.             value = selected.val() ? selected.text() : "";
  192.             this.options.source = select.children( "option[value!='']" ).map(function() {
  193.                 return { label: $.trim(this.text), option: this };
  194.             }).toArray();
  195.             var userSelectCallback = this.options.select;
  196.             var userSelectedCallback = this.options.selected;
  197.             this.options.select = function(event, ui){
  198.                 ui.item.option.selected = true;
  199.                 if (userSelectCallback) userSelectCallback(event, ui);
  200.                 // compatibility with jQuery UI's combobox.
  201.                 if (userSelectedCallback) userSelectedCallback(event, ui);
  202.             };
  203.             this.options.selectElement = select;
  204.             this.input = $( "<input>" ).insertAfter( select )
  205.                 .val( value ).combobox(this.options);
  206.         }
  207.     }
  208. );
  209. })(jQuery);