Populate option tags with data- attributes using a multidimensional array

54 views Asked by At

I have a json file that looks something like this:

{
    "world": {
        "france": {
            "city": {
                "city_1": {
                    "name": "paris",
                    "titre": "lorem ipsum"
                },
                "city_2": {
                    "name": "marseille",
                    "titre": "dolor sit amet"
                }
            }
        },
        "usa": {
            "city": {
                "city_1": {
                    "name": "new york",
                    "titre": "lorem ipsum"
                },
                "city_2": {
                    "name": "los angeles",
                    "titre": "lorem ipsum"
                },
                "city_3": {
                    "name": "portland",
                    "titre": "lorem ipsum"
                }
            }
        }
    }
}

I would like to display a set of option tags with countries as text and some additional attribute declarations like this:

<option value="france" data-city="paris,marseille">france</option>
<option value="usa" data-city="new york,los angeles,portland">usa</option>

I tried something like this to display the countries, but I can't display the list of cities.

foreach ($data['world'] as $key => $value)
{
    $scenario .= '<option value="' . $key . ' data-city="">' . $key .'</option>';
}
3

There are 3 answers

0
cOle2 On BEST ANSWER

The cities are in a sub array so you need to do a second loop within your existing foreach to iterate over the cities.

You can create a new array to capture the individual city names in the sub-loop, and then implode() them in your <option>:

$cityArray = array();
foreach($values['city'] as $cityKey=>$cityValue) {
    $cityArray[] = $cityValue['name'];
}

$scenario .= '<option value="' . $key . ' data-city="'.implode(',',$cityArray).'">' . $key .'</option>';

Here's a working example: https://3v4l.org/l986m

0
AbraCadaver On

Extract the name elements from the city and implode them:

foreach ($data['world'] as $key => $value)
{
    $cities = implode(',', array_column($value['city'], 'name'));
    $scenario .= '<option value="' . $key . '" data-city="' . $cities . '">' . $key .'</option>';
}
0
mickmackusa On
  1. There is never any benefit to duplicating the option's text as its value attribute. All form submission payloads and javascript processes will all work seamlessly without the value attributes. These declarations can be safely removed from all option tags that you are populating.

  2. By using "array destructuring" syntax in your foreach(), you can swiftly and concisely access columns of city data with array_column() then implode() with commas.

Code: (Demo)

$data = json_decode($json, true);
$options = [];
foreach ($data['world'] as $country => ['city' => $cities]) {
    $options[] = sprintf(
        '<option data-city="%s">%s</option>',
        implode(',', array_column($cities, 'name')),
        $country
    );
}

echo implode("\n", $options);

Output:

<option data-city="paris,marseille">france</option>
<option data-city="new york,los angeles,portland">usa</option>

This question is essentially a convoluted way of asking Implode a column of values from a two dimensional array