9

I have a form, inside I have a select with some options and I'm using Laravel Collective Forms to build it, I have something like:

{!! Form::select('size', $data, $selecteds, ['multiple' => true]) !!}

All going well until here, but now I need to set a data-section attribute to each option, how can I make it?

Sredny M Casanova
  • 4,735
  • 21
  • 70
  • 115

3 Answers3

7

I had to do the same thing recently. After inspecting the FormBuilder class to write my own marco I found out that the select() method actually has an undocumented fifth parameter for option attributes:

Form::select('size', $data, $selecteds, ['multiple' => true], $optionAttributes)

The index must match the value of the option, e.g.:

$optionAttributes = [
    'S' => [
        'data-title' => 'Small',
        'data-surcharge' => '0',
    ],
    'M' => [
        'data-title' => 'Medium',
        'data-surcharge' => '5',
    ],
    'L' => [
        'data-title' => 'Large',
        'data-surcharge' => '10',
    ],
];

So I ended up writing a marco which generates this array based on a collection and then uses the default select() method. Something like that:

\Form::macro('locationSelect', function ($name, $value = null, $attributes = []) {
    // Get all locations from the DB
    $locations = \App\Location::all();

    // Make an id=>title Array for the <option>s
    $list = $locations->pluck('title', 'id')->toArray();

    // Generate all data-attributes per option
    $optionAttributes = [];
    foreach ($locations as $location) {
        $optionAttributes[$location->id] = [
            'data-icon' => $location->icon,
            'data-something' => $location->some_attribute,
        ];
    }

    // Use default select() method of the FormBuilder
    return $this->select($name, $list, $value, $attributes, $optionAttributes);
});

Very convenient.

{{ Form::locationSelect('location_id') }}

J-F
  • 71
  • 1
  • 2
4

You can pass option attributes as fifth parameter (version 5.8) like this

$optionParameters = collect($optionsArray)->mapWithKeys(function ($item) {
            return [$item[id] => ['data-anything' => $item['anything']]];
        })->all();

And select will look like

{!! Form::select('name', $optionsArray, null, ['class' => 'form-control', 'placeholder' => 'Select'], $optionParameters) !!}

I think it is much simpler and cleaner than creating macroses

3

Add it to a 4th argument which is an array:

{!! Form::select('size', $data, $selecteds, ['data-attribute' => 'John Smith', 'multiple' => true]) !!}
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279
  • but that, will add the data-attribute to the select? I have a different data-attribute value for each option, that's because I'm using it in javascript – Sredny M Casanova Jan 27 '17 at 13:51
  • 1
    It will add an attribute to the `select` element. If you want to add an attribute to each `option` you could create a [custom macro](https://laravelcollective.com/docs/5.3/html#custom-macros). Or you could add values like `value:data` and easily use it in JS. But in this case, you'll need to retrieve value manually after form submitting, Or just use plain HTML to generate `select` list. – Alexey Mezenin Jan 27 '17 at 13:58