13

I would like to create an attribute read only however it look it is not possible.

I have tried to pass to addAttribute() 'disabled' =>true or 'readonly' => true with out any success. I have found out some suggestion about using setLockedAttributes() but for some reason it is not working

Reference:
Varien_Data_Form_Element_Abstract::serialize($attributes = array(), $valueSeparator='=', $fieldSeparator=' ', $quote='"')

  • 2
    The question was answered on stackoverflow: stackoverflow.com/questions/6384120/… – Fabian Blechschmidt Feb 15 '13 at 19:27
  • This solution is not working. (setLockedAttributes) – Fra Feb 15 '13 at 20:54
  • 2
    it is not setLockedAttribute, it is lockAttribute :-) – user487772 Feb 15 '13 at 23:32
  • 1
    Tim! You smiled! :-D – benmarks Feb 16 '13 at 1:07
  • thanks guys ... I will check it out an update the thread – Fra Feb 17 '13 at 10:33
11

From the referenced SO article - I tried and this indeed works on 1.6CE and 1.7CE / 1.12EE. I haven't tried on 1.8/1.13 as of yet.

https://stackoverflow.com/questions/6384120/magento-read-only-and-hidden-product-attributes

OK, it looks like it can be done after all. After adding an observer for the catalog_product_load_after event, the lockAttribute method of the Mage_Catalog_Model_Abstract class may be used to make a product attribute read-only. Here is the code for the observer method:

public function lockAttributes($observer) {
    $event = $observer->getEvent();
    $product = $event->getProduct();
    $product->lockAttribute('attribute_code');
}
8

If it is enough for you to make it not editable in product management, use the frontend input type label, which replaces the form input with plain text:

addAttribute($entity, $code, array(
    ...
    'input' => 'label',
    ...
));

Note that this will not prevent saving the attribute through API or manipulated POST request. To make it secure, additionally use lockAttribute() as suggested above.

Also it only looks good for text type attributes, for other types, again, fall back to lockAttributes or extend the "label" type.

  • this works only if the attribute is text type, for boolean you need lockattribute() – Fra May 10 '17 at 11:51
  • 1
    Good point, @Fra, thanks! I'll add it to the answer – Fabian Schmengler May 10 '17 at 12:24
  • Doesn't seem to work in 1.9.4.1 even for text attributes – OZZIE Jul 12 at 7:21
3

To make this fixed, you can alternatively use an input renderer for this. The downside is, you would have to do this for each input type and set this via setup for each attribute.

To do so, use the input_renderer key when using addAttribute an attribute or frontend_input_renderer when using updateAttribute. Example:

$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY, 'yourattribute', array(
// ...
// won't be used actually as you use a custom renderer (constant equals to text), but I'm not sure what omitting this will have as effect..
    'input' => Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT,
    'input_renderer' => 'yourns_yourmodule/adminhtml_product_helper_form_disabledText',
    'frontend_class' => 'disabled',
    'note' => 'This field is disabled',
// ...
));

Then with your class Yourns_Yourmodule_Block_Adminhtml_Product_Helper_Form_DisabledText extend the input class you would actually use. For a text field it would be Varien_Data_Form_Element_Text. For selects it would be Varien_Data_Form_Element_Select and so on.

Now add your code like this to disable the attribute, overwriting the getHtml method, setting the attribute and returning the actual HTML code for the input field:

public function getHtml()
{
    // Set disabled
    $this->setReadonly(true, true);
    return parent::getHtml();
}

The method can be found in lib/Varien/Data/Form/Abstract.php which will be inherited by all form input element fields, so it should alaways be available.

/**
 * Disable elements
 *
 * @param boolean $readonly
 * @param boolean $useDisabled
 * @return Varien_Data_Form_Abstract
 */
public function setReadonly($readonly, $useDisabled = false)
{
    if ($useDisabled) {
        $this->setDisabled($readonly);
        $this->setData('readonly_disabled', $readonly);
    } else {
        $this->setData('readonly', $readonly);
    }
    foreach ($this->getElements() as $element) {
        $element->setReadonly($readonly, $useDisabled);
    }

    return $this;
}

It's probably senseful to include the disabled class in the attribute setup like shown above to visualize the denied input possibility. You can probably also use $this->addClass('disabled') in the method, I did not try this yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.