|
|
|
| Доброго времени суток.
Возникла необходимость выводить разделы и подразделы в таком виде:
Раздел1 (+)
Раздел2 (+)
Раздел3 (+)
|
По нажатию на название раздела 1(2,3...n) , открывается данный раздел и показываются все подразделы этого раздела, а именно:
Раздел1 (-)
--Подраздел 1
--Подраздел 2
--Подраздел 3
Раздел2 (+)
Раздел3 (+)
|
При нажатии на имя раскрытого раздела, содержимое должно свернуться
Данные о разделах хранятся в MySQL в таком виде
CREATE TABLE IF NOT EXISTS `table` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`parent` int(9) NOT NULL,
PRIMARY KEY (`id`)
) ;
--
-- Дамп данных таблицы `table`
--
INSERT INTO `table` (`id`, `name`, `parent`) VALUES
(1, 'Раздел1', 0),
(2, 'Раздел2', 0),
(3, 'Раздел3', 0),
(4, 'ПодРаздел1', 1),
(5, 'ПодРаздел2', 1),
(6, 'ПодРаздел3', 1),
(7, 'ПодРаздел1', 2),
(8, 'ПодРаздел2', 2),
(9, 'ПодРаздел1', 3),
|
Вывод делаю таким образом:
<script language="JavaScript">
function expandit(id)
{
obj = document.getElementById(id);
if (obj.style.display=="none") obj.style.display="";
else obj.style.display="none";
}
</script>
<?php
$res = mysql_query("SELECT t1.name AS level1, t2.name AS level2, t2.parent AS par
FROM table t1
LEFT JOIN table t2
ON (t1.id = t2.parent)
WHERE t1.parent = '0'");
$title = NULL;
while ($line = mysql_fetch_assoc($res))
{
if($title != $line['level1'])
{
echo "<b style=\"cursor:pointer;\" onClick=\"expandit('ans".$line['par']."')\">".$line['level1']."</b><br/>";
$title = $line['level1'];
}
echo "<span id = \"ans".$line['par']."\" style=\"display:none\">".$line['level2']."</span><br/>";
}
?>
|
Проблема в том, что при развертывании подразделов, показывает лишь первый подраздел, остальные не видны, в чем моя ошибка? | |
|
|
|
|
|
|
|
для: selma
(03.09.2012 в 09:07)
| | Вы покажите результирующий код вашего меню, а не запрос к MySQL. | |
|
|
|
|
|
|
|
для: confirm
(03.09.2012 в 09:53)
| | Не поняла, какой код? исходный код страницы или что?
Выводит так:
Раздел1
--Подраздел1
Раздел2
Раздел3
|
по нажатию на любой раздел, выводит только первый подраздел нажатого раздела
а нужно чтобы выводило все подразделы нажатого раздела
исходный код страницы:
<b style="cursor:pointer;" onClick="expandit('ans1')">Раздел1</b><br/>
<span id = "ans1" style="display:none">Подраздел1</span><br/>
<span id = "ans1" style="display:none">Подраздел2</span><br/>
<span id = "ans1" style="display:none">Подраздел3</span><br/>
|
| |
|
|
|
|
|
|
|
для: selma
(03.09.2012 в 10:59)
| | Можно конечно и на span сделать, но лучше на списках. Примерно так:
<style>
ul {
list-style: none;
cursor: pointer;
}
ul ul {display: none;}
.sub {display: inline-block;}
</style>
<script>
function showTree(e) {
if(e.tagName=='LI' && e.lastChild.tagName=='UL') {
var u = e.parentNode.getElementsByTagName('ul');
for(var i=0; i<u.length; i++) u[i].className = u[i].className.replace('sub','');
e.lastChild.className = 'sub';
}
}
</script>
<ul onclick="showTree(event.target || event.srcElement)">
<li>Root 1
<ul>
<li><a href="#">Sub 1-1</a></li>
<li><a href="#">Sub 1-2</a></li>
<li><a href="#">Sub 1-3</a></li>
</ul>
</li>
<li>Root 2
<ul>
<li><a href="#">Sub 2-1</a></li>
<li><a href="#">Sub 2-2</a></li>
<li><a href="#">Sub 2-3</a></li>
</ul>
</li>
<li>Root 3
<ul>
<li><a href="#">Sub 3-1</a></li>
<li><a href="#">Sub 3-2</a></li>
<li><a href="#">Sub 3-3</a></li>
</ul>
</li>
</ul>
|
PS. Если меню (вложения его) будут без излишеств, то вместо управления классом вложений его, меняйте видимость их:
for(var i=0; i<u.length; i++) u[i].style.display = 'none';
e.lastChild.style.display = 'inline-block';
|
а в стилях для ul ul пропишите нужное. | |
|
|
|
|
|
|
|
для: selma
(03.09.2012 в 10:59)
| | Метод getElementById () возвращает первый в коде элемент с указанным ID.
Второго-третьего-десятого элемента с тем же значением ID этим методом вы не увидите и не "достанете".
Отсюда, кстати, вытекает правило, что ID на странице должны быть уникальными.
Какой смысл тегу иметь идентификатор, по которому нельзя к этому тегу обратиться?
-----
Задачу вашу можно решить, используя другой метод - getElementsByName () и, соответственно,
другой атрибут - NAME вместо ID у тегов <SPAN>.
Значения атрибутов NAME на странице вполне могут повторяться:
обратите внимание на буквочку s в названии метода getElementsByName () -
эта буквочка говорит о множественном числе элементов с каким-то значением NAME
(а у метода getElementById (), как видите, таковой буквочки нет).
<script>
function expandit (x)
{
for (var s = document.getElementsByName (x), j = 0, lj = s.length; j < lj; j++)
with (s [j].style) display = (display == 'none') ? '' : 'none';
}
</script>
<b style="cursor: pointer" onClick="expandit ('ans1')">Раздел1</b><br/>
<span name="ans1" style="display: none">Подраздел1</span><br/>
<span name="ans1" style="display: none">Подраздел2</span><br/>
<span name="ans1" style="display: none">Подраздел3</span><br/>
|
PS. Это, правда, будет не очень валидно (атрибуты NAME тегам <SPAN> по спецификации HTML4 как бы не положены),
но зато будет везде работать. | |
|
|
|
|
|
|
|
для: ЯСА
(03.09.2012 в 15:05)
| | ЯСА огромное спасибо
работает, только юзабилити нарушается неравномерным расстоянием между закрытыми категориями.
Я так поняла, что расстояние между родителями завсисит от кол-ва подкатегорий содержащихся в родителе
Это как нибудь можно обойти?
Например чтобы все родители были один за одним:
А при нажатии, получалось:
Раздел1
-Подраздел1
-Подраздел2
Раздел2
Раздел3
|
| |
|
|
|
|
|
|
|
для: selma
(04.09.2012 в 09:22)
| | Расстояние между разделами зависит напрямую от количества тегов <br>, которыми у вас разделены <span>'ы с подразделами.
Ведь их (тегов <br>) функция скрытия/открытия никак не затрагивает.
Решение простое - убрать теги <br> вовсе, а тегам <span> в блоке стилей присвоить значение {display: block}.
Ну, или - как полностью безумный вариант - можно теги <br> переместить внутрь тегов <span>, вот так:
<span name="ans1" style="display: none">Подраздел1<br/></span>
<span name="ans1" style="display: none">Подраздел2<br/></span>
<span name="ans1" style="display: none">Подраздел3<br/></span>
|
Самое смешное, что этот бред собачий (последний вариант - с помещением тега <br> внутрь inline-тега <span>) пройдёт без замечаний в любом валидаторе :-) | |
|
|
|
|
|
|
|
для: ЯСА
(04.09.2012 в 11:34)
| | Огромное спасибо, вы АЯС, как всегда в точку. Я вам очень благодарна | |
|
|
|
|
|
|
|
для: selma
(05.09.2012 в 07:36)
| | Чтобы не плодить темы, решила спросить здесь, ибо вопрос всё по тому же коду
<?php
$res = mysql_query("SELECT t1.name AS level1, t2.name AS level2, t2.id AS id,
FROM table t1
LEFT JOIN table t2
ON (t1.id = t2.parent)
WHERE t1.parent = '0'");
$title = NULL;
while ($line = mysql_fetch_assoc($res))
{
if($title != $line['level1'])
{
echo "<b style=\"cursor:pointer;\" onClick=\"expandit('ans".$line['id']."')\">".$line['level1']."</b><br/>";
$title = $line['level1'];
}
echo "<div id ='ans".$line['id']."' style='display:none'>".$line['level2']."</div>";
}
?>
|
есть некий массив, допустим $arr = array('12','25','42');
Как сделать, чтобы при выводе подразделов в собранном виде, и при совпадении ID разделов с элементом массива, все содержимое раздела в котором присутствует совпадающий элемент раскрылось? | |
|
|
|
|
|
|
|
для: selma
(11.09.2012 в 02:04)
| | Можно, конечно, решить и на javascript - вывести этот массив в скриптовом виде и по onload страницы запустить цикл, перебирающий элементы этого массива и запускающий функцию expandit ('ans' + элемент_массива)
Но рациональнее это сделать в PHP.
Перед формированием строки
echo "<div id ='ans".$line['id']."' style='display:none'>".$line['level2']."</div>";
| проверить на совпадение $line ['id'] с элементами массива и при таковом выводить без display: none
echo "<div id ='ans".$line['id']."'>".$line['level2']."</div>";
|
| |
|
|
|
|
|
|
|
для: ЯСА
(11.09.2012 в 08:06)
| | не все так просто
сделала так (допустим что в массиве всегда 2 значения):
if ($arr[0] == $line['id'] OR $arr[1] == $line['id'])
{
$disp = 'display:block';
}
else { $disp = 'display:none'; }
echo "<div id ='ans".$line['id']."' style='".$disp."'>".$line['level2']."</div>";
|
НО, теперь при совпадении показывает только совпавший элемент, а мне нужно чтобы показало все элементы скрытого раздела, в котором присутствует совпавший элемент
Предположим что у нас с элементом массива совпал Подраздел1
выведет так:
Раздел1
-Подраздел1
Раздел2
Раздел3
|
а надо:
Раздел1
-Подраздел1
-Подраздел1
Раздел2
Раздел3
|
если сделать как сказали вы, т.е при совпадении убирать display:none. То открывает все разделы, при этом не выделяя совпадающие | |
|
|
|
|
|
|
|
для: selma
(11.09.2012 в 09:18)
| | Пытаюсь понять логику вашего кода, но пока не понимаю.
То, что вы теги <span> для ПОДразделов заменили на <div> - это понятно.
Но вот остальное...
1. Вроде бы договорились у ПОДразделов писать не id, а name.
Но вы в предлагаем PHP-коде упорно прописываете им id.
Это - "непонятка" номер раз.
2. Во-вторых, в предыдущих примерах все ПОДразделы одного раздела имели у вас одно и то же значение для атрибута name.
Если это положение сохранилось, то все ПОДразделы одного раздела должны иметь одно и то же значение $line['id'] и при совпадении с элементом массива они все должны получить стиль display: block и все должны быть видны при выводе.
Однако, как следует из вашего PHP-кода и разъяснений к нему, ситуация у вас изменилась - ПОДразделы одного раздела теперь имеют у вас разные значения.
Это - "непонятка" номер два.
Согласитесь, очень трудно "въехать" в код, логика которого вами спонтанно меняется и вы об этих изменениях ни гу-гу не пишете :-(( | |
|
|
|
|
|
|
|
для: ЯСА
(11.09.2012 в 09:37)
| | Простите что ввела в заблуждение:
1. Действительно везде вместо id стоит name, это я скопировала старый код указанный в начале этой темы
<?php
$res = mysql_query("SELECT t1.name AS level1, t2.name AS level2, t2.id AS id, t1.id_r AS par
FROM table t1
LEFT JOIN table t2
ON (t1.id = t2.parent)
WHERE t1.parent = '0'");
$title = NULL;
$arr = array('12','25','42');
while ($line = mysql_fetch_assoc($res))
{
if($title != $line['level1'])
{
echo "<b style=\"cursor:pointer;\" onClick=\"expandit('ans".$line['par']."')\">".$line['level1']."</b><br/>";
$title = $line['level1'];
}
if ($arr[0] == $line['id'] OR $arr[1] == $line['id'])
{
$disp = 'display:block';
}
else { $disp = 'display:none'; }
echo "<div name ='ans".$line['par']."' style='".$disp."'>".$line['level2']."</div>";
}
?>
|
2. Попытаюсь разъяснить с идентификаторами
Есть разделы и подразделы, каждый из разделов и подразделов имеет свой id (это видно из первого сообщения темы)
$line['id'] уникальное ID Подраздела
$line[par'] уникальное ID Раздела
я сравниваю, не ID Разделов, а ID подразделов (потому что массив $arr несет в себе значения id подразделов)
наглядное отображение кода (при условии, что подраздел1 имеет ID:12, а подраздел6 имеет ID:25 ):
<div style="cursor:pointer;" onClick="expandit('ans1')"> Раздел1</div>
<div name = 'ans1' style='display:block'>подраздел1</div>
<div name = 'ans1' style='display:none'>подраздел2</div>
<div name = 'ans1' style='display:none'>подраздел3</div>
<div style="cursor:pointer;" onClick="expandit('ans2')">Раздел2</div>
<div name = 'ans2' style='display:none'>подраздел4</div>
<div name = 'ans2' style='display:none'>подраздел5</div>
<div name = 'ans2' style='display:block'>подраздел6</div>
<div style="cursor:pointer;" onClick="expandit('ans3')">Раздел3</div>
|
т.е по исходному коду все ровно, а на странице отображается:
Раздел1
-Подраздел1
Раздел2
-Подраздел6
Раздел3
|
а должно
Раздел1
-Подраздел1
-Подраздел2
-Подраздел3
Раздел2
-Подраздел4
-Подраздел5
-Подраздел6
Раздел3
|
| |
|
|
|
|
|
|
|
для: selma
(11.09.2012 в 10:05)
| | Впринципе мысль уловила. Нужно имея значения id-подразделов, вытаскивать id-разделов, и уже их сравнивать.
Что-то подобное получилось, но уж больно дико выглядит... | |
|
|
|
|
|
|
|
для: selma
(11.09.2012 в 10:36)
| | Уважаемый АЯС, апочему-то наш JS не работает в IE:((
можно какой-нибудь хак дописать? | |
|
|
|
|
|
|
|
для: selma
(12.09.2012 в 07:38)
| | Хак простой - спанам (или дивам? - я уже запутался) подразделов надо прописать и NAME, и ID оновременно. И с одинаковым значением:
<script>
function expandit (x)
{
for (var s = document.getElementsByName (x), j = 0, lj = s.length; j < lj; j++)
with (s [j].style) display = (display == 'none') ? '' : 'none';
}
</script>
<b style="cursor: pointer" onclick="expandit ('ans1')">Раздел1</b><br/>
<span name="ans1" id="ans1" style="display: none">Подраздел1</span><br/>
<span name="ans1" id="ans1" style="display: none">Подраздел2</span><br/>
<span name="ans1" id="ans1" style="display: none">Подраздел3</span><br/>
|
| |
|
|
|
|
|
|
|
для: ЯСА
(12.09.2012 в 08:01)
| | сейчас у меня везде DIV, спасибо за подсказку. | |
|
|
|
|