As far as I know, by default Magento, we cannot save the value of checkbox with a simple declaration of checkbox type in xml config. So, we need to create our own custom renderer for this config.
Create admin config: app/code/Vendor/YourModule/etc/adminhtml/system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="sample_tab" translate="label" sortOrder="1000">
<label>Example tab config</label>
</tab>
<section id="sample_section" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Example config section</label>
<tab>sample_tab</tab>
<resource>Vendor_YourModule::config</resource>
<group id="general" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General</label>
<field id="do_something" translate="label" type="checkbox" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Do something?</label>
<frontend_model>Vendor\YourModule\Block\Adminhtml\System\Config\Checkbox</frontend_model>
<comment>Do we want to do something?</comment>
</field>
</group>
</section>
</system>
</config>
Basically, our config declare a frontend model for rendering custom field.
Create frontend model block:
app/code/Vendor/YourModule/Block/Adminhtml/System/Config/Checkbox.php
<?php
namespace Vendor\YourModule\Block\Adminhtml\System\Config;
use Magento\Framework\Data\Form\Element\AbstractElement;;
class Checkbox extends \Magento\Config\Block\System\Config\Form\Field
{
const CONFIG_PATH = 'sample_section/general/do_something';
protected $_template = 'Vendor_YourModule::system/config/checkbox.phtml';
protected $_values = null;
/**
* Checkbox constructor.
* @param \Magento\Backend\Block\Template\Context $context
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
/**
* Retrieve element HTML markup.
*
* @param AbstractElement $element
*
* @return string
*/
protected function _getElementHtml(AbstractElement $element)
{
$this->setNamePrefix($element->getName())
->setHtmlId($element->getHtmlId());
return $this->_toHtml();
}
public function getValues()
{
$values = [];
$optionArray = \Vendor\YourModule\Model\Config\Source\Checkbox::toOptionArray();
foreach ($optionArray as $value) {
$values[$value['value']] = $value['label'];
}
return $values;
}
/**
* Get checked value.
* @param $name
* @return boolean
*/
public function getIsChecked($name)
{
return in_array($name, $this->getCheckedValues());
}
/**
*
* Retrieve the checked values from config
*/
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;
}
}
Config source value:
app/code/Vendor/YourModule/Model/Config/Source/Checkbox.php
<?php
namespace Vendor\YourModule\Model\Config\Source;
class Checkbox
{
public static function toOptionArray()
{
return [['value' => 'checkbox', 'label'=>__('Do something?')]];
}
}
app/code/Vendor/YourModule/view/adminhtml/templates/system/config/checkbox.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>
Alternative solutions
--In your case, We can use type="select"
, and then try to add the Default Yesno Source.
<field id="do_something" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Do something?</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Do we want to do something?</comment>
</field>
--Also use type="multiselect"
if there are many values.
<field id="do_something" translate="label" type="multiselect" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Do something?</label>
<source_model>Vendor\YourModule\Model\Config\Source\Checkbox</source_model>
</field>
Best Answer
Take a look: vendor/magento/module-customer/Block/Adminhtml/Edit/Tab/Newsletter.php:
We can follow the same logic.