Как добавить дополнительный пробел или пунктирный символ для выбора опции?

Я хочу создать дерево выбора для своей категории. Вот для неупорядоченного списка.

function generate_menu($parent, $menu_array = null)
{
    $has_childs = false;
    foreach ($menu_array as $key => $value) {
        if ($value['parent'] == $parent) {
            if ($has_childs === false) {
                $has_childs = true;
                echo "<ul>\n";
            }
            echo '<li><a href="#">'.$value['name'].'</a>';
            generate_menu($key, $menu_array);
            echo "</li>\n";
        }
    }
    if ($has_childs === true)
        echo "</ul>\n";
}

Вот вывод HTML для неупорядоченного списка.

<ul>
  <li>
    Ford
    <ul>
      <li>
        Falcon
        <ul>
          <li>
            Futura
            <ul>
              <li>FPV</li>
              <li>GT</li>
              <li>F6</li>
              <li>GS</li>
            </ul>
          </li>
        </ul>
      </li>
    </ul>
  </li>
  <li>F150</li>
  <li>Festiva</li>
</ul>

Вопрос: как сделать текущую функцию для select option и результаты будут примерно такими.

<select name="categories">
    <option value="Ford">Ford</option>
    <option value="Falcon">-Falcon</option>
    <option value="Futura">--Futura</option>
    <option value="FPV">--FPV</option>
    <option value="GT">---GT</option>
    <option value="F6">---F6</option>
    <option value="GS">---GS</option>
    <option value="F150">-F150</option>
    <option value="Festiva">-Festiva</option>
</select>

person user1286499    schedule 04.01.2013    source источник
comment
замените ul на select и li на option   -  person Ibu    schedule 05.01.2013
comment
Пожалуйста, добавьте также HTML-вывод списка ul/li к вашему вопросу. Обычно это легко преобразовать в строки, которые вы хотите использовать для выбора.   -  person hakre    schedule 05.01.2013
comment
@Ibu Да, конечно, если в неупорядоченном списке, у него есть <ul><li> для разделения дочерних элементов. При выборе опции я хочу добавить - Sub, --Sub, ---Sub.   -  person user1286499    schedule 05.01.2013
comment
Если вы хотите сгенерировать option так же, как вы сделали с ul, вам нужно указать другой параметр для $level. Каждый раз, когда вы входите в функцию, вы увеличиваете $level на единицу, и каждый раз, когда вы выходите туда, вы уменьшаете ее на единицу (в вашем случае это начало и конец функции). Значение по умолчанию для $level равно 0.   -  person hakre    schedule 05.01.2013


Ответы (1)


Я бы использовал текстовый список, который у вас уже есть, легко превратить его в элемент <select>:

$list = <<<LIST
Ford
| Falcon
| | Futura
| | FPV
| | | GT
| | | F6
| | | GS
| F150
| Festiva
LIST;

echo '<select name="categories">', "\n";
foreach (explode("\n", $list) as $entry) {
    $label = strtr($entry, ['| ' => '-']);
    $value = trim($entry, ' |');
    printf("  <option value=\"%s\">%s</option>\n", htmlspecialchars($value), htmlspecialchars($label));
};
echo "</select>\n";

Вывод:

<select name="categories">
  <option value="Ford">Ford</option>
  <option value="Falcon">-Falcon</option>
  <option value="Futura">--Futura</option>
  <option value="FPV">--FPV</option>
  <option value="GT">---GT</option>
  <option value="F6">---F6</option>
  <option value="GS">---GS</option>
  <option value="F150">-F150</option>
  <option value="Festiva">-Festiva</option>
</select>

В противном случае, если вы не смогли сгенерировать этот текстовый список, а только список ul/li, тогда работайте с этим HTML, но таким же образом.

После того, как вы обновили и предоставили HTML, вот как работает строка списка ul/li ($ul) (PHP 5.4):

echo '<select name="categories">', "\n";
foreach ((new SimpleXMLelement($ul))->xpath('//li') as $li) {
    $label = htmlspecialchars(trim($li->xpath('text()[1]')[0]));
    $level = count($li->xpath('ancestor::li'));
    printf(
        "  <option value=\"%s\">%s%s</option>\n",
        $label, str_repeat('-', $level), $label
    );
}
echo "</select>\n";

Как это работает, более подробно описано в этом моем более раннем ответе: Как я могу извлечь структурированный текст из списка HTML в PHP? . Это с DomDocument, а не SimpleXMLElement, как здесь, однако более или менее основной частью является xpath, который предоставляют оба.

Это все прекрасно и денди. Однако вы, должно быть, пропустили фактическое предоставление массива образцов - я только что предположил:

array (
  1 => 
  array (
    'parent' => 0,
    'name' => 'Ford',
  ),
  2 => 
  array (
    'parent' => 1,
    'name' => 'Falcon',
  ),
  3 => 
  array (
    'parent' => 2,
    'name' => 'Futura',
  ),
  4 => 
  array (
    'parent' => 3,
    'name' => 'FPV',
  ),
  5 => 
  array (
    'parent' => 3,
    'name' => 'GT',
  ),
  6 => 
  array (
    'parent' => 3,
    'name' => 'F6',
  ),
  7 => 
  array (
    'parent' => 3,
    'name' => 'GS',
  ),
  8 => 
  array (
    'parent' => 0,
    'name' => 'F150',
  ),
  9 => 
  array (
    'parent' => 0,
    'name' => 'Festiva',
  ),
)

чтобы указать вам на какой-то метод, который соответствует тому, что вы уже сделали для списка ul/li, рекурсивной функции, которая работает с вашим массивом:

function generate_dropdown($menu_array, $parent = 0, $level = -1) {
    ++$level || print('<select name="categories">'. "\n");
    foreach ($menu_array as $key => $value) {
        if ($value['parent'] != $parent) continue;
        $label = htmlspecialchars($value['name']);
        printf("  <option value=\"%s\">%s%s</option>\n", $label, str_repeat('-', $level), $label);
        generate_dropdown($menu_array, $key, $level);
    }
    $level-- || print('</select>');
}

generate_dropdown($array);

Вывод:

<select name="categories">
  <option value="Ford">Ford</option>
  <option value="Falcon">-Falcon</option>
  <option value="Futura">--Futura</option>
  <option value="FPV">---FPV</option>
  <option value="GT">---GT</option>
  <option value="F6">---F6</option>
  <option value="GS">---GS</option>
  <option value="F150">F150</option>
  <option value="Festiva">Festiva</option>
</select>
person hakre    schedule 04.01.2013
comment
Отлично! большое спасибо @hakre. Вы сделали мой день. Кнопка Paypal должна быть в вашем профиле :) - person user1286499; 05.01.2013
comment
Можно добавить имя родителя к детям <option value="Falcon">Ford->Falcon</option>, <option value="FPV">Falcon->Falcon->FPV</option> - person user1286499; 07.01.2013
comment
да, это возможно. этот ответ показывает, что для столбца CHILDREN в выводе (вы превращаете его в список родителей, изменяя ось xpath от ./ul/li до ./ancestor::li), см. также оси xpath здесь: dret.net/lectures/xml /xpath#xpath-оси - person hakre; 07.01.2013
comment
Если ваш список массивов отсортирован, также можно получить родителей, сделав $level массивом родительских элементов. Подсчет этого обеспечивает уровень, и массив даст вам родительские вещи, такие как их ярлыки. Позвольте мне приготовить это, я думаю, что у меня все еще есть код на блюдечке. - person hakre; 07.01.2013
comment
в настоящее время я использую вашу функцию generate_dropdown. - person user1286499; 07.01.2013
comment
Да, это было бы так. Отвлекся, нужно посмотреть, добавлю ли я его сюда и когда. Это в основном так, как я обрисовал в общих чертах. - person hakre; 08.01.2013
comment
Я понял :) Сначала я перестраиваю массив stackoverflow.com/a/10332361/1286499, затем stackoverflow.com/a/6812689/1286499 и круто! - person user1286499; 08.01.2013