#1 01.11.06 15:46
[JavaScript] Интелектуальное дерево с checkbox'ами
Суть проблемы такая. Есть дерево с чекбоксами типа:
Код: html:
<input type="checkbox" id="n1"> <input type="checkbox" id="n1.1"> <input type="checkbox" id="n1.1.1"> <input type="checkbox" id="n2"> <input type="checkbox" id="n2.1"> <input type="checkbox" id="n2.1.1"> <input type="checkbox" id="n2.1.1.1"> <input type="checkbox" id="n2.1.1.2"> <input type="checkbox" id="n2.1.1.3"> <input type="checkbox" id="n2.1.2"> <input type="checkbox" id="n2.2"> <input type="checkbox" id="n2.2.1">
Нужно придумать механизм зачекивания категорий целиком, категорий если зачеканы все потомки. Короче реализовать механизм как в любом инсталяторе от мелкомягких.
Я изобрёл такую функцию:
Код: javascript:
var stack = 0; function check_group(id, isRecursion) { function uncheck(id){ var obj = document.getElementById('n' + id); if (obj) obj.checked = false; var parent = document.getElementById('n' + id.substring(0,id.lastIndexOf("."))); if (obj && parent) uncheck(id.substring(0,id.lastIndexOf("."))); } function check_group_(id, isRecursion, isChecked) { stack++; var idParent; var objBox = document.getElementsByName('n' + id)[0]; if (objBox == null) objBox = document.getElementById('n' + id); for (var i = 1; true; i++) { var objChild = document.getElementsByName('n' + id + '.' + i)[0]; if (objChild == null) objChild = document.getElementById('n' + id + '.' + i); if (!objChild) { var parent = document.getElementById('n' + id.substring(0,id.lastIndexOf("."))); if (objBox && parent) idParent = id.substring(0,id.lastIndexOf(".")); if(stack == 1 && !objBox.checked) { uncheck(idParent); } else break; } var obj = document.getElementsByName('n' + id + '.' + i)[0]; if (obj==null) obj = document.getElementById('n' + id + '.' + i); if (obj) obj.checked = isChecked; if (isRecursion == '1' || obj) { check_group_(id + '.' + i, isRecursion, isChecked); } } } var obj1 = document.getElementsByName('n' + id)[0]; if (obj1==null) obj1 = document.getElementById('n' + id); check_group_(id, isRecursion, obj1.checked); stack = 0; }
При её вызове на онклик по какому либо чекбоксу если он не зачекан, чекаются все дочернии (также и расчекиваются), и, если идёт клик по самому нижнему уровню (при условии что он зачекан) расчекиваются все родители, типа категория не выбрана целиком.
Я застрял на том, чтобы расчекивание срабатывало не только на самом нижнем уровне, но и выше. И как зачекать корневой чекбокс, если зачеканы все его потомки. В инете подобного ничего не нашёл.
Offline
#3 03.11.06 10:18
Re: [JavaScript] Интелектуальное дерево с checkbox'ами
Спасибо, проблема решена.
Код: javascript:
var stack = 0; function check_group(id, isRecursion) { function existCheckedBrother(id){ for (var i = 1; true; i++) { var objChild = document.getElementsByName('n' + id + '.' + i)[0]; if (objChild == null) objChild = document.getElementById('n' + id + '.' + i); if (objChild && objChild.checked == false) { return false; } if (!objChild) break; } return true; } function checkUp(id, isChecked){ var obj = document.getElementById('n' + id); if (isChecked) { if (existCheckedBrother(id) && obj) obj.checked = isChecked; } else if (obj) obj.checked = isChecked; var parent = document.getElementById('n' + id.substring(0,id.lastIndexOf("."))); if (obj && parent) { checkUp(id.substring(0,id.lastIndexOf(".")), isChecked); } } function check_group_(id, isRecursion, isChecked) { stack++; var idParent; var objBox = document.getElementsByName('n' + id)[0]; if (objBox == null) objBox = document.getElementById('n' + id); for (var i = 1; true; i++) { var objChild = document.getElementsByName('n' + id + '.' + i)[0]; if (objChild == null) objChild = document.getElementById('n' + id + '.' + i); if (!objChild) { var parent = document.getElementById('n' + id.substring(0,id.lastIndexOf("."))); if (objBox && parent) idParent = id.substring(0,id.lastIndexOf(".")); if (stack == 1 && objBox) checkUp(idParent, objBox.checked); else break; } var obj = document.getElementsByName('n' + id + '.' + i)[0]; if (obj==null) obj = document.getElementById('n' + id + '.' + i); if (obj) obj.checked = isChecked; if (isRecursion == '1' || obj) { check_group_(id + '.' + i, isRecursion, isChecked); } } } var obj1 = document.getElementsByName('n' + id)[0]; if (obj1==null) obj1 = document.getElementById('n' + id); check_group_(id, isRecursion, obj1.checked); checkUp(id.substring(0,id.lastIndexOf(".")), obj1.checked); stack = 0; }
Offline
#4 17.11.06 13:57
Re: [JavaScript] Интелектуальное дерево с checkbox'ами
Вчера сел и переделал скриптик. Теперь реализовано 3 состояния: зачекано, частично зачекано, незачекано.
Для тех кому интересно или может пригодиться выкладываю код.
Код: javascript:
var img_checked = new Image; var img_uncheck = new Image; var img_check = new Image; img_checked.src = "checked.gif"; img_uncheck.src = "uncheck.gif"; img_check.src = "check.gif"; function check_it(id) { function getParentId(id, prefix) { var parent = document.getElementById(prefix + id.substring(0,id.lastIndexOf("."))); if (parent == null) parent = document.getElementsByName(prefix + id.substring(0,id.lastIndexOf("."))); if (parent) return id.substring(0,id.lastIndexOf(".")); return false; } function setImg(check_type, objImg) { if(check_type == "0") { objImg.setAttribute("check_type", "2"); objImg.src = img_checked.src; } if(check_type == "1") { objImg.setAttribute("check_type", "2"); objImg.src = img_checked.src; } if(check_type == "2") { objImg.setAttribute("check_type", "0"); objImg.src = img_uncheck.src; } } function existCheckedChildren (id) { var type_1 = 0; var type_2 = 0; for (var i = 1; true; i++) { var objChild = document.getElementsByName("e" + id + "." + i)[0]; if (objChild == null) objChild = document.getElementById("e" + id + "." + i); if (objChild) { if (objChild.getAttribute("check_type")=="1") type_1++; if (objChild.getAttribute("check_type")=="2") type_2++; } if (!objChild) break; } if (i == (type_2+1)) return "2"; if (type_1 > 0 || type_2 > 0) return "1"; return "0"; } function check_down(id, check_type) { var objImg = document.getElementsByName("e" + id)[0]; if (objImg == null) objImg = document.getElementById("e" + id); if (objImg) { setImg(check_type, objImg); } var objBox = document.getElementsByName("n" + id)[0]; if (objBox == null) objBox = document.getElementById("n" + id); if (objBox) { if(check_type == "0" || check_type == "1") objBox.checked = true; else objBox.checked = false; } for (var i = 1; true; i++) { var objChild = document.getElementsByName("e" + id + "." + i)[0]; if (objChild == null) objChild = document.getElementById("e" + id + "." + i); if (!objChild) { break; } if (objChild) { check_down(id + "." + i, check_type); } } } function check_up(id, check_type) { var id = getParentId(id, "e"); var objImg = document.getElementsByName("e" + id)[0]; if (objImg == null) objImg = document.getElementById("e" + id); if (objImg) { var check = existCheckedChildren(id); if(check == "2") setImg("0", objImg); if(check == "0") setImg("2", objImg); if(check == "1") { objImg.setAttribute("check_type", "1"); objImg.src = img_check.src; } } if (getParentId(id, "e")) check_up(id, check_type); } var obj = document.getElementsByName("e" + id)[0]; if (obj==null) obj = document.getElementById("e" + id); var check_type = obj.getAttribute("check_type"); check_down(id, check_type); check_up(id, check_type); }
"checked.gif" - зачекано
"uncheck.gif" - незачекано
"check.gif" - частично зачекано
А это html для этого скрипта:
Код: html:
<a href="javascript:check_it('1')"><img border='0' name='e1' src='uncheck.gif' check_type="0"></a> -<a href="javascript:check_it('1.1')"><img border='0' name='e1.1' src='uncheck.gif' check_type="0"></a> --<a href="javascript:check_it('1.1.1')"><img border='0' name='e1.1.1' src='uncheck.gif' check_type="0"></a><input type="checkbox" id="n1.1.1" style="display: none;"> <a href="javascript:check_it('2')"><img border='0' name='e2' src='uncheck.gif' check_type="0"></a> -<a href="javascript:check_it('2.1')"><img border='0' name='e2.1' src='uncheck.gif' check_type="0"></a> --<a href="javascript:check_it('2.1.1')"><img border='0' name='e2.1.1' src='uncheck.gif' check_type="0"></a> ---<a href="javascript:check_it('2.1.1.1')"><img border='0' name='e2.1.1.1' src='uncheck.gif' check_type="0"></a><input type="checkbox" id="n2.1.1.1" style="display: none;"> --<a href="javascript:check_it('2.1.2')"><img border='0' name='e2.1.2' src='uncheck.gif' check_type="0"></a> ---<a href="javascript:check_it('2.1.2.1')"><img border='0' name='e2.1.2.1' src='uncheck.gif' check_type="0"></a><input type="checkbox" id="n2.1.2.1" style="display: none;"> ---<a href="javascript:check_it('2.1.2.2')"><img border='0' name='e2.1.2.2' src='uncheck.gif' check_type="0"></a><input type="checkbox" id="n2.1.2.2" style="display: none;">
Похожая реализация сделана в Yahoo UI, но без checkbox'ов на нижнем уровне.
Offline

