1/** 2 * jQuery Tree Control 3 * 4 * @author Maxim Vasiliev 5 */ 6(function($){ 7 8 var CLASS_JQUERY_TREE = 'jquery-tree'; 9 var CLASS_JQUERY_TREE_CONTROLS = 'jquery-tree-controls'; 10 var CLASS_JQUERY_TREE_COLLAPSE_ALL = 'jquery-tree-collapseall'; 11 var CLASS_JQUERY_TREE_EXPAND_ALL = 'jquery-tree-expandall'; 12 var CLASS_JQUERY_TREE_COLLAPSED = 'jquery-tree-collapsed'; 13 var CLASS_JQUERY_TREE_HANDLE = 'jquery-tree-handle'; 14 var CLASS_JQUERY_TREE_TITLE = 'jquery-tree-title'; 15 var CLASS_JQUERY_TREE_NODE = 'jquery-tree-node'; 16 var CLASS_JQUERY_TREE_LEAF = 'jquery-tree-leaf'; 17 var CLASS_JQUERY_TREE_CHECKED = 'jquery-tree-checked'; 18 var CLASS_JQUERY_TREE_UNCHECKED = 'jquery-tree-unchecked'; 19 var CLASS_JQUERY_TREE_CHECKED_PARTIAL = 'jquery-tree-checked-partial'; 20 21 var COLLAPSE_ALL_CODE = '<span class="' + CLASS_JQUERY_TREE_COLLAPSE_ALL + '">СвеÑнÑÑÑ Ð²Ñе</span>'; 22 var EXPAND_ALL_CODE = '<span class="' + CLASS_JQUERY_TREE_EXPAND_ALL + '">РазвеÑнÑÑÑ Ð²Ñе</span>'; 23 var TREE_CONTROLS_CODE = '<div class="' + CLASS_JQUERY_TREE_CONTROLS + '">' + 24 COLLAPSE_ALL_CODE + 25 EXPAND_ALL_CODE + 26 '</div>'; 27 28 var TREE_NODE_HANDLE_CODE = '<span class="' + CLASS_JQUERY_TREE_HANDLE + '">+</span>'; 29 var TREE_NODE_HANDLE_COLLAPSED = "+"; 30 var TREE_NODE_HANDLE_EXPANDED = "−"; 31 32 $.fn.extend({ 33 34 /** 35 * ÐÐµÐ»Ð°ÐµÑ Ð´ÐµÑево из ÑÑÑÑкÑÑÑÑ Ð²Ð¸Ð´Ð°: 36 * <ul> 37 * <li><label><input type="checkbox" />Item1</label></li> 38 * <li> 39 * <label><input type="checkbox" />ItemWithSubitems</label> 40 * <ul> 41 * <li><label><input type="checkbox" />Subitem1</label></li> 42 * </ul> 43 * </li> 44 * </ul> 45 */ 46 Tree: function(){ 47 // Ðобавим конÑÑÐ¾Ð»Ñ Ð´Ð»Ñ Ð²Ñего деÑева (вÑе ÑвеÑнÑÑÑ, ÑазвеÑнÑÑÑ Ð¸ Ñ.д.), и добавим клаÑÑ 48 $(this) 49 .addClass(CLASS_JQUERY_TREE) 50 .before(TREE_CONTROLS_CODE) 51 .prev('.' + CLASS_JQUERY_TREE_CONTROLS) 52 .find('.' + CLASS_JQUERY_TREE_COLLAPSE_ALL).click(function(){ 53 $(this).parent().next('.' + CLASS_JQUERY_TREE) 54 .find('li:has(ul)') 55 .addClass(CLASS_JQUERY_TREE_COLLAPSED) 56 .find('.' + CLASS_JQUERY_TREE_HANDLE) 57 .html(TREE_NODE_HANDLE_COLLAPSED); 58 }) 59 60 .parent('.' + CLASS_JQUERY_TREE_CONTROLS).find('.' + CLASS_JQUERY_TREE_EXPAND_ALL) 61 .click(function(){ 62 $(this).parent().next('.' + CLASS_JQUERY_TREE) 63 .find('li:has(ul)') 64 .removeClass(CLASS_JQUERY_TREE_COLLAPSED) 65 .find('.' + CLASS_JQUERY_TREE_HANDLE) 66 .html(TREE_NODE_HANDLE_EXPANDED); 67 }); 68 69 $('li', this).find(':first').addClass(CLASS_JQUERY_TREE_TITLE) 70 .closest('li').addClass(CLASS_JQUERY_TREE_LEAF); 71 72 // ÐÐ»Ñ Ð²ÑÐµÑ ÑлеменÑов, ÑвлÑÑÑÐ¸Ñ ÑÑ Ñзлами (имеÑÑÐ¸Ñ Ð´Ð¾ÑеÑние ÑлеменÑÑ)... 73 $('li:has(ul:has(li))', this).find(':first') 74 // ... добавим ÑлеменÑ, оÑкÑÑваÑÑий/закÑÑваÑÑий Ñзел 75 .before(TREE_NODE_HANDLE_CODE) 76 // ... добавим к конÑейнеÑÑ ÐºÐ»Ð°ÑÑ "Ñзел деÑева" и "ÑвеÑнем". 77 .closest('li') 78 .addClass(CLASS_JQUERY_TREE_NODE) 79 .addClass(CLASS_JQUERY_TREE_COLLAPSED) 80 .removeClass(CLASS_JQUERY_TREE_LEAF); 81 82 // ... повеÑим обÑабоÑÑик клика 83 $('.' + CLASS_JQUERY_TREE_HANDLE, this).bind('click', function(){ 84 var leafContainer = $(this).parent('li'); 85 var leafHandle = leafContainer.find('>.' + CLASS_JQUERY_TREE_HANDLE); 86 87 leafContainer.toggleClass(CLASS_JQUERY_TREE_COLLAPSED); 88 89 if (leafContainer.hasClass(CLASS_JQUERY_TREE_COLLAPSED)) 90 leafHandle.html(TREE_NODE_HANDLE_COLLAPSED); 91 else 92 leafHandle.html(TREE_NODE_HANDLE_EXPANDED); 93 }); 94 95 // ÐобавлÑем обÑабоÑÐºÑ ÐºÐ»Ð¸ÐºÐ° по ÑекбокÑам 96 $('input:checkbox', this).click(function(){ 97 setLabelClass(this); 98 checkCheckbox(this); 99 }) 100 // ÐÑÑÑавлÑем ÑекбокÑам изнаÑалÑнÑе клаÑÑÑ 101 .each(function(){ 102 setLabelClass(this); 103 if (this.checked) 104 checkParentCheckboxes(this); 105 }) 106 // ÐÐ»Ñ IE веÑаем обÑабоÑÑики на лейбл 107 .closest('label').click(function(){ 108 labelClick(this); 109 checkCheckbox($('input:checkbox', this)); 110 }); 111 } 112 113 }); 114 115 /** 116 * РекÑÑÑивно пÑовеÑÑеÑ, вÑе ли ÑекбокÑÑ Ð² поддеÑеве ÑодиÑелÑÑкого Ñзла вÑбÑанÑ. 117 * ÐÑли ни один ÑÐµÐºÐ±Ð¾ÐºÑ Ð½Ðµ вÑбÑан - ÑÐ½Ð¸Ð¼Ð°ÐµÑ Ñек Ñ ÑодиÑелÑÑкого ÑекбокÑа 118 * ÐÑли Ñ Ð¾ÑÑ Ð±Ñ Ð¾Ð´Ð¸Ð½, но не вÑе - вÑÑÑавлÑÐµÑ ÐºÐ»Ð°ÑÑ CLASS_JQUERY_TREE_CHECKED_PARTIAL ÑодиÑелÑÑÐºÐ¾Ð¼Ñ ÑекбокÑÑ 119 * ÐÑли вÑе - ÑÑÐ°Ð²Ð¸Ñ Ñек на ÑодиÑелÑÑкий ÑÐµÐºÐ±Ð¾ÐºÑ 120 * 121 * @param {Object} checkboxElement ÑекÑÑий ÑÐµÐºÐ±Ð¾ÐºÑ 122 */ 123 function checkParentCheckboxes(checkboxElement){ 124 if (typeof checkboxElement == 'undefined' || !checkboxElement) 125 return; 126 127 // пÑовеÑим, вÑе ли ÑекбокÑÑ Ð²ÑделенÑ/ÑаÑÑиÑно вÑÐ´ÐµÐ»ÐµÐ½Ñ Ð½Ð° вÑÑележаÑем ÑÑовне 128 var closestNode = $(checkboxElement).closest('ul');
129 var allCheckboxes = closestNode.find('input:checkbox'); 130 var checkedCheckboxes = closestNode.find('input:checkbox:checked'); 131 132 var allChecked = allCheckboxes.length == checkedCheckboxes.length; 133 134 var parentCheckbox = closestNode.closest('li').find('>.' + CLASS_JQUERY_TREE_TITLE + ' input:checkbox'); 135 136 if (parentCheckbox.length > 0) { 137 parentCheckbox.get(0).checked = allChecked; 138 139 if (!allChecked && checkedCheckboxes.length > 0) 140 parentCheckbox.closest('label') 141 .addClass(CLASS_JQUERY_TREE_CHECKED_PARTIAL) 142 .removeClass(CLASS_JQUERY_TREE_CHECKED) 143 .removeClass(CLASS_JQUERY_TREE_UNCHECKED); 144 else 145 if (allChecked) 146 parentCheckbox.closest('label') 147 .removeClass(CLASS_JQUERY_TREE_CHECKED_PARTIAL) 148 .removeClass(CLASS_JQUERY_TREE_UNCHECKED) 149 .addClass(CLASS_JQUERY_TREE_CHECKED); 150 else 151 parentCheckbox.closest('label') 152 .removeClass(CLASS_JQUERY_TREE_CHECKED_PARTIAL) 153 .removeClass(CLASS_JQUERY_TREE_CHECKED) 154 .addClass(CLASS_JQUERY_TREE_UNCHECKED); 155 156 checkParentCheckboxes(parentCheckbox.get(0)); 157 } 158 } 159 160 /** 161 * ÐÑли Ñ ÑекÑÑего ÑекбокÑа еÑÑÑ Ð´Ð¾ÑеÑние ÑÐ·Ð»Ñ - менÑÐµÑ Ð¸Ñ ÑоÑÑоÑние 162 * на ÑоÑÑоÑние ÑекÑÑего ÑекбокÑа 163 * 164 * @param {Object} checkboxElement ÑекÑÑий ÑÐµÐºÐ±Ð¾ÐºÑ 165 */ 166 function checkCheckbox(checkboxElement){ 167 // Ñекнем/анÑекнем нижележаÑие ÑекбокÑÑ 168 $(checkboxElement).closest('li').find('input:checkbox').each(function(){ 169 this.checked = $(checkboxElement).attr('checked'); 170 setLabelClass(this); 171 }); 172 checkParentCheckboxes(checkboxElement); 173 }; 174 175 /** 176 * ÐÑÑÑавлÑÐµÑ ÐºÐ»Ð°ÑÑ Ð»ÐµÐ¹Ð±Ð»Ñ Ð² завиÑимоÑÑи Ð¾Ñ ÑоÑÑоÑÐ½Ð¸Ñ ÑекбокÑа 177 * 178 * @param {Object} checkboxElement ÑÐµÐºÐ±Ð¾ÐºÑ 179 */ 180 function setLabelClass(checkboxElement){ 181 isChecked = $(checkboxElement).attr('checked'); 182 183 if (isChecked) { 184 $(checkboxElement).closest('label') 185 .addClass(CLASS_JQUERY_TREE_CHECKED) 186 .removeClass(CLASS_JQUERY_TREE_UNCHECKED) 187 .removeClass(CLASS_JQUERY_TREE_CHECKED_PARTIAL); 188 } 189 else { 190 $(checkboxElement).closest('label') 191 .addClass(CLASS_JQUERY_TREE_UNCHECKED) 192 .removeClass(CLASS_JQUERY_TREE_CHECKED) 193 .removeClass(CLASS_JQUERY_TREE_CHECKED_PARTIAL); 194 } 195 }; 196 197 /** 198 * ÐбÑабаÑÑÐ²Ð°ÐµÑ ÐºÐ»Ð¸Ðº по Ð»ÐµÐ¹Ð±Ð»Ñ (Ð´Ð»Ñ IE6) 199 */ 200 function labelClick(labelElement){ 201 var checkbox = $('input:checkbox', labelElement); 202 var checked = checkbox.attr('checked'); 203 checkbox.attr('checked', !checked); 204 setLabelClass(checkbox); 205 } 206 207})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.