Ty Yt
Ty Yt

Reputation: 466

Check if option is selected Form cakephp 3

I have a form for selecting Types. Each type has a color associated. In my TypesController, I have a function related to a view :

$types = $this->Types->find('list')->select(['id','name','color'])->toArray();
$this->set(compact(['types']));

And in my view, I can list every types in a select :

echo $this->Form->select('type_id', $types,['empty'=>'Types','class' => 'form-control','id'=>'types']);

I would like to show the type's color when user selects a type. Only when an option is selected. Is it possible? I tried with JS but it didn't work. Color is hexadecimal.

Thanks for your help!

Upvotes: 2

Views: 964

Answers (1)

Holt
Holt

Reputation: 37626

First, you should not use find('list') since it returns key/value pairs, you want to use (e.g.):

$types = $this->Types->find()->select(['id','name','color'])->toArray();

Then in your view, you want to be able to store the color attributes, so e.g.:

// Convert your $types array to something we can send to `select`
$options = array_map(function ($e) {
    return [
        'value' => $e->id,
        'text'  => $e->name,
        'templateVars' => [
            'color' => $e->color
        ]
    ];
}, $types);
// Use a custom template for the `option` element to store the color as a data- attribute
$this->Form->templates([
    'option' => '<option value="{{value}}" data-color="{{color}}"{{attrs}}>{{text}}</option>'
]);
// Create the select element
echo $this->Form->select('type', $options, [
    'empty'=>'Types', 'class' => 'form-control', 'id' => 'types'
]);

See the cookbook if you don' t know what are additional template variables (templateVars ) - You need CakePHP 3.1+ to use templateVars.

You will get something like:

<select name="type" class="form-control form-control" id="types">
    <option value="" data-color="">Types</option>
    <option value="1" data-color="ff0000">Red</option>
    <option value="2" data-color="0000ff">Blue</option>
    <option value="3" data-color="00ff00">Green</option>
</select>

For the following, I am assuming you have an element with id="color-preview" in which you want to set the background color, e.g.:

<div id="color-preview"></div>

Here is what the javascript code would look like (with jQuery):

$('#types').on('change', function () {
    var opt = $(this).find(':selected');
    var col = '';
    if (opt.data('color')) {
        col = '#' + opt.data('color');
    }
    $('#color-preview').css({background: col});
});

Without jQuery (modern browser only):

var previewDiv = document.getElementById('color-preview');
document.getElementById('types').addEventListener('change', function () {
    var opt = this.options[this.selectedIndex];
    var col = '';
    if (opt.dataset.color) {
        col = '#' + opt.dataset.color;
    }
    previewDiv.style.background = col;
});

Upvotes: 2

Related Questions