This is a known (annoying) behaviour of the Magento Adminhtml forms.
The problem is that if no value is selected for the multiselect, no value for that attribute is posted when the form is submitted.
On the server side Magento then loads the model, sets all the posted attribute values on the model and saves it.
Because no value was posted the original value that was loaded on the model wasn't updated.
As a solution for attributes with a custom source model I tend to provide an empty option with a special option value (e.g. -1
). That value must not be 0
or an empty string.
Then I specify a backend model for that attribute that checks for that special value in the _beforeSave()
method. If it is found the backend model unsets the attribute on the model instance.
Here is an example:
Source Model:
class Your_Module_Model_Entity_Attribute_Source_Example
extends Mage_Eav_Model_Entity_Attribute_Source_Abstract
{
const EMPTY = '-1';
public function getAllOptions()
$options = array(
array('value' => 1, 'label' => 'One'),
array('value' => 2, 'label' => 'Two'),
array('value' => 3, 'label' => 'Three')
);
if ($this->getAttribute()->getFrontendInput() === 'multiselect')
{
array_unshift($options, array('value' => self::EMPTY, 'label' => ''));
}
return $options;
}
}
Backend Model:
class Your_Module_Model_Entity_Attribute_Backend_Example
extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
public function beforeSave($object)
{
$code = $this->getAttribute()->getAttributeCode();
$value = $object->getData($code);
if ($value == Your_Module_Model_Entity_Attribute_Source_Example::EMPTY)
{
$object->unsetData($code);
}
return parent::beforeSave($object);
}
}
If you find a better workaround please let me know.