4

How do I use Checkboxes in system.xml file with bydefault checked? I want to configure my custom module with four check-boxes (left,right,top,bottom). I am using this code, but it's display only unchecked checkboxes. When I am going to save settings it's save only last checkbox's value. Please see attached screen-shot. enter image description here

<positions translate="label">
    <label>Show Position</label>
    <frontend_type>Checkboxes</frontend_type>
    <source_model>customodule/model</source_model>
    <sort_order>14</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>
</positions>

I have created model function for this:

public function toOptionArray()
{
    return array('position' => 
        array('value' => 'left', 'label'=>Mage::helper('adminhtml')->__('Left')),
        array('value' => 'right', 'label'=>Mage::helper('adminhtml')->__('Right')),
        array('value' => 'top', 'label'=>Mage::helper('adminhtml')->__('Top')),
        array('value' => 'bottom', 'label'=>Mage::helper('adminhtml')->__('Bottom')),
    );
}

please suggest me what's code need to set and use these check-boxes?

Thanks in advance.

  • Suggest reading through the Magento Wiki on system.xml setup. magentocommerce.com/wiki/5_-_modules_and_development/admin/… – pspahn Aug 21 '13 at 23:58
  • I read this Wiki but not much information about Checkboxes. default check not working and when I save with check all Checkboxes, only last one's value saved in database. PS:sorry for my bed english – Lalit Kaushik Aug 22 '13 at 5:05
  • 2
    I'm not finding any good examples of how this is done in core, and I know I've looked at this previously. Maybe the best option is to use a multi-select instead. – pspahn Aug 22 '13 at 8:01
  • It looks like when the html is created all the checkboxes have the same name so the last checked item will always be the one returned. – David Manners Sep 27 '13 at 13:57
3

There is no way of achieving what you need just through declaring the field in system.xml.
I really think the easiest way is to use a multiselect. It saves you the trouble.
But if you insist here is how you can do it. You will need a custom renderer for your config setting.
Declare your element like this:

<positions translate="label">
    <label>Show Position</label>
    <frontend_model>[module]/adminhtml_system_config_positions</frontend_model>
    <sort_order>14</sort_order>
    <show_in_default>1</show_in_default>
    <show_in_website>1</show_in_website>
    <show_in_store>1</show_in_store>
</positions>

Now create the renderer: file app/code/[codepool]/[Namespace]/[Module]/Block/Adminhtml/System/Config/Positions.php

<?php
class [Namespace]_[Module]_Block_Adminhtml_System_Config_Positions extends Mage_Adminhtml_Block_System_Config_Form_Field{
    const CONFIG_PATH = 'path/to/positions'; //put here the full path from the config to your element
    protected $_values = null;
    protected function _construct()
    {
        $this->setTemplate('[namespace]_[module]/system/config/positions.phtml');
        return parent::_construct();
    }
    protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
    {
        $this->setNamePrefix($element->getName())
            ->setHtmlId($element->getHtmlId());
        return $this->_toHtml();
    }
    public function getValues(){
        $values = array();
        //get the available values (use the source model from your question)
        foreach (Mage::getSingleton('customodule/model')->toOptionArray() as $value){
            $values[$value['value']] = $value['label'];
        }
        return $values;
    }
    public function getIsChecked($name){
        return in_array($name, $this->getCheckedValues());
    }
    public function getCheckedValues(){
        if (is_null($this->_values)){
            $data = $this->getConfigData();
            if (isset($data[self::CONFIG_PATH])){
                $data = $data[self::CONFIG_PATH];
            }
            else{
                $data = '';
            }
            $this->_values = explode(',', $data);
        }
        return $this->_values;
    }
}

now the template to render your checkboxes. File app/design/adminhtml/default/default/[namespace]_[module]/system/config/positions.phtml

<input type="hidden" name="<?php echo $this->getNamePrefix() ?>" value="" /><!-- this is send if nothing is checked -->
<ul class="checkboxes">
    <?php foreach ($this->getValues() as $name => $label): ?>
        <li>
            <input type="checkbox" value="<?php echo $name?>" name="<?php echo $this->getNamePrefix() ?>[]" id="<?php echo $this->getHtmlId() . '_' . $name ?>"<?php echo ($this->getIsChecked($name) ? ' checked="checked"' : '') ?>/><label for="<?php echo $this->getHtmlId() . '_' . $name ?>">
                <?php echo $label ?>
            </label>
        </li>
    <?php endforeach;?>
</ul>

replace the placeholders [Module], [Namespace] and [codepool] with your module values and give it a go.

This is how you can create any type of config element.

  • Great answer but multi-selects are a bad suggestion. They usually have the worst UX of any form control. A testament to this is Android's rendering of multi-selects as a list of checkboxes. – Walf Jul 18 '14 at 4:50
  • @Walf. I didn't suggest multi-selects. I said that it's easier to code it, because Magento had already a renderer for multi selects. – Marius Jul 18 '14 at 5:53
  • "I really think the easiest way is to use a multiselect. It saves you the trouble. But if you insist…" Looks like a suggestion to me. – Walf Jul 21 '14 at 5:57
  • @Walf I offered 2 options, and expressed my opinion. One option is easier to implement, one looks nicer. – Marius Jul 21 '14 at 6:01
  • I like your solution, I just think steering people away from multi-selects is a good idea. – Walf Jul 21 '14 at 6:03

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.