Reputation: 466
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
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