/* * jsMultiSelectTree * * I just stepped in some jQuery, could someone hand me something to wipe this off? * * Abbey Hawk Sparrow * */ (function(){ if(jQuery && jQuery.MultiSelectTree) { return; } (function(jQuery){ //jqrysx jQuery.fn.MultiSelectTree = function(options) { //jqrysx var object = this; var defaults = { element : '#multiselecttree', allowOrphans : true, //remove any orphaned nodes without complaining relationshipAttribute : 'ancestry', openGlyph : '▼', closedGlyph : '▶', selectChildren : true, selectNode : false, openToSelected : true, openDepth : 1 } var closedGlyphValue; var settings = jQuery.extend(defaults, options); //jqrysx if(typeof settings.element == 'string') settings.element = jQuery('#'+settings.element)[0]; if(!settings.element) settings.element = jQuery(this); settings.openDepth++; var tree = {}; var getOption = function(id){ result = false; jQuery(settings.element).children('option').each(function(key, item){ if(item.value == id) result = item; }); return result; }; var countFieldsInObject = function(obj){ //jqrysx var count = 0; for (k in obj) if (obj.hasOwnProperty(k)) count++; return count; }; var is_object = function(mixed_var){ if (Object.prototype.toString.call(mixed_var) === '[object Array]') return false; return mixed_var !== null && typeof mixed_var == 'object'; }; var addToTree = function(tree, id, value){ var node = tree; jQuery.each(id.split('>'), function(index, key){ var cleanKey = getOption(jQuery.trim(key)).innerHTML; if(!node[cleanKey]) node[cleanKey] = {'*':value}; else node[cleanKey]['*'] = key; node = node[cleanKey]; }); return tree; }; jQuery(settings.element).children('option').each(function(key, item){ var descention = item.getAttribute(settings.relationshipAttribute); descention = descention=='' ? item.value : descention+'>'+item.value; tree = addToTree(tree, descention, item.value); }); var recursiveListBuild = function(root, depth){ if(!depth) depth = 0; var element = document.createElement('ul'); //jqrysx if(depth >= settings.openDepth) jQuery(element).hide(); var count = 0; jQuery.each(root, function(key, node){ var listElement = document.createElement('li'); var link = document.createElement('a'); if(node['*']){ link.setAttribute('identifier', node['*']); delete node['*']; } if(settings.linkClass) jQuery(link).addClass(settings.linkClass); var label = document.createElement('span'); label.innerHTML = key; jQuery(label).addClass('multiselecttree_label'); var spinner = document.createElement('span'); spinner.innerHTML = settings.closedGlyph; if(!closedGlyphValue) closedGlyphValue = spinner.innerHTML; if(countFieldsInObject(node) > 0) link.appendChild(spinner); link.appendChild(label); if(is_object(node)){ var sublist = recursiveListBuild(node, depth + 1); link.appendChild(sublist); jQuery(spinner).bind('click', function(event){ jQuery(sublist).toggle(); if(spinner.innerHTML == closedGlyphValue) spinner.innerHTML = settings.openGlyph; else spinner.innerHTML = settings.closedGlyph; }); var opt = getOption(link.getAttribute('identifier')); if(opt.getAttribute('selected') != null) jQuery(label).addClass('selected_node'); var getFirstLeafNode = function(node){ var nodeList = jQuery(node).find('a'); if(nodeList.length > 0){ var sublistList = jQuery(nodeList[0]).find('ul'); if(sublistList.length > 0 && jQuery(sublistList[0]).children().length > 0) return getFirstLeafNode(sublistList[0]); else return nodeList[0]; } return false; } if(opt.getAttribute('disabled') == null) jQuery(label).bind('click', function(event){ var selected = opt.getAttribute('selected'); if(settings.selectChildren && !settings.selectNode){ var node = getFirstLeafNode(sublist); if(node){ var o = getOption(node.getAttribute('identifier')); selected = o.getAttribute('selected'); } } if(selected){ if(settings.selectChildren){ var links = jQuery(sublist).find('a'); jQuery(links).each(function(key, item){ var option = getOption(item.getAttribute('identifier')); jQuery(item).find('span.multiselecttree_label').removeClass('selected_node'); if(settings.selectNode || jQuery(item).find('li').length == 0 ){ option.removeAttribute('selected'); } }); } jQuery(label).removeClass('selected_node'); if(settings.selectNode || jQuery(link).find('li').length == 0 ){ opt.removeAttribute('selected'); } }else{ if(settings.selectChildren){ var links = jQuery(sublist).find('a'); jQuery(links).each(function(key, item){ var option = getOption(item.getAttribute('identifier')); jQuery(item).find('span.multiselecttree_label').addClass('selected_node'); if(settings.selectNode || jQuery(item).find('li').length == 0 ){ option.setAttribute('selected', true); } }); } jQuery(label).addClass('selected_node'); if(settings.selectNode || jQuery(link).find('li').length == 0 ){ opt.setAttribute('selected', true); } } return false; }); } listElement.appendChild(link); element.appendChild(listElement); count++; if(jQuery(sublist).css('display') != 'none'){ spinner.innerHTML = settings.openGlyph; } }); if(settings.openToSelected) jQuery(element).find('span.selected_node').parents('ul').show(); return element; }; var el = recursiveListBuild(tree); jQuery(el).addClass('multiselecttree'); jQuery(settings.element).after(el); jQuery(settings.element).hide(); jQuery(el).show(); return this; //jqrysx } })(jQuery); })(); jQuery('treeselect').MultiSelectTree({ element : 'treeselect', relationshipAttribute : 'heredity' });
.multiselecttree { line-height: 18px; } .multiselecttree .selected_node { color: black; } .multiselecttree .multiselecttree_label { padding-left: 1px; cursor: pointer; } .multiselecttree .multiselecttree_label:before { margin-right: 3px; display: inline-block; height: 13px; width: 13px; background-color: #CCCCCC; content: '\A0'; background-color: #ececec; background-image: -webkit-gradient(linear, left top, left bottom, from(#ececec), to(#a8a8a8)); background-image: -webkit-linear-gradient(top, #ececec, #a8a8a8); background-image: -moz-linear-gradient(top, #ececec, #a8a8a8); background-image: -o-linear-gradient(top, #ececec, #a8a8a8); background-image: -ms-linear-gradient(top, #ececec, #a8a8a8); background-image: linear-gradient(top, #ececec, #a8a8a8); box-shadow: inset 0px 0px 3px #686868; -moz-box-shadow: inset 0px 0px 3px #686868; -webkit-box-shadow: inset 0px 0px 3px #686868; -webkit-border-radius: 2px; -moz-border-radius: 2px; border-radius: 2px; border: 1px solid #626262; } .multiselecttree .selected_node:before { content: '\2713'; } .multiselecttree ul { margin-left: 20px; } .multiselecttree_label { color: grey; margin-left: 3px; }
<select multiple name="selector" class="treeselect" id="treeselect"> <option value="1" heredity="">An Item</option> <option value="2" heredity="1" disabled>A Test</option> <option value="3" heredity="1>2">Another Test</option> <option value="4" heredity="1>2">A Test3</option> <option value="5" heredity="1">A Test4</option> <option value="6" heredity="1">A Test5</option> <option value="7" heredity="1>5">A Test2</option> <option value="8" heredity="">fsfdsfg</option> <option value="9" heredity="">werttg</option> </select>