Im not sure if this is a bug, or it's me being silly. What I'm trying to achieve is in the checkout and on an input is the following:
aria-invalid="null"
However what I've noticed is on initial load of the checkout every input on the page loads the
aria-invalid="false"
This can be seen here:
The ticks indicate that the value is set to false, however there isn't any content inside of these items.
What I want is, the value to actually return null on first load, and then use the Ko.observable to say if it should be:
True - there is an error ( its empty )
False - everything is okay
I've had a nosey around and found that the file sits here:
/vendor/magento/module-ui/view/frontend/web/templates/form/element/input.html
And returns the following:
<input class="input-text" type="text" data-bind="
value: value,
valueUpdate: 'keyup',
hasFocus: focused,
attr: {
name: inputName,
placeholder: placeholder,
'aria-describedby': getDescriptionId(),
'aria-required': required,
'aria-invalid': error() ? true : 'false',
id: uid,
disabled: disabled
}" />
I've gotten to this stage and tried to find the even/function for " error() " but I've gotten lost in the rabbit hole.
If anyone has any advice on this, that'd be awesome.
2 Answers 2
I've no working M2 box that is at least 2.2 which is when I think aria-invalid was introduced so I can't look into it other than the codebase but this is what I presume it happening.
input.htmlgets called fromvendor/magento/module-checkout/view/frontend/web/template/shipping-address/form.html:13form.htmlis called fromvendor/magento/module-checkout/view/frontend/web/js/view/shipping.js:61shipping.jsis called fromvendor/magento/module-checkout/view/frontend/layout/checkout_index_index.xml:119- This leads to the
shipping-addresscomponent -vendor/magento/module-checkout/view/frontend/layout/checkout_index_index.xml:92and this is where regions are defined.
That's a horrible maze and I got lost several times so I probably missed parts, my thinking is something along the way tells these inputs to use vendor/magento/module-ui/view/base/web/js/form/element/abstract.js but I haven't confirmed this.
I believe this is where the error function is called from.
There are functions like this that alter the state of this.error().
/**
* Sets value observable to initialValue property.
*
* @returns {Abstract} Chainable.
*/
reset: function () {
this.value(this.initialValue);
this.error(false);
return this;
},
Hope this points you in the right direction, I could be way off as it's so damned complex and over engineered but it's where I'd start looking. Warning that changing abstract.js will likely affect a lot of other functionality.
Good luck!
-
Ahh mate, I was in the abstract for a while, scratching my head. I’m tempted to say that the core is wrong for this. But... I modded this.error, but not much joy. I’m going to give it another crack tomorrowandy jones– andy jones2018年02月22日 18:52:41 +00:00Commented Feb 22, 2018 at 18:52
-
1It could well be somewhere else, abstract is the only place making sense to me right now. It's madness, it'd probably be easier to create your own shipping form :/Ben Crook– Ben Crook2018年02月22日 19:35:55 +00:00Commented Feb 22, 2018 at 19:35
So to answer my own question. Yes @ben is right. The abstract.js is the right place to be looking. However, the plot thickens.
aria-invalid can only return the following values:
- false (default) No errors detected
- grammar A grammatical error has been detected. spelling A
- spelling error has been detected.
- true The value has failed validation.
So seems that you can't return null on the aria attribute. Doh. So what to do?
Seems that there are observables on the containing div, this screamed edit me, so adding to the following in abstract:
/**
* Extends 'additionalClasses' object.
*
* @returns {Abstract} Chainable.
*/
_setClasses: function () {
var additional = this.additionalClasses;
if (_.isString(additional)) {
this.additionalClasses = {};
if (additional.trim().length) {
additional = additional.trim().split(' ');
additional.forEach(function (name) {
if (name.length) {
this.additionalClasses[name] = true;
}
}, this);
}
}
_.extend(this.additionalClasses, {
_required: this.required,
_error: this.error,
_complete: this.value, <- adding this
_warn: this.warn,
_disabled: this.disabled
});
console.log(this);
return this;
},
Adding
_complete: this.value,
Allowed me to add a class to the parent div and on change of the input value from true to false the class gets added. I'm not sure if this should be a pull request? Im not sure if everyone desires it like i do.
Hopefully anyone who needs this functionality, hopefully this will help.