2

In my joomla custom component I used the SQL field type (item.xml):

    <field name="colors" type="sql" query="SELECT id ,name FROM #__products_colors" multiple="multiple" key_field="id" value_field="name" class="inputbox"
         label="colors" description="COM_PRODUCTS_FORM_DESC_ITEM_COLORS" /> 

In my view I call the field like this:

<?php echo $this->form->getInput('colors'); ?>

Which gives me a nice and smooth selectbox like this:

<select id="jform_colors" class="inputbox" multiple="multiple" name="jform[colors][]" aria-invalid="false">
<option value="1">blue</option>
<option value="2">yellow</option>
<option value="3">red</option>
<option value="4">green</option>
<option value="5">purple</option>

When I save this colors field, after selecting blue and red for example it gets saved as 1,3 in my database. Joomla does all the work for me... (THANKS Joomla)

Now maybe I am getting greedy, but somehow I expect Joomla to preselect these values for me when I edit an entry after saving. It does this with every other type of field, so why not here? Is there anything Im forgetting?

Thanks in adv!

edit: the bind function in the answer, I tweaked it a bit.

    public function bind($array, $ignore = '') {
    if (isset($array['params']) && is_array($array['params'])) {
        $registry = new JRegistry();
        $registry->loadArray($array['params']);
        $array['params'] = (string) $registry;
    }
    //print_r($array);
    if (key_exists('colors', $array) && is_array($array['colors'])) {
        echo "pwn";
        $array['colors'] = implode(',', $array['colors']);
    }

    if (isset($array['metadata']) && is_array($array['metadata'])) {
        $registry = new JRegistry();
        $registry->loadArray($array['metadata']);
        $array['metadata'] = (string) $registry;
    }
    return parent::bind($array, $ignore);
}

And DONT use filter="safehtml" :)

Good luck all!

Hans Wassink
  • 2,529
  • 3
  • 30
  • 45

2 Answers2

5

If you are following Joomla's standards, you should have a method called "loadFormData" in your model. There you can be sure that the field is converted to array when fetched from the database, example:

<?php
protected function loadFormData()
{
    // Check the session for previously entered form data.
    $data = JFactory::getApplication()->getUserState('com_yourcomponent.edit.item.data', array());

    if (empty($data)) {
        $data = $this->getItem();
    }

    // THIS IS WHAT YOU MUST BE MISSING
    if (is_array($data) && !is_array($data['colors'])){
        $data['colors'] = explode(',',$data['colors']);
    } elseif (is_object($data) && !is_array($data->colors)) {
        $data->colors = explode(',',$data->colors);
    }

    return $data;
}
?>

You will also need to override your bind method in your table class:

<?php
public function bind($src, $ignore = array())
{
    if (parent::bind($src, $ignore) && is_array($this->colors)){
        $this->colors = implode(',', $this->colors);
    }
}
guilleva
  • 1,301
  • 11
  • 13
  • Guilleva!! My hero.. I actually fiddled around with this, but that was before i used the SQL datafield. Just one edit: getItem() gets an object: not an array! so replace `$data['colors']` with `$data->colors` . Bounty is your way! – Hans Wassink Jan 11 '12 at 09:49
  • Thanks Hans, I think that $data is an object when retrieved from the database, for example when the item is opened for editing, but it's and array when the user submitted the form and there is an error with the data and the form is displayed again with the data that was submitted. So I have updated the answer to handle both cases. – guilleva Jan 11 '12 at 14:29
  • btw: a while ago my magic multiple sql field automatically saved data as 1,3,4 when I ticked those options... But now it doesnt anymore. I removed filter="safehtml" from the sql field xml and it stopped working. When I put that element back it started storing something again, but it stored 'Array'. I dont think I changed much else, so now Im thinking it maybe never saved 1,3,4 but maybe I typed it in the db myself. My question to you @guilleva is it supposed to save 1,3,4 automatically or is there a savemydata() function somewhere where I need to explode my array first? – Hans Wassink Jan 12 '12 at 07:37
  • I have updated the answer with the instructions on how you can save it as string. – guilleva Jan 12 '12 at 15:44
  • Guilleva! Thanks man... I shouldve figured these things out myself ofc, but the fact that so much is done for me by the framework made me lazy :D – Hans Wassink Jan 12 '12 at 15:59
  • Btw Guilleva, what is up with only saving my ass... Go and tackle more problems here! :) – Hans Wassink Jan 13 '12 at 09:07
  • You sir, deserve a medal! Couldn't figure out why the data wasn't being stored for a good hour until I read your post about overwriting the bind method. – Adam B Oct 09 '13 at 06:56
0

My data were stored little different like {"0":"3841","1":"3889"} so the right code for the convertion is

$data->postcode = (array)json_decode($data->postcode);

Thank you for you solution, very helpfull.

  • Well that is just because your data was stored as JSON in your particular component. Thats not really relevant in this case, but thanks for the addition :) – Hans Wassink Jan 18 '12 at 08:30