Advertisement
Guest User

Untitled

a guest
Aug 8th, 2012
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function ($) {
  2.        
  3.         var DropList = function (element, settings, callback) {
  4.        
  5.                 var self = this,
  6.                         doc = $(document),
  7.                         defaults = {
  8.                                 direction: 'auto',
  9.                                 customScroll: false,
  10.                                 namespaces: {
  11.                                         droplist: 'droplist',
  12.                                         clickout: 'droplistClickout'
  13.                                 }
  14.                         },
  15.        
  16.                         /*
  17.                         PRIVATE METHODS
  18.                         ==============================================================================
  19.                         */
  20.                        
  21.                         setText = function (str) {
  22.                                 self.option.html(str);
  23.                         },
  24.                        
  25.                         customScroll = function () {
  26.                                
  27.                                 var h1 = settings.height || 150,
  28.                                         h2 = self.dropdown.height();
  29.                                
  30.                                 if (h2 > h1) {
  31.                                         self.list.css('height', h1 + 'px').jScrollPane({
  32.                                                 showArrows: false
  33.                                         });
  34.                                 }
  35.                        
  36.                         },
  37.                        
  38.                         layoutController = function () {
  39.                                
  40.                                 // config
  41.                                 var w = {};
  42.                                 w.obj = self.obj.width;
  43.                                 w.option = w.obj - self.drop.outerWidth(true) - 7;
  44.                                 w.dropdown = w.obj - (self.dropdown.outerWidth(true) - self.dropdown.width());
  45.                                
  46.                                 // set
  47.                                 self.option.css('width', w.option + 'px');
  48.                                 self.dropdown.css('width', w.dropdown + 'px');
  49.                        
  50.                         },
  51.                        
  52.                         options2list = function (data) {
  53.                                
  54.                                 var output = '<ul>';
  55.                                 data.each(function () {
  56.                                         var selected = $(this).prop('selected') ? 'selected' : '';
  57.                                         output += '<li class="' + selected + '"><a href="' + $(this).val() + '">' + $(this).text() + '</a></li>\t';
  58.                                 });
  59.                                 output += '</ul>';
  60.                                 return output;
  61.                        
  62.                         },
  63.                        
  64.                         setInitialTitle = function () {
  65.                        
  66.                                 if (self.obj.title !== '') {
  67.                                         setText(self.obj.title);
  68.                                 }
  69.                        
  70.                         },
  71.                        
  72.                         setInitialSelected = function () {
  73.                                
  74.                                 var selectedItem = self.list.find('.selected:first');
  75.                                 if (selectedItem.length === 1) {
  76.                                         self.set(selectedItem);
  77.                                 }
  78.                                 else {
  79.                                         self.set(self.list.find('li:first'));
  80.                                 }
  81.                        
  82.                         };
  83.                        
  84.                 /*
  85.                 SETTINGS
  86.                 ==============================================================================
  87.                 */
  88.                
  89.                 settings = $.extend({}, defaults, settings || {});
  90.                
  91.                 /*
  92.                 PUBLIC METHODS
  93.                 ==============================================================================
  94.                 */
  95.                
  96.                 self.open = function () {
  97.                
  98.                         // just show
  99.                         self.dropdown.show();
  100.                         self.wrapper.addClass('droplist-active');
  101.                        
  102.                         // auto direction
  103.                         if (settings.direction === 'auto') {
  104.                                 var distanceFromBottom = (self.select.height() + self.wrapper.offset().top - doc.scrollTop() - $(window).height()) * -1,
  105.                                         objHeight = self.select.height() + self.dropdown.height();
  106.                                 if (distanceFromBottom < objHeight) {
  107.                                         self.wrapper.addClass('droplist-up');
  108.                                 } else {
  109.                                         self.wrapper.removeClass('droplist-up');
  110.                                 }
  111.                         } else if (settings.direction === 'up') {
  112.                                 self.wrapper.addClass('droplist-up');
  113.                         }
  114.                        
  115.                         // focus selected item (auto scroll)
  116.                         self.listItems.filter('.selected').focus();
  117.                        
  118.                         // events (clickout / ESC key / type-ahead)
  119.                         self.typedKeys = '';
  120.                        
  121.                         doc.bind('click.' + settings.namespaces.clickout, function (e) {
  122.                                
  123.                                 // clickout
  124.                                 if ($(e.target).closest('.droplist').length === 0) {
  125.                                         self.close();
  126.                                 }
  127.                        
  128.                         }).bind('keyup.' + settings.namespaces.clickout, function (e) {
  129.                        
  130.                                 var keycode,
  131.                                         key,
  132.                                         focused,
  133.                                         current,
  134.                                         next;
  135.                        
  136.                                 // get keycode
  137.                                 if (e === null) { // ie
  138.                                         keycode = event.keyCode;
  139.                                 }
  140.                                 else { // mozilla
  141.                                         keycode = e.which;
  142.                                 }
  143.                                
  144.                                 // esc
  145.                                 if (keycode === 27) {
  146.                                         self.close();
  147.                                 }
  148.                                
  149.                                 // space
  150.                                 else if (keycode === 32) {
  151.                                        
  152.                                         focused = $('a:focus');
  153.                                         current = (focused.parent().is('li')) ? focused.parent() : self.listItems.first();
  154.                                        
  155.                                         self.set(current);
  156.                                         self.close();
  157.                                
  158.                                 }
  159.                                
  160.                                 // type-ahead support
  161.                                 else if (keycode >= 0x30 && keycode <= 0x7a) {
  162.                                        
  163.                                         // key char
  164.                                         key = String.fromCharCode(keycode);
  165.                                        
  166.                                         // clear up
  167.                                         window.clearTimeout(self.typeDelay);
  168.                                        
  169.                                         // typing a letter repeatedly
  170.                                         if (self.typedKeys === key) {
  171.                                        
  172.                                                 current = self.list.find('.selected:first');
  173.                                                 next = current.next();
  174.                                                 link = next.choldren('a');
  175.                                                
  176.                                                 if (link.text().toUpperCase().indexOf(self.typedKeys) === 0) {
  177.                                                         self.set(next);
  178.                                                 }
  179.                                                 else {
  180.                                                         self.setBySearch(self.typedKeys);
  181.                                                 }
  182.                                        
  183.                                         }
  184.                                        
  185.                                         // typing a word
  186.                                         else {
  187.                                        
  188.                                                 // concatenate
  189.                                                 self.typedKeys += key + '';
  190.                                                
  191.                                                 // wait user to finish typing
  192.                                                 self.typeDelay = window.setTimeout(function () {
  193.                                                        
  194.                                                         self.setBySearch(self.typedKeys);
  195.                                                         self.typedKeys = '';
  196.                                                
  197.                                                 }, 300);
  198.                                        
  199.                                         }
  200.                                        
  201.                                 }
  202.                        
  203.                         });
  204.                        
  205.                         self.obj.trigger('open.' + settings.namespaces.droplist, self);
  206.                
  207.                 };
  208.                
  209.                 self.close = function () {
  210.                        
  211.                         self.dropdown.hide();
  212.                         self.wrapper.removeClass('droplist-active');
  213.                         doc.unbind('.' + settings.namespaces.clickout);
  214.                        
  215.                         self.obj.trigger('close.' + settings.namespaces.droplist, self);
  216.                
  217.                 };
  218.                
  219.                 self.set = function (el) {
  220.                
  221.                         var el = $(el),
  222.                                 link = el.children('a'),
  223.                                 text = link.text();
  224.                        
  225.                         // style
  226.                         self.listItems.removeClass('selected');
  227.                         el.addClass('selected');
  228.                        
  229.                         // text
  230.                         setText(text);
  231.                
  232.                         // value
  233.                         if (self.originalSelect.length > 0) {
  234.                                 var val = el.find('a').attr('href');
  235.                                 self.originalSelect.find("option[value$='" + val + "']").prop('selected', true);
  236.                         }
  237.                        
  238.                         // trigger
  239.                         self.obj.trigger('change.' + settings.namespaces.droplist, self);
  240.                
  241.                 };
  242.                
  243.                 self.setBySearch = function (q) {
  244.                        
  245.                         self.listItems.each(function () {
  246.                                 var link = $(this).children('a');
  247.                                 if (link.text().toUpperCase().indexOf(q) === 0) {
  248.                                         self.set(this);
  249.                                         return false;
  250.                                 }
  251.                         });
  252.                
  253.                 };
  254.                
  255.                 self.get = function () {
  256.                         return self.list.find('.selected:first a').attr('href');
  257.                 };
  258.                
  259.                
  260.                 /*
  261.                 HELPERS
  262.                 ==============================================================================
  263.                 */
  264.                
  265.                 self.tabs = function () {
  266.                        
  267.                         var that = this;
  268.                        
  269.                         that.list.find('li').bind('click', function () {
  270.                                 that.set(this);
  271.                                 that.close();
  272.                                 var id = $(this).find('a').attr('href');
  273.                                 $(id).removeClass('hide').show().siblings().hide();
  274.                                 return false;
  275.                         });
  276.                
  277.                 };
  278.  
  279.  
  280.                 /*
  281.                 CONTROLLER
  282.                 ==============================================================================
  283.                 */
  284.                
  285.                 self.obj = $(element);
  286.                 self.obj.css('border', 'none');
  287.                
  288.                 self.obj.id = self.obj.attr('id');
  289.                 self.obj.classname = self.obj.attr('class');
  290.                 self.obj.name = self.obj.attr('name');
  291.                 self.obj.width = self.obj.width();
  292.                 self.obj.title = self.obj.attr('title');
  293.                
  294.                 self.isInsideForm = false;
  295.                 self.isDisabled = (self.obj.prop('disabled') == true);
  296.                
  297.                 // style
  298.                 if (self.isDisabled) {
  299.                         self.obj.classname += ' droplist-disabled';
  300.                 }
  301.                
  302.                 // insert wrapper
  303.                 var wrapperHtml = '<div id="' + self.obj.id + '" class="' + self.obj.classname + '"><div class="droplist-list"></div></div>';
  304.                
  305.                 // get elements
  306.                 self.wrapper = self.obj.removeAttr('class').wrap(wrapperHtml).parent().parent();
  307.                 self.dropdown = self.wrapper.find('.droplist-list:first');
  308.                 self.list = self.dropdown.find('ul:first');
  309.                
  310.                 // case it's a SELECT tag, not a UL
  311.                 if (self.list.length === 0) {
  312.                        
  313.                         self.isInsideForm = true;
  314.                        
  315.                         var html = '',
  316.                                 select = self.dropdown.find('select:first'),
  317.                                 optgroups = select.find('optgroup'),
  318.                                 options;
  319.                                
  320.                         select.removeAttr('id');
  321.                        
  322.                         if (optgroups.length > 0) {
  323.                                 html += '<ul>';
  324.                                 optgroups.each(function () {
  325.                                         options = $(this).find('option');
  326.                                         html += '<li><strong>' + $(this).attr('label') + '</strong>' + options2list(options) + '</li>';
  327.                                 });
  328.                                 html += '</ul>';
  329.                         } else {
  330.                                 options = self.dropdown.find('select:first option');
  331.                                 html += options2list(options);
  332.                         }
  333.                        
  334.                         self.dropdown.append(html);
  335.                        
  336.                         // override list
  337.                         self.list = self.dropdown.find('ul:first');
  338.                
  339.                 }
  340.                
  341.                 // insert HTML into the wrapper
  342.                 self.wrapper.prepend('<div class="droplist-value"><a href="javascript:void(0);"></a><div></div></div>');
  343.                
  344.                 // GET ELEMENTS
  345.                 self.listItems = self.list.find('li');
  346.                 self.select = self.wrapper.find('.droplist-value:first');
  347.                 self.option = self.select.find('div:first');
  348.                 self.drop = self.select.find('a:first');
  349.                 self.originalSelect = self.wrapper.find('select:first');
  350.                
  351.                 /*
  352.                 EVENTS
  353.                 ==============================================================================
  354.                 */
  355.                
  356.                 if (self.isDisabled == false) {
  357.                
  358.                         // toggle dropdown
  359.                         self.select.bind('click', function () {
  360.                                 if (self.dropdown.is(':hidden')) {
  361.                                         self.open();
  362.                                 } else {
  363.                                         self.close();
  364.                                 }
  365.                         });
  366.                
  367.                         if (self.isInsideForm) {
  368.                                
  369.                                 // clicking on an option inside a form
  370.                                 self.list.find('a').bind('click', function () {
  371.                                         var parent = $(this).parent();
  372.                                         self.set(parent);
  373.                                         self.close();
  374.                                         return false;
  375.                                 });
  376.                                
  377.                                 // label correlation
  378.                                 if (self.obj.id) {
  379.                                         self.wrapper.parents('form').find('label[for="' + self.obj.id + '"]').bind('click', function () {
  380.                                                 self.drop.focus();
  381.                                         });
  382.                                 }
  383.                        
  384.                         }
  385.                
  386.                 }
  387.                
  388.                 /*
  389.                 $(window).bind('resize', function () {
  390.                         layoutController();
  391.                 });
  392.                 */
  393.                
  394.                 // adjust layout
  395.                 layoutController();
  396.                        
  397.                 // custom scroll
  398.                 if (settings.customScroll) {
  399.                         customScroll();
  400.                 }
  401.                
  402.                 // initial state
  403.                 setInitialTitle();
  404.                 setInitialSelected();
  405.                 self.close();
  406.                
  407.                 // callback
  408.                 if (typeof callback == 'function') {
  409.                         callback.apply(self);
  410.                 }
  411.                
  412.                 return self;
  413.        
  414.         };
  415.  
  416.        
  417.         /*
  418.         INSTANCES MANAGER
  419.         ==============================================================================
  420.         */
  421.        
  422.         $.fn.droplist = function (settings, callback) {
  423.                 return this.each(function () {
  424.                        
  425.                         var obj = $(this),
  426.                                 instance = null;
  427.                        
  428.                         if (obj.data('droplist')) return; // return early if this obj already has a plugin instance
  429.                        
  430.                         instance = new DropList(this, settings, callback);
  431.                         obj.data('droplist', instance);
  432.                        
  433.                 });
  434.         };
  435.  
  436. })(jQuery);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement