Magento 2 toggle switch (yes/no) in admin config of custom module using system.xml or in any programmatic way

magento.stackexchange https://magento.stackexchange.com/questions/256587

Question

I understand that we can create a toggle switch using form with ui_component. However, I want to create an admin configuration for my custom module using system.xml configuration.

Is there any way to apply the toogle switch (yes/no) (which is a ui_component of magento, to system.xml configuration? I want it to be implemented instead of a select type with dropdown option.

reference: Magento 2 form field toggled type

enter image description here

Was it helpful?

Solution

After several research, I come up with this solution. (Not a clean code but still able to come up with the expected results)

I ended up creating a block to be inserted in the admin system config using the <frontend_model/> markers reference here

First, I added a Field inside system.xml config file. It goes like this:

<field id="status" type="checkbox" translate="label" sortOrder="104" showInDefault="1" showInWebsite="0" showInStore="0">
    <frontend_model>Vendor\Module\Block\Adminhtml\System\Config\Advanced</frontend_model>
    <attribute type="shared">1</attribute>
</field>  

Block file which is the class Advanced code

<?php

namespace Vendor\Module\Block\Adminhtml\System\Config;

class Advanced extends \Magento\Config\Block\System\Config\Form\Field
{
/**
 * Template path
 *
 * @var string
 */
protected $_template = 'system/config/advance/check.phtml';

/**
 * Render fieldset html
 *
 * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
 * @return string
 */
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
    //$columns = $this->getRequest()->getParam('website') || $this->getRequest()->getParam('store') ? 5 : 4;
    return $this->_decorateRowHtml($element, "<td class='label'>Label Text</td><td>" . $this->toHtml() . '</td><td></td>');
}
}

check.phtml code the phtml file

<style>
.switch {
    position: relative;
    display: inline-block;
    width: 37px;
    height: 22px;
    vertical-align: middle;

}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;
    vertical-align: middle;

}
.sliderOne {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ccc;
    -webkit-transition: .4s;
    transition: .4s;
    vertical-align: middle;

}

.slider:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: -7.75px;
    bottom: 0px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
    vertical-align: middle;

}
.sliderOne:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: .5px;
    bottom: 0px;
    background-color: white;
    -webkit-transition: .4s;
    transition: .4s;
    vertical-align: middle;

}

input:checked + .slider {
    background-color: #79a22e;
}

input:focus + .slider {
    box-shadow: 0 0 0px #2196F3;

}

input:checked + .sliderOne {
    background-color: #79a22e;
}

input:focus + .sliderOne {
    box-shadow: 0 0 0px #2196F3;

}

input:checked + .slider:before {
    -webkit-transform: translateX(22px);
    -ms-transform: translateX(22px);
    transform: translateX(22px);

}
input:checked + .sliderOne:before {
    -webkit-transform: translateX(22px);
    -ms-transform: translateX(22px);
    transform: translateX(22px);

}

/* Rounded sliders */
.slider.round {
    border-radius: 35px;

}

.slider.round:before {
    border-radius: 100%;
    display: inline-block;

}

.sliderOne.round {
    border-radius: 35px;

}

.sliderOne.round:before {
    border-radius: 100%;
    display: inline-block;

}

</style>
<script>
function myFunction() {

    if(document.getElementById('spa').classList.contains("slider")) {
        document.getElementsByClassName("slider")[0].setAttribute("class","sliderOne round");
        document.getElementById('toggle').innerHTML = "  &nbsp; No";
    }else{
        document.getElementsByClassName("sliderOne")[0].setAttribute("class","slider round");
        document.getElementById('toggle').innerHTML = "  &nbsp; Yes";
    }
}
</script>
<label class="switch">
    <input type="checkbox" onclick="myFunction()" checked>
    <span class="slider round" id="spa"></span>
</label>
<span id="toggle"></span>

Main reference for the whole idea

The output

Yes No

OTHER TIPS

You have to use this code in your system.xml

...
<field id="enable_product" translate="label" type="select" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
    <label>Enable Product</label>
    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
...

For a full example take a look at system.xml of a mine extension here.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top