Официальный сайт студ.городка НГТУ
Программирование и БД » [JavaScript] Интелектуальное дерево с checkbox'ами 

#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

#2  01.11.06 16:36

Re: [JavaScript] Интелектуальное дерево с checkbox'ами

forum.vingrad.ru

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

#5  17.11.06 15:28

Re: [JavaScript] Интелектуальное дерево с checkbox'ами

кстати тормозов почти не замечено, притормаживает если записей нижнего уровня больше сотни...

Offline

Программирование и БД » [JavaScript] Интелектуальное дерево с checkbox'ами 

ФутЕр:)

© Hostel Web Group, 2002-2025.   Сообщить об ошибке

Сгенерировано за 0.353 сек.
Выполнено 11 запросов.