为什么这个可扩展列表在php中没有以正确的方式显示项目?

时间:2016-01-30 05:29:58

标签: javascript php jquery expandable

我正在尝试创建一个可扩展列表。它以下列方式正确显示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       - 课程0            - 学生0            - 学生1            - 学生2
    • Department1       - 课程1            - 学生0            - 学生1            - 学生2
    • Department2       - 课程2            - 学生0            - 学生1            - 学生2

我可能做错了什么?我的逻辑似乎是正确的。

1 个答案:

答案 0 :(得分:1)

代码破坏:PHP错误

您的代码会触发

等错误
  

“注意:未定义的变量:countOfStudents

(与countOfCoursescountOfDepartments相同),因为您没有定义这些变量:

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替换未定义的变量,现在它可以正常工作,但它缺少最后一次出现的部门,课程和学生,如下所示:

enter image description here

如下面针对部门所示,您的代码依次为:

  • 为大学打开<ul>,然后为部门#0打开<li>

    if ($department == 0) {
      echo '<ul>';
      echo '<li>';
      echo "d".$department;
    }
    
  • 关闭(最后)部门#2的<li>,然后关闭大学的<ul>

    else if ($department == 3 - 1) {
      echo '</li>';
      echo '</ul>';
    
  • 为任何其他部门(此处为#1)打开<li>

    } 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;
}

现在给出了预期的结果:

enter image description here