The question:
I have a toggle checkbox at product edit form:
Created as:
<field name="open_amount" formElement="checkbox">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">homeslider</item>
<item name="default" xsi:type="number">1</item>
</item>
</argument>
<settings>
<dataType>boolean</dataType>
<label translate="true">Open Amount</label>
<dataScope>status</dataScope>
</settings>
<formElements>
<checkbox>
<settings>
<valueMap>
<map name="false" xsi:type="number">0</map>
<map name="true" xsi:type="number">1</map>
</valueMap>
<prefer>toggle</prefer>
</settings>
</checkbox>
</formElements>
</field>
<field name="min_val">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Open Amount Min Value</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">faq</item>
</item>
</argument>
</field>
<field name="max_val">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Open Amount Max Value</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">faq</item>
</item>
</argument>
</field>
Can somebody show me how to add js component to show/hide both fields upon toggle on/off. Thanks
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
Replace your form code with below
<field name="open_amount" formElement="checkbox">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">[Vendor]_[Module]/js/mycheckbox</item>
<item name="source" xsi:type="string">homeslider</item>
<item name="default" xsi:type="number">1</item>
</item>
</argument>
<settings>
<dataType>boolean</dataType>
<label translate="true">Open Amount</label>
<dataScope>status</dataScope>
</settings>
<formElements>
<checkbox>
<settings>
<valueMap>
<map name="false" xsi:type="number">0</map>
<map name="true" xsi:type="number">1</map>
</valueMap>
<prefer>toggle</prefer>
</settings>
</checkbox>
</formElements>
</field>
<field name="min_val">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Open Amount Min Value</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">faq</item>
</item>
</argument>
</field>
<field name="max_val">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Open Amount Max Value</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">faq</item>
</item>
</argument>
</field>
Make mycheckbox.js file in vendor/module/view/adminhtml/web/js
define([
'underscore',
'uiRegistry',
'Magento_Ui/js/form/element/single-checkbox',
'Magento_Ui/js/modal/modal',
'ko'
], function (_, uiRegistry, select, modal, ko) {
'use strict';
return select.extend({
initialize: function () {
this._super();
this.fieldDepend(this.value());
return this;
},
onUpdate: function (value)
{
console.log(value);
var field_min_val = uiRegistry.get('index = min_val'); // get field
var field_max_val = uiRegistry.get('index = max_val'); // get fieldset
if (value == 0) {
field_min_val.hide();
field_max_val.hide();
}
else {
field_min_val.show();
field_max_val.show();
}
return this._super();
},
fieldDepend: function (value)
{
setTimeout( function(){
var field_min_val = uiRegistry.get('index = min_val');
var field_max_val = uiRegistry.get('index = max_val');
if (value == 0) {
field_min_val.hide();
field_max_val.hide();
}
else {
field_min_val.show();
field_max_val.show();
}
});
}
});
});
Hope it will be helpful.
Method 2
No meed all that js
files! this has worked for me as treat give a try using settings
:
<field name="open_amount">
<argument name="data" xsi:type="array">
....<!-- More Configuration-->
</argument>
<settings>
<switcherConfig>
<rules>
<rule name="0">
<value>0</value>
<actions>
<action name="0">
<target>vendor_module_form_edit.vendor_module_form_edit.your_field_set_name.min_val</target>
<callback>show</callback>
</action>
</actions>
</rule>
<rule name="1">
<value>1</value>
<actions>
<action name="0">
<target>vendor_module_form_edit.vendor_module_form_edit.your_field_set_name.min_val</target>
<callback>hide</callback>
</action>
</actions>
</rule>
</rules>
<enabled>true</enabled>
</switcherConfig>
<validation>
<rule name="required-entry" xsi:type="boolean">true</rule>
</validation>
</settings>
</field>
Method 3
For the toggle field, single-checkbox.js
file is responsible for this. so you need to extend the single-checkbox.js
file in your custom module.
First, create a require-config.js
file in below path.
app/code/Namespace/Modulename/view/adminhtml/requirejs-config.js
var config = {
'paths': {
'fabric': 'Magedelight_Productlabel/js/fabric'
},
map: {
'*': {
'Magento_Ui/js/form/element/single-checkbox':'Namespace_Modulename/js/form/element/single-checkbox'
}
},
'shim': {
'fabric': {
exports: 'fabric',
'deps': ['jquery']
}
}
};
Now create a single-checkbox.js
file in below path. and add below code.
app/code/Namespace/Modulename/view/adminhtml/web/js/form/element/single-checkbox.js
define([
'Magento_Ui/js/form/element/abstract',
'underscore',
'mage/translate'
], function (AbstractField, _, $t) {
'use strict';
return AbstractField.extend({
defaults: {
template: 'ui/form/components/single/field',
checked: false,
initialChecked: false,
multiple: false,
prefer: 'checkbox', // 'radio' | 'checkbox' | 'toggle'
valueMap: {},
templates: {
radio: 'ui/form/components/single/radio',
checkbox: 'ui/form/components/single/checkbox',
toggle: 'ui/form/components/single/switcher'
},
listens: {
'checked': 'onCheckedChanged',
'value': 'onExtendedValueChanged'
}
},
/**
* @inheritdoc
*/
initConfig: function (config) {
this._super();
if (!config.elementTmpl) {
if (!this.prefer && !this.multiple) {
this.elementTmpl = this.templates.radio;
} else if (this.prefer === 'radio') {
this.elementTmpl = this.templates.radio;
} else if (this.prefer === 'checkbox') {
this.elementTmpl = this.templates.checkbox;
} else if (this.prefer === 'toggle') {
this.elementTmpl = this.templates.toggle;
} else {
this.elementTmpl = this.templates.checkbox;
}
}
if (this.prefer === 'toggle' && _.isEmpty(this.toggleLabels)) {
this.toggleLabels = {
'on': $t('Yes'),
'off': $t('No')
};
}
if (typeof this.default === 'undefined' || this.default === null) {
this.default = '';
}
if (typeof this.value === 'undefined' || this.value === null) {
this.value = _.isEmpty(this.valueMap) || this.default !== '' ? this.default : this.valueMap.false;
this.initialValue = this.value;
} else {
this.initialValue = this.value;
}
if (this.multiple && !_.isArray(this.value)) {
this.value = []; // needed for correct observable assignment
}
this.initialChecked = this.checked;
return this;
},
/**
* @inheritdoc
*/
initObservable: function () {
return this
._super()
.observe('checked');
},
/**
* Get true/false key from valueMap by value.
*
* @param {*} value
* @returns {Boolean|undefined}
*/
getReverseValueMap: function getReverseValueMap(value) {
var bool = false;
_.some(this.valueMap, function (iValue, iBool) {
if (iValue === value) {
bool = iBool === 'true';
return true;
}
});
return bool;
},
/**
* @inheritdoc
*/
setInitialValue: function () {
if (_.isEmpty(this.valueMap)) {
this.on('value', this.onUpdate.bind(this));
} else {
this._super();
this.checked(this.getReverseValueMap(this.value()));
}
return this;
},
/**
* Handle dataScope changes for checkbox / radio button.
*
* @param {*} newExportedValue
*/
onExtendedValueChanged: function (newExportedValue) {
var isMappedUsed = !_.isEmpty(this.valueMap),
oldChecked = this.checked.peek(),
oldValue = this.initialValue,
newChecked;
if (this.multiple) {
newChecked = newExportedValue.indexOf(oldValue) !== -1;
} else if (isMappedUsed) {
newChecked = this.getReverseValueMap(newExportedValue);
} else if (typeof newExportedValue === 'boolean') {
newChecked = newExportedValue;
} else {
newChecked = newExportedValue === oldValue;
}
if (newChecked !== oldChecked) {
this.checked(newChecked);
}
},
/**
* Handle checked state changes for checkbox / radio button.
*
* @param {Boolean} newChecked
*/
onCheckedChanged: function (newChecked) {
var isMappedUsed = !_.isEmpty(this.valueMap),
oldValue = this.initialValue,
newValue;
console.log('called');
if (isMappedUsed) {
newValue = this.valueMap[newChecked];
} else {
newValue = oldValue;
}
if (!this.multiple && newChecked) {
this.value(newValue);
} else if (!this.multiple && !newChecked) {
if (typeof newValue === 'boolean') {
this.value(newChecked);
} else if (newValue === this.value.peek()) {
this.value('');
}
if (isMappedUsed) {
this.value(newValue);
}
} else if (this.multiple && newChecked && this.value.indexOf(newValue) === -1) {
this.value.push(newValue);
} else if (this.multiple && !newChecked && this.value.indexOf(newValue) !== -1) {
this.value.splice(this.value.indexOf(newValue), 1);
}
},
/**
* @inheritdoc
*/
onUpdate: function () {
if (this.hasUnique) {
this.setUnique();
}
return this._super();
},
/**
* @inheritdoc
*/
reset: function () {
if (this.multiple && this.initialChecked) {
this.value.push(this.initialValue);
} else if (this.multiple && !this.initialChecked) {
this.value.splice(this.value.indexOf(this.initialValue), 1);
} else {
this.value(this.initialValue);
}
this.error(false);
return this;
},
/**
* @inheritdoc
*/
clear: function () {
if (this.multiple) {
this.value([]);
} else {
this.value('');
}
this.error(false);
return this;
}
});
});
Run below command :
php bin/magento s:s:d -f
php bin/magento c:f
Then go to your admin form and check in the console you can see called
Now you need to get your toggle field value and hide/show your fields.
That’s all, I hope it helps!
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0