1

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:

enter inputs loading ticks

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

1

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.

  1. input.html gets called from vendor/magento/module-checkout/view/frontend/web/template/shipping-address/form.html:13
  2. form.html is called from vendor/magento/module-checkout/view/frontend/web/js/view/shipping.js:61
  3. shipping.js is called from vendor/magento/module-checkout/view/frontend/layout/checkout_index_index.xml:119
  4. This leads to the shipping-address component - 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!

2
  • 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 tomorrow
    – andy jones
    Feb 22, 2018 at 18:52
  • 1
    It 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
    Feb 22, 2018 at 19:35
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.