Почему этот расширяемый список неправильно отображает элементы в php?

Я пытаюсь создать расширяемый список. Это правильно показывает для 1 узла следующим образом:

  • Университет
    • Department0
      • Course0
        Student0

Тем не менее, когда я делаю то же самое для более чем 1 пунктов, т.е. когда число отделов больше 1. Распределяет список где угодно. Вот мой код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Family Tree</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen, projection">
<script type="text/javascript" src="js/jquery-1.4.2.min.js">
</script>
<script type="text/javascript" src="js/scripts.js">
</script>
</script>
</head>
<body>

<h1><b>Demo ExpandableList</b></h1>
<div id="listContainer">
<div class="listControl">
<a id="expandList">Expand All</a>
<a id="collapseList">Collapse All</a>
</div>

<ul id="expList">

<?php

echo '<li>';
echo 'University';

for($department = 0; $department < 3; $department++){if($department == 0){
echo '<ul>';
echo '<li>';
echo "d".$department;
}
else if($department == $countOfDepartments - 1){

echo '</li>';
echo '</ul>';
} else{

echo '<li>';
echo "d".$department;
}

for($course = 0; $course < 3; $course++){

if($course == 0){
echo '<ul>';
echo '<li>';
echo "c".$course;
}
else if($course == $countOfCourses - 1){

echo '</li>';
echo '</ul>';
} else{

echo '<li>';
echo "c".$course;
}

for($student = 0; $student < 3; $student++){
if($student == 0){
echo '<ul>';
echo '<li>';
echo "s".$student;
}
else if($student == $countOfStudents - 1){

echo '</li>';
echo '</ul>';
} else{

echo '<li>';
echo "s".$student;
}
} // for - 3
} // for - 2
}// for - 1
echo '</li>';

?>
</ul>
</div>
</body>
</html>

styles.js:

function prepareList() {
$('#expList').find('li:has(ul)')
.click( function(event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();

//Create the button funtionality
$('#expandList')
.unbind('click')
.click( function() {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})

$('#collapseList')
.unbind('click')
.click( function() {
$('.collapsed').removeClass('expanded');
$('.collapsed').children().hide('medium');
})

};

$(document).ready( function() {
prepareList()
});

style.css:

body {
font-size: 16px;
}

#menu {
list-style: none;
padding: 0;
margin: 0;
}

.clear {
clear: both;
}/********************/
/* EXPANDABLE LIST  */
/********************/
#listContainer{
margin-top:15px;
}

#expList ul, li {
list-style: none;
margin:0;
padding:0;
cursor: pointer;
}
#expList p {
margin:0;
display:block;
}
#expList p:hover {
background-color:#121212;
}
#expList li {
line-height:140%;
text-indent:0px;
background-position: 1px 8px;
padding-left: 20px;
background-repeat: no-repeat;
}

/* Collapsed state for list element */
#expList .collapsed {
background-image: url(../img/collapsed.png);
}
/* Expanded state for list element
/* NOTE: This class must be located UNDER the collapsed one */
#expList .expanded {
background-image: url(../img/expanded.png);
}
#expList {
clear: both;
}

.listControl{
margin-bottom: 15px;
}
.listControl a {
border: 1px solid #555555;
color: #555555;
cursor: pointer;
height: 1.5em;
line-height: 1.5em;
margin-right: 5px;
padding: 4px 10px;
}
.listControl a:hover {
color:#222222;
font-weight:normal;
}

Список, который я пытаюсь получить, имеет следующий формат;

  • Unversity
    • Department0
      — Course0
      — Студент0
      — Студент1
      — Студент2
    • department1
      — Курс 1
      — Студент0
      — Студент1
      — Студент2
    • Department2
      — курс2
      — Студент0
      — Студент1
      — Студент2

Что я, возможно, делаю не так? Моя логика кажется правильной.

1

Решение

Неработающий код: ошибки PHP

Ваш код запускает ошибки, такие как

«Примечание: неопределенная переменная: countOfStudents«

(то же самое с countOfCourses а также countOfDepartments) потому что вы не определили эти переменные:

for ($department = 0; $department < 3; $department++) {
if ($department == 0) {
//...
else if ($department == $countOfDepartments - 1) {

Вместо этого должно быть что-то вроде этого (при условии $countOfDepartments предварительно определено):

for ($department = 0; $department < $countOfDepartments; $department++) {
if ($department == 0) {
//...
else if ($department == $countOfDepartments - 1) {

Код не работает, как ожидалось

Пока, если мы просто заменим неопределенные переменные на 3Теперь он работает без ошибок, но ему не хватает открытия последнего появления факультетов, курсов и студентов, например:

введите описание изображения здесь

Как показано ниже для отделов, ваш код последовательно:

  • открывает <ul> для университета, то <li> для отдела № 0:

    if ($department == 0) {
    echo '<ul>';
    echo '<li>';
    echo "d".$department;
    }
    
  • закрывается <li> для (последнего) отдела № 2, затем <ul> для университета:

    else if ($department == 3 - 1) {
    echo '</li>';
    echo '</ul>';
    
  • открывает <li> для любого другого отдела (здесь # 1):

    } else {
    echo '<li>';
    echo "d".$department;
    }
    

Вы можете заметить, что в нем не хватает открытия последнего отдела и последнего курса, и не отображается последний студент, не говоря уже о закрытии всех отделов, кроме последнего (к счастью, браузер управляет этим).

Как заставить это работать

Таким образом, выше было объяснение, почему вы не получаете то, что ожидаете. Но я не буду предлагать вам способ исправить ваше решение, поскольку оно слишком сложное и не самое эффективное.
Вместо этого вы можете использовать рекурсивный метод, например так:

function array2ul($array) {
$return = NULL;
foreach ($array as $key => $value) {
$return .=
'<li>' . $key . (is_array($value) ? array2ul($value) : $value) . '</li>';
}
return '<ul>' . $return . '</ul>';
}

Тогда весь университет <li> будет выглядеть так:

echo array2ul([
'd0' => [
'c0' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c1' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c2' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
],
'd1' => [
'c0' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c1' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c2' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
],
'd2' => [
'c0' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c1' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
'c2' => ['s0' => NULL, 's1' => NULL, 's2' => NULL,],
],
]);

На этом этапе вы можете сказать, что это решение использует очень простую функцию, но требует более тяжелого предыдущего определения!
Это потому, что я предполагаю, что предоставленный вами случай предназначен только для примера, в то время как для вашего реального приложения вы будете получать исходные данные из базы данных, поэтому вам придется адаптировать исходные данные (и, возможно, функцию) к реальной структуре. ты получаешь.

В любом случае, по крайней мере, для развлечения, давайте превратим текущий пример в простую форму. Вы можете сгенерировать вышеуказанную структуру из простого выражения ваших потребностей, например так:

function generate($groups) {
$name = key($groups);
$number = array_shift($groups);
for ($i = 0; $i < $number; $i++) {
$out[$name . $i] = $groups ? generate($groups) : NULL;
}
return $out;
}

Тогда весь университет <li> становится просто:

echo array2ul(generate(['d' => 3, 'c' => 3, 's' => 3]));

И, наконец, вот весь ваш HTML-код:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Family Tree</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen, projection">
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/scripts.js"></script>
</head>
<body>

<h1><b>Demo ExpandableList</b></h1>
<div id="listContainer">
<div class="listControl">
<a id="expandList">Expand All</a>
<a id="collapseList">Collapse All</a>
</div>

<ul id="expList">
<li>
University
<?php echo array2ul(generate(['d' => 3, 'c' => 3, 's' => 3])); ?>
</li>
</ul>
</div>
</body>
</html>

<?php
function array2ul($array) {
$return = NULL;
foreach ($array as $key => $value) {
$return .=
'<li>' . $key . (is_array($value) ? array2ul($value) : $value) . '</li>';
}
return '<ul>' . $return . '</ul>';
}

function generate($groups) {
$name = key($groups);
$number = array_shift($groups);
for ($i = 0; $i < $number; $i++) {
$out[$name . $i] = $groups ? generate($groups) : NULL;
}
return $out;
}

Теперь он дает ожидаемый результат:

введите описание изображения здесь

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]