- открытие/закрытие ветвей дерева
- перемещение категории на уровень вверх/вниз
- дублирование (как категории отдельно, так и целой ветки)
- удаление элементов
Немного поразмыслив я придумал такой подход:
Каждой строке таблицы присваивается 2 параметра:
level - уровень, на котором лежит узел (от 0 и выше)
state - состояние узла (open - узел открыт, closed - закрыт, end - узел является конечным )
Смотрите скриншот таблицы:
И так, первая функция для открытия и закрытия узлов. Встречайте:
- function changeRowState(box, RH_Panel)
- {
- elem = box.parentNode.parentNode.parentNode;
- var current_level = elem.getAttribute("level");
- var current_state = elem.getAttribute("state");
- var current_table = "table_body";
- if(RH_Panel)
- current_table = "RH_table_body";
- var row_display = "none"; // for style.display
- if(current_state == "closed") // if item is closed, than show all children
- row_display = "";
- var tbody = document.getElementById(current_table);
- var children = tbody.childNodes;
- var after_current = false;
- for(var i=0; i<children.length; i++)
- {
- if(children[i].tagName == 'TR')
- {
- if(children[i] == elem)
- {
- after_current = true;
- }
- if(after_current)
- {
- if((children[i] != elem) && (children[i].getAttribute('level') == current_level))
- {
- if(current_state == "open")
- {
- elem.setAttribute("state", "closed");
- box.src = "images/branch_closed.gif";
- }
- else
- {
- elem.setAttribute("state", "open");
- box.src = "images/branch_open.gif";
- }
- return;
- }
- if(children[i].getAttribute('level') > current_level)
- {
- children[i].style.display = row_display;
- }
- }
- }
- }
- if(current_state == "open")
- {
- elem.setAttribute("state", "closed");
- box.src = "images/branch_closed.gif";
- }
- else
- {
- elem.setAttribute("state", "open");
- box.src = "images/branch_open.gif";
- }
Эту функцию мы ставим на событие onclick для элемента <img> в строке таблицы:
<tr level="0" state="open" style="background:#99ddaa;">
<td><input type="checkbox" name="tree_items[]" /></td>
<td>
<a href="javascript:void(0)">
<img src="images/branch_open.gif" onclick="changeRowState(this);" />
</a>
<a href="action.php"> <b>Web Channel (2)</b></a>
</td>
<td>56</td>
<td>2</td>
<td>3</td>
<td>10</td>
<td class="statusProduction">Published</td>
</tr>Syhi-подсветка кода
<td><input type="checkbox" name="tree_items[]" /></td>
<td>
<a href="javascript:void(0)">
<img src="images/branch_open.gif" onclick="changeRowState(this);" />
</a>
<a href="action.php"> <b>Web Channel (2)</b></a>
</td>
<td>56</td>
<td>2</td>
<td>3</td>
<td>10</td>
<td class="statusProduction">Published</td>
</tr>Syhi-подсветка кода
Логика очень проста: при нажатии на иконку, функция проходит по всем строчкам таблицы и изменяет атрибут display (если уровень больше). При таком подходе, в принципе, уровень вложенности может быть большим. Но для нашего проекта я сделал ограничение до 10 уровней.
Функция для изменения уровня узлов:
function changeLevel(direction)
{
var delta_level = -1;
if(direction == "down")
delta_level = 1;
var checkboxes = document.getElementsByName("tree_items[]");
for(var i=0; i<checkboxes.length; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var current_level = row.getAttribute("level");
if(current_level != 0 || direction == "down") // dont move up row with level = 0
{
var td = checkboxes[i].parentNode.nextSibling;
if(td.nodeType == 3)
td = checkboxes[i].parentNode.nextSibling.nextSibling;
var prev_html = td.innerHTML;
prev_html = prev_html.slice(prev_html.indexOf("<"));
var new_level = parseInt(current_level) + parseInt(delta_level);
td.innerHTML = getSpacesForLevel(new_level) + prev_html;
row.setAttribute("level", new_level);
row.style.backgroundColor = arrColors[new_level];
var tbody = document.getElementById('table_body');
var children = tbody.childNodes;
var row_index = getRowIndex(row);
if(direction == "down")
row_index++;
for(var j=row_index; j<children.length; j++)
{
if(children[j].tagName == 'TR')
{
if(children[j].getAttribute("level") == current_level)
break;
if(children[j].getAttribute("level") > current_level)
{
var cur_level = children[j].getAttribute("level")
var td = children[j].childNodes[3];
if(td.innerHTML.indexOf("<img") == -1) // IE and Safari hack
td = children[j].childNodes[1];
var prev_html = td.innerHTML;
prev_html = prev_html.slice(prev_html.indexOf("<"));
var new_lev = parseInt(cur_level) + parseInt(delta_level);
td.innerHTML = getSpacesForLevel(new_lev) + prev_html;
children[j].setAttribute("level", new_lev);
children[j].style.backgroundColor = arrColors[new_lev];
}
}
}// for
checkAll(0); // uncheck all checkboxes
}// if
}// if checked
// AJAX request to set level
}
}Syhi-подсветка кода
{
var delta_level = -1;
if(direction == "down")
delta_level = 1;
var checkboxes = document.getElementsByName("tree_items[]");
for(var i=0; i<checkboxes.length; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var current_level = row.getAttribute("level");
if(current_level != 0 || direction == "down") // dont move up row with level = 0
{
var td = checkboxes[i].parentNode.nextSibling;
if(td.nodeType == 3)
td = checkboxes[i].parentNode.nextSibling.nextSibling;
var prev_html = td.innerHTML;
prev_html = prev_html.slice(prev_html.indexOf("<"));
var new_level = parseInt(current_level) + parseInt(delta_level);
td.innerHTML = getSpacesForLevel(new_level) + prev_html;
row.setAttribute("level", new_level);
row.style.backgroundColor = arrColors[new_level];
var tbody = document.getElementById('table_body');
var children = tbody.childNodes;
var row_index = getRowIndex(row);
if(direction == "down")
row_index++;
for(var j=row_index; j<children.length; j++)
{
if(children[j].tagName == 'TR')
{
if(children[j].getAttribute("level") == current_level)
break;
if(children[j].getAttribute("level") > current_level)
{
var cur_level = children[j].getAttribute("level")
var td = children[j].childNodes[3];
if(td.innerHTML.indexOf("<img") == -1) // IE and Safari hack
td = children[j].childNodes[1];
var prev_html = td.innerHTML;
prev_html = prev_html.slice(prev_html.indexOf("<"));
var new_lev = parseInt(cur_level) + parseInt(delta_level);
td.innerHTML = getSpacesForLevel(new_lev) + prev_html;
children[j].setAttribute("level", new_lev);
children[j].style.backgroundColor = arrColors[new_lev];
}
}
}// for
checkAll(0); // uncheck all checkboxes
}// if
}// if checked
// AJAX request to set level
}
}Syhi-подсветка кода
А также функции дублирования:
function duplicateSingle()
{
var checkboxes = document.getElementsByName("tree_items[]");
var tbody = document.getElementById("table_body");
var len = checkboxes.length; // FireFox hack (against constant reference to collection of checkboxes)
for(var i=0; i<len; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var inserted_row = tbody.appendChild(row.cloneNode(1));
var td = inserted_row.childNodes[3];
if(td.innerHTML.indexOf("<img") == -1) // IE and Safari hack
td = inserted_row.childNodes[1];
var cell_content = td.innerHTML;
var ins_pos = cell_content.indexOf("</b>");
td.innerHTML = cell_content.slice(0, ins_pos) + " Copy" + cell_content.slice(ins_pos);
}
}
checkAll(0);
}
function duplicateBranch()
{
var checkboxes = document.getElementsByName("tree_items[]");
var tbody = document.getElementById("table_body");
var len = checkboxes.length; // FireFox hack (against constant reference to collection of checkboxes)
for(var i=0; i<len; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var inserted_row = tbody.appendChild(row.cloneNode(1));
var current_level = inserted_row.getAttribute("level");
var tbody = document.getElementById('table_body');
var children = tbody.childNodes;
var row_index = getRowIndex(row);
for(var j=(row_index+1); j<children.length; j++)
{
if(children[j].tagName == 'TR')
{
if(children[j].getAttribute("level") == current_level)
break;
if(children[j].getAttribute("level") > current_level)
{
tbody.appendChild(children[j].cloneNode(1));
}
}
}
}
}
checkAll(0);
}Syhi-подсветка кода
{
var checkboxes = document.getElementsByName("tree_items[]");
var tbody = document.getElementById("table_body");
var len = checkboxes.length; // FireFox hack (against constant reference to collection of checkboxes)
for(var i=0; i<len; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var inserted_row = tbody.appendChild(row.cloneNode(1));
var td = inserted_row.childNodes[3];
if(td.innerHTML.indexOf("<img") == -1) // IE and Safari hack
td = inserted_row.childNodes[1];
var cell_content = td.innerHTML;
var ins_pos = cell_content.indexOf("</b>");
td.innerHTML = cell_content.slice(0, ins_pos) + " Copy" + cell_content.slice(ins_pos);
}
}
checkAll(0);
}
function duplicateBranch()
{
var checkboxes = document.getElementsByName("tree_items[]");
var tbody = document.getElementById("table_body");
var len = checkboxes.length; // FireFox hack (against constant reference to collection of checkboxes)
for(var i=0; i<len; i++)
{
if(checkboxes[i].checked)
{
var row = checkboxes[i].parentNode.parentNode;
var inserted_row = tbody.appendChild(row.cloneNode(1));
var current_level = inserted_row.getAttribute("level");
var tbody = document.getElementById('table_body');
var children = tbody.childNodes;
var row_index = getRowIndex(row);
for(var j=(row_index+1); j<children.length; j++)
{
if(children[j].tagName == 'TR')
{
if(children[j].getAttribute("level") == current_level)
break;
if(children[j].getAttribute("level") > current_level)
{
tbody.appendChild(children[j].cloneNode(1));
}
}
}
}
}
checkAll(0);
}Syhi-подсветка кода
Кому нужны будут подробные объяснения, или кто сталкивался с подробной задачей - сообщите об этом в комментах.
Удачи!
Комментариев нет:
Отправить комментарий