1

Starting from array of string like :

"mobili;tavolini_lato_divano",
"mobili;tavoli_da_pranzo",
"illuminazione;plafoniere",
"illuminazione;lampade_decorative",
"sculture;sculture_in_resina",
"sculture;sculture_in_resina;serie_limitata_tatoo",
"sculture;sculture_in_resina;sculture_resina_grandi",

Need to create a select that have nested optgroup and option , based on split by " ; " ,where if 2 elements , first ( parent ) become optgroup and second ( son ) an option.

If 3 elements ( with same 1st element ) , 2nd element will become an optiongroup (inside first optgroup - Nested - ) with inside an option ( 3d element ).

And so on if 4 elements, and more elements.

Actually I made this example but this work only if there are 2 count.

Full example with input and output in :

https://wtools.io/php-sandbox/b63q

Select Execute and HTML as output to see result.
Thanks

0

1 Answer 1

2

First create an ordered (and nested) array of your element array (line 76-89 in my code), and then you must use the recursive function (line 91-104 in my code) to create a string of options and optgroup.

Finally, print the output of the recursive function (line 107 in my code).

<?php

/*
Row 1 : mobiletti_puzzle_3d;mobili
Output : "optgroup" -> mobiletti_puzzle_3d
            "option" -> mobili

Row 2 : sculture;sculture_in_resina
Output : "optgroup" -> sculture
            "option" -> sculture_in_resina

Row 3 : sculture;sculture_in_resina;sculture_resina_grandi
Output : "optgroup" -> sculture
            "optgroup" -> sculture_in_resina
                "option" -> sculture_resina_grandi

If they have the same parent must be added as Option of Row 2 

Row 4 : sculture;sculture_in_metallo
Output : "optgroup" -> sculture
            "option" -> sculture_in_metallo


Final Output ALL EXAMPLE :
"optgroup" -> mobiletti_puzzle_3d
    "option" -> mobili
"optgroup" -> sculture
    "option" -> sculture_in_resina
    "option" -> sculture_in_metallo
    "optgroup" -> sculture_in_resina
        "option" -> sculture_resina_grandi

Split by " ; " the count-1 , always will be an optgroup and this will generate a Nested Optgroup 

*/
$Categories = [
    "mobiletti_puzzle_3d;mobili",
    "mobili;sedie_da_pranzo",
    "mobili;sgabelli",
    "mobili;tavolini_da_salotto",
    "mobili;tavolini_lato_divano",
    "mobili;tavoli_da_pranzo",
    "sculture;sculture_decorate_in_vetro",
    "sculture;sculture_in_bronzo",
    "sculture;sculture_in_metallo",
    "sculture;sculture_in_resina;sculture_resina_grandi",
    "sculture;sculture_in_resina;sculture_resina_medie",
    "sculture;sculture_in_resina;sculture_resina_piccole",
    "sculture;sculture_in_resina;serie_limitata_tatoo",
    "illuminazione;plafoniere",
    "illuminazione;lampade_decorative",
    "illuminazione;lampade_da_terra",
    "illuminazione;lampade_da_tavolo",
    "illuminazione;lampade_da_comodino",
    "illuminazione;lampadari",
    "divani_e_poltrone;mobili",
    "decorazione_murale;stampe_su_telaio_estetico",
    "decorazione_murale;specchi_design_moderno",
    "decorazione_murale;quadri_scultura_in_metallo",
    "decorazione_murale;puzzle_3d_in_legno",
    "decorazione_murale;orologi_parete",
    "decorazione_murale;dipinti_su_telaio_estetico",
    "decorazione_murale;dipinti_su_plexiglas",
    "consolle;mobili",
    "colonne;mobili",
    "collage_3d;decorazione_murale",
    "appliques;illuminazione",
    "altri_oggetti;vasi",
    "altri_oggetti;posacenere",
    "altri_oggetti;portagioie",
    "altri_oggetti;portacandele",
    "altri_oggetti;oggetti_decorativi",
    "altri_oggetti;centrotavola"
];

$select = [];
foreach ($Categories as $row) {
    $pointer = &$select;
    $row = explode(';', $row);
    $ogCount = count($row) - 1;
    for ($i = 0; $i < $ogCount; $i++) {
        $row[$i] = $row[$i];
        if (empty($pointer[$row[$i]]))
            $pointer[$row[$i]] = [];
        $pointer = &$pointer[$row[$i]];
        if (($i + 1) >= $ogCount)
            $pointer[] = $row[$i + 1];
    }
}

function recursiveSelect($_options, $_space = '')
{
    if (!is_array($_options))
        return  '<option value="' . $_options . '">' . $_options . '</option>' . "\n";
    else {
        $tmp = '';
        foreach ($_options as $key => $option)
            if (!is_array($option)) {
                $tmp .= recursiveSelect($option);
            } else
                $tmp .= '<optgroup label="' . $_space . $key . '">' . recursiveSelect($option, $_space . str_repeat('&nbsp;', 4)) . '</optgroup>' . "\n";
        return $tmp;
    }
}
?>
<select>
    <?php echo (recursiveSelect($select)); ?>
</select>

This code can handle all depths of nested elements in your array.

To better display the select optgroups, I added the space ($_space) parameter to the recursive function (with 4 spaces in line 101).

Sign up to request clarification or add additional context in comments.

2 Comments

Really awesome ! last question ... how about set selected if i have a default value like "sculture;sculture_in_resina;sculture_resina_grandi" ?
Two ways: 1- Set the ID for all options by name and set default selected option by js when page loaded. 2- In the return option line of recursive function, Check if value ($_options) is default option, add an attribute named "selected".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.