1

親/子ツリーをループする関数を使用して、カテゴリとサブカテゴリのリストを示すテーブルがあります。スクリプトのマークアップは次のとおりです。

<table border="1" width="100%" cellspacing="0" cellpadding="2">
    <tr class="dataTableHeadingRow">
        <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
        <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?>&nbsp;</td>
    </tr>

<?php
function category_list( $category_parent_id = 0 )
{
    // build our category list only once
    static $cats;

    if ( ! is_array( $cats ) )
    {
        $sql  = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id';
        $res  = tep_db_query( $sql );
        $cats = array();

        while ( $cat = tep_db_fetch_array( $res ) )
        {
            $cats[] = $cat;
        }
    }

    // populate a list items array
    $list_items = array();

    foreach ( $cats as $cat )
    {
        // if not a match, move on
        if ( ( int ) $cat['parent_id'] !== ( int ) $category_parent_id )
        {
            continue;
        }

        // open the list item
        $list_items[] = '<tr class="dataTableRow">';
        $list_items[] = '<td class="dataTableContent"><li>';

        // construct the category link

        $list_items[] = $cat['categories_name'];

        // recurse into the child list
        $list_items[] = category_list( $cat['categories_id'] );

        // close the list item
        $list_items[] = '</li></td>';
        $list_items[] = '</tr>';
    }

    // convert to a string
    $list_items = implode( '', $list_items );

    // if empty, no list items!
    if ( '' == trim( $list_items ) )
    {
        return '';
    }

    // ...otherwise, return the list
    return '<ul>' . $list_items . '</ul>';
}  

echo category_list();
?>
        <td class="dataTableContent"></td>
</table>

現時点では、これは<tr class="dataTableHeadingRow">と両方を<td class="dataTableHeadingContent">正しく<td class="dataTableContent">印刷しますが、の場合、関数内のタグを正しく印刷するだけです。両方のdataTableContentタグを正しく出力し、両方をループに保持するにはどうすればよいですか? ここに画像の説明を入力してください

4

3 に答える 3

1

関数の再帰的な使用を見ると、 sの要素category_listが出力されます。これは無効なHTMLです。<tr> <li>

また、<tr>本文の各セルには1つのセルしかありませんが<tr>、ヘッダー行のには2つのセルがあります。

出力がどのように見えるかを検討し、それを説明するコードを記述し、フロースルーに従って何が書き出されているかを確認する必要があります。また、ブラウザがどのようにレンダリングするかではなく、ブラウザに返される実際のHTMLソースを確認してください。ブラウザが異なれば、無効なHTMLのレンダリングも異なることに注意してください。

また、(問題とは関係ありませんが)、、、、およびHTML属性をCSSに置き換えることを検討してborderください。もう1つの考慮事項は、and要素を追加のセマンティックマークアップとして使用することです。widthcellspacingcellpaddingalign<head><tbody>

詳細説明

あなたの問題は本質的にこれらの行です:

    // open the list item
    $list_items[] = '<tr class="dataTableRow">';
    $list_items[] = '<td class="dataTableContent"><li>';

    // construct the category link

    $list_items[] = $cat['categories_name'];

    // recurse into the child list
    $list_items[] = category_list( $cat['categories_id'] );

    // close the list item
    $list_items[] = '</li></td>';
    $list_items[] = '</tr>';

ループを繰り返すたびに、新しいtr要素が作成されます。代わりにこれを試してください:

<table border="1" width="100%" cellspacing="0" cellpadding="2">
    <tr class="dataTableHeadingRow">
        <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
        <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?>&nbsp;</td>
    </tr>
    <tr class="dataTableRow">
    <td class="dataTableContent">
<?php
function category_list( $category_parent_id = 0 )
{
    // NOTE THE ADDITIION OF THE PARENT ID:
    $sql  = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
    $res  = tep_db_query( $sql );
    $cats = array();

    while ( $cat = tep_db_fetch_array( $res ) )
    {
        $cats[] = $cat;
    }

   if (count($cats) == 0)
   {
      // There are no categories to list
      return '';
   }

    // Create a list HTML string
    $list = '<ul>';

    foreach ( $cats as $cat )
    {
        // open the list item
        $list .= '<li>';

        // construct the category link

        $list .= $cat['categories_name'];

        // recurse into the child list
        $list .= category_list( $cat['categories_id'] );

        // close the list item
        $list .= '</li>';
    }

    // close and return the list
    $list .= '</ul>';
    return $list;

}  

echo category_list();
?>
        </td>
        <td class="dataTableContent"></td>
    </tr>
</table>

データとプレゼンテーションロジックの分離に関して、さらに改善できることに注意してください。必ずしも本格的なMVCフレームワークを採用する必要はありません。OOPを使用して、データベースエンティティを表すクラス内にSQLクエリをカプセル化するだけです。

編集

各カテゴリは独自のものである必要があるという仕様に従います<td>

これには、リスト要素を削除する必要があります。Aには、子としての要素<ul>のみを含めることができます。<li>子を含めることはできません<tr>。の<td>子である必要があり<tr>ます。他の場所では許可されていません。Aは、、*、または<tr>の子になります。これらのルールはすべてHTMLDTDで定義されています<thead><tbody><tfoot>

したがって、以下はあなたが見なければならない種類のものです:

<table border="1" width="100%" cellspacing="0" cellpadding="2">
    <tr class="dataTableHeadingRow">
        <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
        <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?>&nbsp;</td>
    </tr>
<?php
function category_list( $category_parent_id = 0, $level = 0 )
{
    // NOTE THE ADDITIION OF THE PARENT ID:
    $sql  = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
    $res  = tep_db_query( $sql );
    $cats = array();

    while ( $cat = tep_db_fetch_array( $res ) )
    {
        $cats[] = $cat;
    }

    $list = '';
    foreach ( $cats as $cat )
    {
        // start the next row:
        $list .= "<tr class=\"dataTableRow\">\n";
        // The cell for the category needs
        $list .= "<td class=\"dataTableContent\">\n";

        // construct the category link.  Note we are now enclosing 
        // this in a div with a left-indent to show the sub level
        // this category is at.  Adjust the padding-left calculation 
        // to suit your page
        $list .= '<div style="padding-left: ' . (2 * $level) . 'em;">';
        $list .= "&bull; {$cat['categories_name']}";
        $list .= "</div>\n";

        // close the row
        $list .= "</td>\n";
        $list .= "<td class=\"dataTableContent\"></td>\n";
        $list .= "</tr>\n";

        // recurse into the child list, incrementing $level
        $list .= category_list( $cat['categories_id'], 1+$level );
    }

    // return the list
    return $list;

}

echo category_list();
?>
</table>

*これ<tbody>暗黙の要素であることに注意してください。コードで明示的に定義する必要はありませんが、常にDOMに存在します。

于 2012-09-26T14:30:55.613 に答える
0

配列をループして内容をテーブルの一部として表示するには、ビジネスロジックを表示ロジックからもう少し分離します。ここでの私の解決策は次のようになります。

<!-- populate the array of data to be displayed -->
<?php $list_items = category_list(); ?>

<!-- start the table, display header rows -->
<table border="1" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
    <td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
    <td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?>&nbsp;</td>
</tr>
<tr class="dataTableRow">
<td class="dataTableContent">

<ul>
    <!-- iterate over data array, create ul for each member -->
    <?php 
        foreach($list_items as $item) {
    ?>
        <li><?php print $item ?></li>
    <?php
        }
    ?>
</ul>

<!-- finish the table -->
</td>
</tr>
</table>

<!-- define function which will populate your array -->
<?php
function category_list( $category_parent_id = 0 )
{
    /* 
      this function will look very similar to the one in the 
      one in the original post but will just return the whole
      array instead of printing out one member.
    */

    // populate $items_list...
    return $items_list;
}
?>

この不完全なコードはテストしていませんが、アイデアは正しいはずです。

于 2012-09-26T14:31:35.570 に答える
-1

次のコードを置き換えてみてください。

    $list_items[] = '<tr class="dataTableRow">';
    $list_items[] = '<td class="dataTableContent"><li>';

と:

    $list_items[] = "<tr class='dataTableRow'>";
    $list_items[] = "<td class='dataTableContent'><li>";
于 2012-09-26T14:52:01.340 に答える