I want to make a select tree for my category. Here is for unordered list.
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";
}
Here is the HTML output for unordered list.
<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>
Question : How to make the current function for select option
and the results will be something like this.
<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>
I would go with the text-list you have already, it's a breeze to turn it into the <select>
element:
$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";
Output:
<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>
Otherwise if you were unable to generate this text-list but only the ul/li
list, then work on that HTML but in the same fashion.
After you've updated and provided the HTML, here is it working of the ul/li
list string ($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";
How this works is outlined more in this earlier answer of mine: How can I extract structured text from an HTML list in PHP?. That one is with DomDocument
not SimpleXMLElement
like here, however, the more or less main part is the xpath here which both provide.
This is all fine and dandy. However you somewhat must have missed to actually provide the sample array - I just now assumed:
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',
),
)
to point you to some method that is aligned with what you already do for the ul/li
list, a recursive function that works with your array:
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);
Output:
<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>