|
|
|
|
<?php
function showTree($parent,$level) {
global $list, $smarty, $link;
$q = mysql_query("SELECT * FROM modules WHERE visib=1 and pid=$parent and id_blocks=6 ORDER BY id_mod") or die (mysql_error());
if ($level > 0 && mysql_num_rows($q) > 0) {
$divopn = "<div id='dropmenu2_a' class='dropmenudiv_a' style='width: 150px;'>";
$divcls = "</div>";
$liopn = "";
$licls = "";
} else{
$divopn = "";
$divcls = "";
$liopn = "<li>";
$licls = "</li>";
$list .= $divopn;
}
while ($row = mysql_fetch_row($q)) {
$title = $row[3];
$list .= $liopn;
$list .= "<A HREF='?id=$row[0]' title=\"$title\"><span>".htmlspecialchars($title)."</span></A>";
showTree($row[0],$level+1);
$list .= $licls;
}
$list .= $divcls;
}
$list = "<div id='colortab' class='ddcolortabs'>";
$list .= "<ul>";
showTree(0,0);
$list .= "</ul>";
$list .= "</div>";
?>
|
Проблема такая: в результирующем коде внутри <div></div>, которые выводят подменю, появляются вложенные <li></li>. Как он них избавиться, чтобы получилось вот такое:
<div id="colortab" class="ddcolortabs">
<ul>
<li></li>
<li><a href="" title="CSS" rel="dropmenu2_a"><span>3333</span></a></li>
</ul>
</div>
<!--подменю -->
<div id="dropmenu2_a" class="dropmenudiv_a" style="width: 150px;">
<a href="">11111</a>
<a href="">22222</a>
</div>
|
Я не привожу стили и JS, если в этом есть необходимость, скажите.
Сейчас на данный момент все меню - и родители, и потомки выводятся в одну строку.
Заранее всем спасибо. | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 11:49)
| | Вот этот оператор , похоже, у Вас живет своей жизнью. Меняется от версии к версии как бог на душу положит.
if ($level > 0 && mysql_num_rows($q) > 0) {
$divopn = "<div id='dropmenu2_a' class='dropmenudiv_a' style='width: 150px;'>";
$divcls = "</div>";
$liopn = "";
$licls = "";
} else{
$divopn = "";
$divcls = "";
$liopn = "<li>";
$licls = "</li>";
$list .= $divopn;
}
|
В ветви else Вы сами пишете - Если вложенных элементов нет, ставим $liopn = "<li>"; $licls = "</li>";
Зачем? | |
|
|
|
|
|
|
|
для: Trianon
(09.07.2008 в 13:45)
| | Если вложенных элементов нет, мы оформляем каждый элемент в виде элемента списка:
<li><A HREF='?id=24' title="О нас"><span>О нас</span></A>
Это будет список родителей.
Если же вложенные элементы есть, то внутри <li> появляется свой стиль (<div></div>). И тогда результирующий код будет вот таким:
<li>
<div id='dropmenu2_a' class='dropmenudiv_a' style='width: 150px;'>
<A HREF='?id=26' title="Информация"><span>Информация</span></A>
<A HREF='?id=27' title="Связаться с нами"><span>Связаться с нами</span></A>
</div>
</li>
Переставила у себя в коде скобку:
else{
$divopn = "";
$divcls = "";
$liopn = "<li>";
$licls = "</li>";
}
$list .= $divopn;
|
Теперь результирующий код нормальный - все тэги на местах, но почему-то только родителей показывает, а потомки не выпадают. Что можно сделать? | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 14:13)
| | Приведите пожалуйста дамп структуры и данных таблицы.
У меня уже нет сил рассуждать на уровне голой теории. | |
|
|
|
|
1.9 Кб |
|
|
для: Trianon
(09.07.2008 в 14:54)
| | Дамп таблицы. Все, что относится к меню. | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 15:33)
| | То есть уровней всего и ровно два? | |
|
|
|
|
|
|
|
для: Trianon
(09.07.2008 в 15:57)
| | Да, уровней всего два | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 16:32)
| | Вот те раз...
Тогда логично предположить, что верхний уровень и нижний уровни отображаются совсем по-разному.
И тогда здесь совершенно не нужна рекурсия. Рекурсия предполагает одинаковую (или очень близкую) обработку на всех уровнях. А в Вашем случае она только мешать будет.
Вопрос номер два. Как должен выглядеть HTML-код для приведенных в предыдущем посте строк таблицы?
Похоже, проще будет написать php-код, просто зная аргумент и результат. | |
|
|
|
|
9.8 Кб |
|
|
для: Trianon
(09.07.2008 в 16:43)
| | Мне рекурсия жить не мешает, но если здесь лучше без нее, то давайте пробовать.
Я вам высылаю все, что есть в этом меню, стили и JS, в теле - HTML-код, который должен получиться. Я не помню, как там идут по порядку пункты меню, написала в разброс, но смысл, что верхний уровень одним стилем выводится, нижний - другим. | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 17:06)
| | Честно говоря смутно представляю что Вы хотите получить. Но чтобы избавится от <li> в подменю попробуйте заменить код на следующее
<?php
function showTree($parent,$level) {
global $list, $smarty, $link;
$q = mysql_query("SELECT * FROM modules WHERE visib=1 and pid=$parent and id_blocks=6 ORDER BY id_mod") or die (mysql_error());
if ($level > 0 && mysql_num_rows($q) > 0) {
$divopn = "<div id='dropmenu2_a' class='dropmenudiv_a' style='width: 150px;'>";
$divcls = "</div>";
$liopn = "";
$licls = "";
} else{
$divopn = "";
$divcls = "";
//$liopn = "<li>";
//$licls = "</li>";
$list .= $divopn;
}
while ($row = mysql_fetch_row($q)) {
$title = $row[3];
//$list .= $liopn;
$list .= "<A HREF='?id=$row[0]' title=\"$title\"><span>".htmlspecialchars($title)."</span></A>";
showTree($row[0],$level+1);
//$list .= $licls;
}
$list .= $divcls;
}
$list = "<div id='colortab' class='ddcolortabs'>";
//$list .= "<ul>";
showTree(0,0);
//$list .= "</ul>";
$list .= "</div>";
?>
|
И если не сложно можно посмотреть что именно Вы заменили ? | |
|
|
|
|
|
|
|
для: White_Owl
(09.07.2008 в 17:28)
| | >Честно говоря смутно представляю что Вы хотите получить...
Не обижайтесь, но вы, похоже, вообще себе не представляете, что я хочу получить. Почитайте предыдущие посты. Там в аттачменте все файлы. | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 17:06)
| | Вот примерно то, что вышло.
<?php
require_once('dbconfig.php');
/* Это то, что требуется получить:
<div id="colortab" class="ddcolortabs">
<ul>
<li><a href="" title="Главная"><span>Главная</span></a></li>
<li><a href="" title="Карта сайта"><span>Карта сайта</span></a></li>
<li><a href="" title="О нас" rel="dropmenu1_a"><span>О нас</span></a></li>
<li><a href="" title="Архив" rel="dropmenu2_a"><span>Архив</span></a></li>
</ul>
</div>
<div class="ddcolortabsline"> </div>
<!--подменю -->
<div id="dropmenu1_a" class="dropmenudiv_a" style="width: 150px;">
<a href="">Контакты1</a>
<a href="">Связаться с вами1</a>
</div>
<div id="dropmenu2_a" class="dropmenudiv_a" style="width: 150px;">
<a href="">Контакты2</a>
<a href="">Связаться с вами2</a>
</div>
* А это сам код: */
$sql =
"SELECT m.id_mod AS mid_mod
,m.name AS mname
,m.descr AS mdescr
,e.id_mod AS eid_mod
,e.name AS ename
,e.descr AS edescr
FROM modules AS m
LEFT JOIN modules AS e
ON m.id_mod = e.pid AND e.id_blocks = 6 AND e.visib=1
WHERE m.pid = 0 AND m.id_blocks = 6 AND m.visib=1
ORDER BY mid_mod, eid_mod";
$res = mysql_query($sql) or die("Error in $sql : ".mysql_error());
for($m = array(),$mhtm = $ehtm = $cmod = $mclose = $eclose = '';
$row = mysql_fetch_assoc($res) ;)
{
$mid_mod = $row['mid_mod'];
$mname = htmlspecialchars($row['mname']);
$mdescr = htmlspecialchars($row['mdescr']);
$eid_mod = $row['eid_mod'];
$ename = htmlspecialchars($row['ename']);
$edescr = htmlspecialchars($row['edescr']);
if($cmod != $mid_mod)
{
$cmod = $mid_mod;
$ehtm .= $eclose; $eclose ='';
$relname = $rel = '';
if(!empty($eid_mod))
{
$relname = '"dropmenu'.$cmod.'_a"';
$rel = " rel=$relname";
}
$mhtm .= "<li><a href=\"?m=$cmod\" title=\"$mdescr\" $rel"
. "><span>$mname</span></a></li>\r\n";
if(!empty($eid_mod))
{
$ehtm .= '<div id="dropmenu'.$eid_mod.'_a "'
. ' class="dropmenudiv_a" style="width: 150px;">'."\r\n";
$eclose = "</div>\r\n";
}
}
if(!empty($eid_mod))
$ehtm .= '<a href="'."?m=$cmod&e=$eid_mod".'">'.$ename.'</a>'."\r\n";
}
if($mclose != '') $mhtm .= $mclose;
if($eclose != '') $ehtm .= $eclose;
$h = '
<div id="colortab" class="ddcolortabs">
<ul>
'.$mhtm.'</ul>
</div>
<div class="ddcolortabsline"> </div>
<!--подменю -->
'.$ehtm;
echo $h;
?>
|
Начало со стилями, JS-кодом , и прочими весёлостями , конечно, надо добавить сверху. | |
|
|
|
|
|
|
|
для: Trianon
(09.07.2008 в 18:55)
| | В запросе разобралась. Для тех, кто еще этого не знает, - http://www.mysql.ru/docs/gruber/ или в Гугле поискать "Объединение таблиц".
Здесь - объединение таблицы самой себя, как бы создаются две ее копии и чтобы они были обработаны независимо в одном запросе, каждой присваивается псевдоним (m, e). Чтобы ссылаться к отдельным столбцам таблиц внутри запроса им тоже присваиваются псевдонимы.
Вопрос 1. Предложение FROM modules AS m в разных источниках встречается как FROM modules m. Это альтернативный синтаксис?
Когда получаем результаты выполнения запроса, в цикле for начинается их перебор.
Вопрос 2. Непонятно условие цикла $mhtm = $ehtm = $cmod = $mclose = $eclose = '';
Цикл работает до тех пор, пока эти переменные пустые. Допустим, выбирается первый ряд из таблицы - и тогда $mhtm заполняется и уже эта переменная не пустая. Объясните.
Вопрос 3.
$cmod = $mid_mod; Зачем вводить еще одну переменную, почему просто в нужном месте не использовать уже ранее определенную $mid_mod?
Все остальное понятно.
Большое человеческое спасибо, Trianon | |
|
|
|
|
|
|
|
для: Лена
(10.07.2008 в 15:26)
| | >В запросе разобралась.
Респект.
0. Операцию JOIN обычно называют соединением. Термин "объединение" применяют для операции UNION. В остальном таки да.
1. Да. Но я привык писать AS явно. Некоторые СУБД "едят" один вариант , некоторые другой. MySQL "ест" оба.
2. for($m = array(),$mhtm = $ehtm = $cmod = $mclose = $eclose = '';
$row = mysql_fetch_assoc($res) ;)
>Непонятно условие цикла $mhtm = $ehtm = $cmod = $mclose = $eclose = '';
Это не условие. Условие в for-заголовке начинается после точки-с-запятой Это обычная операция присваивания, как и $m=array() . Можно было записать её до for отдельным оператором или даже несколькими. Всем указанным переменным до цикла присваиваются пустые строки.
Кстати, только сейчас заметил: $m=array(), вообще не нужно. Была мысль сперва сохранить строки в отдельном массиве. Потом обошелся. Так что надо сократить до for( $mhtm=$ehtm = ...
Итак, условие у нас после (точнее между) точки-с-запятой: $row = mysql_fetch_assoc($res)
На самом деле это тоже операция присваивания, и цикл оценивает её результат таким образом
($row = mysql_fetch_assoc($res)) != false
То бишь присвоить переменной $row массив с очередной строкой выборки (если строка есть) либо признак её отсутствия(если строки нету) . Присвоенное сравнить с false. признак окончания совпадет с false - массив окажется отличен.
3. переменная $cmod введена в первую очередь для создания условия
if($cmod != $mid_mod)
{
и ветви под ним. Ветвь эта выполняется лишь один раз на группу элементов подменю соответствующих одному элементу горизонтального меню.
Эта переменная (точнее это условие) позволяет разбить строки на группы.
Для второй и последующих строк группы из всего тела цикла выполняется только
if(!empty($eid_mod))
$ehtm .= '<a href="'."?m=$cmod&e=$eid_mod".'">'.$ename.'</a>'."\r\n";
и больше ничего.
Почему не использовал $mid_mod в ссылках?
Мог и её. Использовал ту, что легче написать :) | |
|
|
|
|
|
|
|
для: Trianon
(10.07.2008 в 16:30)
| | Спасибо за объяснения.
А теперь самое интересное: меню не работает.
Выводятся только родители, непослушные потомки опять куда-то исчезают.
В результирующем коде получается вот что:
//это строка родителя, у которого есть потомки
<li><a href="?m=24" title="Установление контактов с администратором сайта" rel="dropmenu24_a"><span>О нас</span></a></li>
//а это блок подменю этого родителя
<div id="dropmenu26_a " class="dropmenudiv_a" style="width: 150px;">
<a href="?m=24&e=26">Информация</a>
<a href="?m=24&e=27">Связаться с нами</a>
</div>
|
Как можно объяснить, что ссылаемся мы на dropmenu24_a (rel="dropmenu24_a"), а получается <div id="dropmenu26_a "? 24 - это родитель. Зачем родительскому элементу <li> делать ссылку на себя же, когда ссылаться надо на id дочерней ветки, которая открывается?
Может, в этом причина, почему не выходит? | |
|
|
|
|
|
|
|
для: Лена
(11.07.2008 в 11:00)
| | Само собой...
Похоже, я умудрился не последний вариант в ответ отправить.
<?
if($cmod != $mid_mod)
{
$cmod = $mid_mod;
$ehtm .= $eclose; $eclose ='';
$relname = $rel = '';
if(!empty($eid_mod))
{
$relname = '"dropmenu'.$cmod.'_a"';
$rel = " rel=$relname";
$ehtm .= "<div id=$relname"
. ' class="dropmenudiv_a" style="width: 150px;">'."\r\n";
$eclose = "</div>\r\n";
}
$mhtm .= "<li><a href=\"?m=$cmod\" title=\"$mdescr\" $rel"
. "><span>$mname</span></a></li>\r\n";
}
if(!empty($eid_mod))
$ehtm .= '<a href="'."?m=$cmod&e=$eid_mod".'">'.$ename.'</a>'."\r\n";
|
| |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 11:24)
| | Только не злитесь. Там еще один кусок кода есть, который я вам не прислала. Почему-то он выпал.
<script type="text/javascript">
//Синтаксис: tabdropdown.init("menu_id", [integer OR "auto"])
tabdropdown.init("colortab", 3)
</script>
|
Может, в этом проблема? Я его вставила в общий код, но ничего не поменялось | |
|
|
|
|
|
|
|
для: Лена
(11.07.2008 в 12:01)
| | У меня элементы подменю выскакивали и без него. Точнее - в том комплекте, что Вы тогда прислали.
Так что врядли он сильно влияет на замеченный Вами баг.
А вот неверное определение ссылки на дочерний блок влияет однозначно.
После замены фрагмента скрипта лучше не стало?
Я злюсь? И в мыслях не было... | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 12:22)
| | Нет, лучше не стало. Ни мне, ни скрипту :-)
Хотя теперь прямая ссылка из родителя, которая выводится в дочерний блок, есть.
Что будем делать? | |
|
|
|
|
5.6 Кб |
|
|
для: Лена
(11.07.2008 в 12:34)
| | Сравнивать. У меня вот такой набор файлов выводит Ваше меню. | |
|
|
|
|
|
|
|
для: Trianon
(11.07.2008 в 13:01)
| | We are the chempions!
Получилось!!!
Но главный chempion - это вы, Trianon :-))
Ошибки свои нашла. Спасибо, я вам очень благодарна. | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 11:49)
| |
if ($level > 0 && mysql_num_rows($q) > 0) {
|
попробуйте так
if (($level > 0) && (mysql_num_rows($q) > 0)) {
|
Возможно PHP вычисляет это логическое выражение неверно | |
|
|
|
|
|
|
|
для: Лена
(09.07.2008 в 11:49)
| | <div> не нужен, рекурсия тож | |
|
|
|