diff options
author | Thomas Tanghus <thomas@tanghus.net> | 2012-12-03 18:56:15 +0100 |
---|---|---|
committer | Thomas Tanghus <thomas@tanghus.net> | 2012-12-04 18:00:13 +0100 |
commit | 9ddd754bce4c9ffcef86748e2abcd1d727f3f382 (patch) | |
tree | 69da9f9d284556a755d2dc53bc3641556da9a4ab /core/js/multiselect.js | |
parent | 9e6ffece64ab8b44bc58ecb01249b682e8d45ba6 (diff) | |
download | nextcloud-server-9ddd754bce4c9ffcef86748e2abcd1d727f3f382.tar.gz nextcloud-server-9ddd754bce4c9ffcef86748e2abcd1d727f3f382.zip |
Enhanced multiSelect jquery plugin.
Diffstat (limited to 'core/js/multiselect.js')
-rw-r--r-- | core/js/multiselect.js | 134 |
1 files changed, 101 insertions, 33 deletions
diff --git a/core/js/multiselect.js b/core/js/multiselect.js index c4fd74b0475..bec9b5856c2 100644 --- a/core/js/multiselect.js +++ b/core/js/multiselect.js @@ -1,3 +1,13 @@ +/** + * @param 'createCallback' A function to be called when a new entry is created. Only argument to the function is the value of the option. + * @param 'createText' The placeholder text for the create action. + * @param 'title' The title to show if no options are selected. + * @param 'checked' An array containing values for options that should be checked. Any options which are already selected will be added to this array. + * @param 'labels' The corresponding labels to show for the checked items. + * @param 'oncheck' Callback function which will be called when a checkbox/radiobutton is selected. If the function returns false the input will be unchecked. + * @param 'onuncheck' @see 'oncheck'. + * @param 'singleSelect' If true radiobuttons will be used instead of checkboxes. + */ (function( $ ){ var multiSelectId=-1; $.fn.multiSelect=function(options){ @@ -5,16 +15,25 @@ var settings = { 'createCallback':false, 'createText':false, + 'singleSelect':false, 'title':this.attr('title'), 'checked':[], + 'labels':[], 'oncheck':false, 'onuncheck':false, 'minWidth': 'default;', }; $.extend(settings,options); $.each(this.children(),function(i,option){ - if($(option).attr('selected') && settings.checked.indexOf($(option).val())==-1){ + // If the option is selected, but not in the checked array, add it. + if($(option).attr('selected') && settings.checked.indexOf($(option).val()) == -1){ settings.checked.push($(option).val()); + settings.labels.push($(option).text().trim()); + } + // If the option is in the checked array but not selected, select it. + else if(settings.checked.indexOf($(option).val()) !== -1 && !$(option).attr('selected')){ + $(option).attr('selected', 'selected'); + settings.labels.push($(option).text().trim()); } }); var button=$('<div class="multiselect button"><span>'+settings.title+'</span><span>▾</span></div>'); @@ -30,18 +49,31 @@ button.css('min-width',settings.minWidth); settings.minOuterWidth=button.outerWidth()-2; button.data('settings',settings); - if(settings.checked.length>0){ - button.children('span').first().text(settings.checked.join(', ')); + + if(!settings.singleSelect && settings.checked.length>0){ + //button.children('span').first().text(settings.checked.join(', ')); + button.children('span').first().text(settings.labels.join(', ')); + } else if(settings.singleSelect) { + button.children('span').first().text(this.find(':selected').text()); } + var self = this; + self.menuDirection = 'down'; button.click(function(event){ var button=$(this); if(button.parent().children('ul').length>0){ - button.parent().children('ul').slideUp(400,function(){ - button.parent().children('ul').remove(); - button.removeClass('active'); - }); + if(self.menuDirection === 'down') { + button.parent().children('ul').slideUp(400,function(){ + button.parent().children('ul').remove(); + button.removeClass('active'); + }); + } else { + button.parent().children('ul').fadeOut(400,function(){ + button.parent().children('ul').remove(); + button.removeClass('active').removeClass('up'); + }); + } return; } var lists=$('ul.multiselectoptions'); @@ -54,15 +86,19 @@ event.stopPropagation(); var options=$(this).parent().next().children(); var list=$('<ul class="multiselectoptions"/>').hide().appendTo($(this).parent()); + var inputType = settings.singleSelect ? 'radio' : 'checkbox'; function createItem(element,checked){ element=$(element); var item=element.val(); var id='ms'+multiSelectId+'-option-'+item; - var input=$('<input type="checkbox"/>'); + var input=$('<input type="' + inputType + '"/>'); input.attr('id',id); + if(settings.singleSelect) { + input.attr('name', 'ms'+multiSelectId+'-option'); + } var label=$('<label/>'); label.attr('for',id); - label.text(item); + label.text(element.text() || item); if(settings.checked.indexOf(item)!=-1 || checked){ input.attr('checked',true); } @@ -70,33 +106,41 @@ settings.checked.push(item); } input.change(function(){ - var groupname=$(this).next().text(); + var value = $(this).attr('id').substring(String('ms'+multiSelectId+'-option').length+1); + var label = $(this).next().text().trim(); if($(this).is(':checked')){ + if(settings.singleSelect) { + settings.checked = []; + settings.labels = []; + $.each(self.find('option'), function() { + $(this).removeAttr('selected'); + }); + } element.attr('selected','selected'); if(settings.oncheck){ - if(settings.oncheck(groupname)===false){ + if(settings.oncheck(value)===false){ $(this).attr('checked', false); return; } } - settings.checked.push(groupname); + settings.checked.push(value); + settings.labels.push(label); }else{ - var index=settings.checked.indexOf(groupname); + var index=settings.checked.indexOf(value); element.attr('selected',null); if(settings.onuncheck){ - if(settings.onuncheck(groupname)===false){ + if(settings.onuncheck(value)===false){ $(this).attr('checked',true); return; } } settings.checked.splice(index,1); + settings.labels.splice(index,1); } var oldWidth=button.width(); - if(settings.checked.length>0){ - button.children('span').first().text(settings.checked.join(', ')); - }else{ - button.children('span').first().text(settings.title); - } + button.children('span').first().text(settings.labels.length > 0 + ? settings.labels.join(', ') + : settings.title); var newOuterWidth=Math.max((button.outerWidth()-2),settings.minOuterWidth)+'px'; var newWidth=Math.max(button.width(),settings.minWidth); var pos=button.position(); @@ -123,7 +167,7 @@ var input=$('<input class="new">'); li.append(input); input.focus(); - input.css('width',button.width()); + input.css('width',button.innerWidth()); button.parent().data('preventHide',true); input.keypress(function(event) { if(event.keyCode == 13) { @@ -132,7 +176,7 @@ var value = $(this).val(); var exists = false; $.each(options,function(index, item) { - if ($(item).val() == value) { + if ($(item).val() == value || $(item).text() == value) { exists = true; return false; } @@ -143,15 +187,18 @@ var li=$(this).parent(); $(this).remove(); li.text('+ '+settings.createText); - li.before(createItem(this)); + li.before(createItem(this, true)); + if(self.menuDirection === 'up') { + var list = li.parent(); + list.css('top', list.position().top-li.outerHeight()); + } var select=button.parent().next(); var option=$('<option selected="selected"/>'); - option.attr('value',value); - option.text($(this).val()); select.append(option); + option.text($(this).val()); li.prev().children('input').trigger('click'); button.parent().data('preventHide',false); - if(settings.createCallback){ + if(typeof settings.createCallback === 'function'){ settings.createCallback($(this).val()); } } @@ -169,20 +216,41 @@ list.append(li); } var pos=button.position(); - list.css('top',pos.top+button.outerHeight()-5); - list.css('left',pos.left+3); - list.css('width',(button.outerWidth()-2)+'px'); - list.slideDown(); + if($(document).height() > button.offset().top+button.outerHeight() + list.children().length * button.height()) { + list.css('top',pos.top+button.outerHeight()-5); + list.css('left',pos.left+3); + list.css('width',(button.outerWidth()-2)+'px'); + list.addClass('down'); + button.addClass('down'); + list.slideDown(); + } else { + list.css('top', pos.top - list.height()); + list.css('left', pos.left+3); + list.css('width',(button.outerWidth()-2)+'px'); + list.detach().insertBefore($(this)); + list.addClass('up'); + button.addClass('up'); + list.fadeIn(); + self.menuDirection = 'up'; + } list.click(function(event){ event.stopPropagation(); }); }); $(window).click(function(){ if(!button.parent().data('preventHide')){ - button.parent().children('ul').slideUp(400,function(){ - button.parent().children('ul').remove(); - button.removeClass('active'); - }); + // How can I save the effect in a var? + if(self.menuDirection === 'down') { + button.parent().children('ul').slideUp(400,function(){ + button.parent().children('ul').remove(); + button.removeClass('active').removeClass('down'); + }); + } else { + button.parent().children('ul').fadeOut(400,function(){ + button.parent().children('ul').remove(); + button.removeClass('active').removeClass('up'); + }); + } } }); |