C5-8.3: select form widget doesn't save selected value in DB
Permalink
I have an array of strings (font names), it's a $this-fonts public variable which works fine in the view and in the form. This array is populated with values in the controller's on_start():
So for example, setting the font in view() and edit()
shows the first array key in the view.php and form.php. No problem here.
I have a select input in the form which is populated with those array keys:
But I can't get the selected font saved in the DB. If I simply do this:
it only saves the selected font index. But if I do this:
or simply this:
it doesn't save anything, the DB field is empty.
I've also tried that in the validate($args):
it returns an empty value with the error:
If I cast that to string (string)array_keys($this->fonts)[1], it returns an empty value.
I'm out of clues. $this->fonts is set in the on_start(), available for view() and edit(), how come it's not working for save() or validate()?
How can I save the selected font text value, not the selected index?
foreach ($files as $filename => $path) { $this->fonts[pathinfo($path)['filename']] = $path; $this->set('fonts', array_keys($this->fonts));
So for example, setting the font in view() and edit()
$this->set('font', array_keys($this->fonts)[1]);
shows the first array key in the view.php and form.php. No problem here.
I have a select input in the form which is populated with those array keys:
echo $form->select('font', $fonts, $font_selected);
But I can't get the selected font saved in the DB. If I simply do this:
$args['font'] = $args['font'];
it only saves the selected font index. But if I do this:
$args['font'] = array_keys($this->fonts)[(int)$args['font']];
or simply this:
$args['font'] = array_keys($this->fonts)[1];
it doesn't save anything, the DB field is empty.
$args['font'] = "test" // this DOES save the 'test' string though
I've also tried that in the validate($args):
$e->add(array_keys($this->fonts)[1]);
it returns an empty value with the error:
If I cast that to string (string)array_keys($this->fonts)[1], it returns an empty value.
I'm out of clues. $this->fonts is set in the on_start(), available for view() and edit(), how come it's not working for save() or validate()?
How can I save the selected font text value, not the selected index?
As I said, everything works fine in view and form. For example:
controller view():
view.php:
result:
But array_keys($this->fonts) in save() is empty!
controller save():
view.php:
result:
controller view():
$this->set('fonts', array_keys($this->fonts));
view.php:
<?php var_dump($fonts); ?>
result:
array(3) { [0]=> string(14) "Andika-Regular" [1]=> string(15) "Lobster-Regular" [2]=> string(19) "MarckScript-Regular" }
But array_keys($this->fonts) in save() is empty!
controller save():
$args['font'] = array_keys($this->fonts)[(int)$args['font']];
view.php:
<?php var_dump($font); ?>
result:
string(0) ""
This saves the correct selected index:
So, something does get saved, however anything but the actual selected string
$args['font_selected'] = (int)$args['font'];
So, something does get saved, however anything but the actual selected string
Since you want to save the selected font as a string. I suggest changing the code. Instead of using array_keys just provide the array as it is. When the array is passed to $form->select() the keys will be the option value and the value in the array is what is displayed to the user.
In the save method $args['font'] now should contain a string ( the font name).
The selected font in the form can be the $font variable.
If you need to store the path instead of the font name. You can change the array.
array('Andika-Regular' => 'path')
In the save method $args['font'] now should contain a string ( the font name).
The selected font in the form can be the $font variable.
$form->select('font', $fonts, $font);
If you need to store the path instead of the font name. You can change the array.
$this->fonts[$path] = pathinfo($path)['filename'];
The array passed to the select is in the form 'filename => path' (please see the top of my 1st post), so I can't pass it to the select as that will fill it with paths, not filenames.
You only have to make sure the array keys contain the value that you would like to store in the database. Also, make sure that in the db.xml the correct type is set.
// keys are filled with the font name foreach ($files as $filename => $path) { $filename = pathinfo($path)['filename']; $this->fonts[$filename] = $filename; } $this->set('fonts', $this->fonts);
<field name="font" type="string" size="255" />
That's exactly what I verified in view and form. However exactly the same code which returns a string in view or form returns empty in the save.
in save():
in view():
db.xml:
in save():
$args['font'] = "test" // this saves the string $args['font'] = array_keys($this->fonts)[1]; //this saves nothing
in view():
$this->set('font', array_keys($this->fonts)[1]); //this shows the 2nd filename from the array
db.xml:
<field name="font" type="string" size="100"/>
on_start is not triggered when a block is saved. You might want to create a function which you call on start and in the save to fill the fonts array.
Isn't it? I thought it's triggered before everything loads. And I was also using a public class variable.
Yeah, you're right! I've taken building the array out of on_start() and now the selected value is saved.
Thanks a lot for pointing that out!
Yeah, you're right! I've taken building the array out of on_start() and now the selected value is saved.
Thanks a lot for pointing that out!
No problem. If you do it as I said in my earlier answer (store the value you want in the database in the array keys). You would not have to use the function since the value is directly available in $args.
Example
I would suggest starting debugging in save method and see what values are available in $args.