I have created a custom module to add some fields to the order checkout however I have some troubles enabling them conditionally.
I have a radio button and 4 elements
When the radio is clicked, depending on the value, I change the 4 fields to disabled=false
or disabled=true
and I would like the input fields to either add the attribute disabled
or not even display at all
I've added the fields through my layout processor class like this
class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
{
/**
* @var CustomerSession
*/
protected $customerSession;
/**
* @var HelperData
*/
protected $helperData;
/**
* LayoutProcessor constructor.
* @param CustomerSession $customerSession
* @param HelperData $helperData
*/
public function __construct(
CustomerSession $customerSession,
HelperData $helperData
) {
$this->customerSession = $customerSession;
$this->helperData = $helperData;
}
protected function getIsBusinessField()
{
$position = $this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION);
$inputElementTmpl = 'Vendor_Invoicefields/form/element/radio';
if ($position == 3) {
$inputElementTmpl = 'Vendor_Invoicefields/form/element/radio_payment';
}
$customAttributeCode = 'is_business';
$customField = [
'component' => 'Vendor_Invoicefields/js/view/form/element/radio',
'config' => [
'customScope' => 'customCheckoutForm',
'template' => 'ui/form/field',
'elementTmpl' => $inputElementTmpl
],
'dataScope' => 'customCheckoutForm' . '.' . $customAttributeCode,
'label' => __('Are you an individual or a business?'),
'provider' => 'checkoutProvider',
'sortOrder' => 0,
'validation' => [
'required-entry' => true
],
'options' => [],
'filterBy' => null,
'customEntry' => null,
'visible' => true,
//'value' => $this->getTaxInformationSession($customAttributeCode)
];
return $customField;
}
protected function getLayoutField($customAttributeCode, $label, $required_entry, $sortOrder)
{
$position = $this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION);
// $inputElementTmpl = 'ui/form/element/input';
$inputElementTmpl = 'Vendor_Invoicefields/form/element/input';
// if ($position == 3) {
// $inputElementTmpl = 'Vendor_Invoicefields/form/element/input';
// }
$customField = [
'component' => 'Magento_Ui/js/form/element/abstract',
'config' => [
'customScope' => 'customCheckoutForm',
'template' => 'ui/form/field',
'elementTmpl' => $inputElementTmpl
],
'dataScope' => 'customCheckoutForm' . '.' . $customAttributeCode,
'label' => __($label),
'provider' => 'checkoutProvider',
'sortOrder' => $sortOrder,
'validation' => [
'required-entry' => (boolean) $required_entry
],
'additionalClasses' => 'tax_information_group',
'options' => [],
'filterBy' => null,
'customEntry' => null,
'visible' => true,
//'value' => $this->getTaxInformationSession($customAttributeCode)
];
return $customField;
}
public function getTaxInformationSession($key = '')
{
$result = '';
$tax_information = $this->customerSession->getTaxInformation();
if (array_key_exists($key, $tax_information) && $tax_information[$key] != "") {
$result = $tax_information[$key];
}
return $result;
}
protected function getCompanyNameField()
{
$customField = [];
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_COMPANY_NAME)) {
$required_entry = $this->helperData->getStoreConfig(HelperData::CONFIG_REQUIRE_COMPANY_NAME);
$customField = $this->getLayoutField('company_name', 'Company Name', $required_entry, 1);
}
return $customField;
}
protected function getTaxIdField()
{
$customField = [];
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_TAX_ID)) {
$required_entry = $this->helperData->getStoreConfig(HelperData::CONFIG_REQUIRE_TAX_ID);
$customField = $this->getLayoutField('tax_id', 'Tax ID', $required_entry, 2);
}
return $customField;
}
protected function getTaxDepartmentField()
{
$customField = [];
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_TAX_DEPARTMENT)) {
$required_entry = $this->helperData->getStoreConfig(HelperData::CONFIG_REQUIRE_TAX_DEPARTMENT);
$customField = $this->getLayoutField('tax_department', 'Tax Department', $required_entry, 3);
}
return $customField;
}
protected function getOccupationField()
{
$customField = [];
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_OCCUPATION)) {
$required_entry = $this->helperData->getStoreConfig(HelperData::CONFIG_REQUIRE_OCCUPATION);
$customField = $this->getLayoutField('occupation', 'Occupation', $required_entry, 4);
}
return $customField;
}
protected function getCustomCheckoutStep()
{
$customAttributeCode = 'tax-information-step';
$customField = [
'component' => 'Vendor_Invoicefields/js/view/my-step-view',
'children' => [
'custom-checkout-form-container' => [
'component' => 'Vendor_Invoicefields/js/view/custom-checkout-form',
'provider' => 'checkoutProvider',
'config' => [
'template' => 'Vendor_Invoicefields/custom-checkout-form'
],
'children' => [
'custom-checkout-form-fieldset' => [
'component' => 'uiComponent',
'displayArea' => 'custom-checkout-form-fields',
'children' => []
]
]
]
],
'sortOrder' => 2,
];
return $customField;
}
protected function getCustomCheckoutForm()
{
$customAttributeCode = 'tax-information-step';
$customField = [
'component' => 'Vendor_Invoicefields/js/view/custom-checkout-form',
'provider' => 'checkoutProvider',
'config' => [
'template' => 'Vendor_Invoicefields/custom-checkout-form-fields'
],
'children' => [
'custom-checkout-form-fieldset' => [
'component' => 'uiComponent',
'displayArea' => 'custom-checkout-form-fields',
'children' => []
],
'custom-validator' => [
'component' => 'Vendor_Invoicefields/js/view/custom-validate'
]
]
];
return $customField;
}
public function addFieldsToForm(&$parentElement)
{
$parentElement['custom-checkout-form-container'] = $this->getCustomCheckoutForm();
$taxInformationStep = &$parentElement['custom-checkout-form-container']['children']
['custom-checkout-form-fieldset']['children'];
$taxInformationStep['is_business'] = $this->getIsBusinessField();
$taxInformationStep['company_name'] = $this->getCompanyNameField();
$taxInformationStep['tax_id'] = $this->getTaxIdField();
$taxInformationStep['tax_department'] = $this->getTaxDepartmentField();
$taxInformationStep['occupation'] = $this->getOccupationField();
return $parentElement;
}
/**
* @param array $jsLayout
* @return array
*/
public function process($jsLayout)
{
if (!$this->helperData->isModuleEnabled()) {
return $jsLayout;
}
/* Before Shipping Address */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '1') {
$beforeShippingAddressPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['shipping-step']['children']['shippingAddress']['children']['before-form']['children'];
if (isset($beforeShippingAddressPosition)) {
$this->addFieldsToForm($beforeShippingAddressPosition);
}
}
/* After Shipping Address */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '2') {
if (!$this->customerSession->isLoggedIn()) {
$afterShippingAddressPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];
} else {
$afterShippingAddressPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['shipping-step']['children']['shippingAddress']['children']['before-form']['children'];
}
if (isset($afterShippingAddressPosition)) {
$this->addFieldsToForm($afterShippingAddressPosition);
}
}
/* After Billing Address */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '3') {
$afterBillingAddressPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['billing-step']['children']['payment']['children']
['payments-list']['children']['before-place-order']['children'];
if (isset($afterBillingAddressPosition)) {
$this->addFieldsToForm($afterBillingAddressPosition);
}
}
/* Before Payment Information */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '4') {
$beforePaymentPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['billing-step']['children']['payment']['children']['beforeMethods']['children'];
if (isset($beforePaymentPosition)) {
$this->addFieldsToForm($beforePaymentPosition);
}
}
/* After Payment Information */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '5') {
$afterPaymentPosition = &$jsLayout['components']['checkout']['children']['steps']['children']
['billing-step']['children']['payment']['children']['afterMethods']['children'];
if (isset($afterPaymentPosition)) {
$this->addFieldsToForm($afterPaymentPosition);
}
}
/* Summary */
if ($this->helperData->getStoreConfig(HelperData::CONFIG_SHOW_ON_CHECKOUT_POSITION) == '6') {
$SummaryPosition = &$jsLayout['components']['checkout']['children']['sidebar']['children']
['summary']['children'];
if (isset($SummaryPosition)) {
$this->addFieldsToForm($SummaryPosition);
}
}
return $jsLayout;
}
I then created my radio element
define([
'Magento_Ui/js/form/element/abstract',
'jquery',
'uiRegistry'
], function(Abstract, $, uiRegistry) {
'use strict';
return Abstract.extend({
initialize: function () {
this._super();
this.value(0);
this.hideElement(true);
return this;
},
company_name_field: uiRegistry.get('index = company_name'),
tax_id_field: uiRegistry.get('index = tax_id'),
tax_department_field: uiRegistry.get('index = tax_department'),
occupation_field: uiRegistry.get('index = occupation'),
/**
* Handle radio click, return true to check te radio
*/
click: function(data, event) {
this.change(event.target.value);
this.value(event.target.value);
return true;
},
/**
* Change value of radio
*/
change: function(value) {
this.hideElement(value);
},
hideElement: function(value) {
var elements = $('.tax_information_group');
if (value === '0' || value ===0) {
elements.hide();
this.updateElementStatus(true);
} else if (value === '1' || value === 1) {
elements.show();
this.updateElementStatus(false);
}
},
updateElementStatus: function (value) {
if (this.company_name_field) {
this.company_name_field.disabled(value);
}
if (this.tax_id_field) {
this.tax_id_field.disabled(value);
}
if (this.tax_department_field) {
this.tax_department_field.disabled(value);
}
if (this.occupation_field) {
this.occupation_field.disabled(value);
}
}
});
});
And finally I added my input element template
<input ko-if="disabled" class="admin__control-text" type="text" data-bind="
event: {change: userChanges},
value: value,
hasFocus: focused,
valueUpdate: valueUpdate,
attr: {
name: inputName,
placeholder: placeholder,
'aria-describedby': noticeId,
id: uid,
maxlength: 255
}"/>
As per the devdocs https://devdocs.magento.com/guides/v2.3/ui_comp_guide/concepts/magento-bindings.html
I've tried to use the bindings for disabled but I always receive some type of error.
Case 1
data-bind="
disable: !isEnabled
"
Uncaught ReferenceError: Unable to process binding "disable: function(){return !isEnabled }"
Case 2
attr: {
name: inputName,
placeholder: placeholder,
'aria-describedby': noticeId,
id: uid,
disabled: disabled,
maxlength: 255
}
Nothing happens
Case 3
I've tried using the accessors isEnabled, isDisabled in any area either the attribute, or the input element but I get an error that the function is undefined.
I'm not quite sure where I'm doing it wrong. I'm assuming the property disabled is not declared as ko.observable thus it's not reactive in the element but in that case there should be a method responsible for monitoring this. That's why I thought of using the accessor methods but to no avail.
Any help is appreciated because I'm completely new to knockoutjs