IE11 and validationController validation

Hello aurelians,

Hopefully someone has an answer to this issue we’re running into. We have 2 Aurelia applications that have the following validation logic;

buttonClick() {
    this.validationController.validate().then((result) => {
        console.log('button clicked', this.validationController);

        if (result.valid === true) {
            console.log('valid');
        } else {
            console.log('not valid');
        }
    });
}

The weird thing we haven’t been able to figure out is the following; this validation fires successfully in Chrome, FireFox, Edge (the old one), and IE11 in 1 of our apps. Leaving a required field empty and hitting the button that fires this code will keep the user from moving on.

The problem we’re running into is that in our other app the validationController will return .valid as true in IE11 when the button is clicked even when nothing has been filled out. It seems that somehow all rules are lost when the button is clicked in IE11 and the user gets sent to the next page when they should have stayed on the same page. Errors also don’t appear. The ValidateResult array is not there at all, length is 0, when every other browser will return the expected errors in here.

The validation rules do fire correctly per input. When selecting an option from a select list and changing this selection back to an option with no value will display the error message that the field is required, clicking the button that fires buttonClick will then validate that this empty selection is somehow valid.

Now, I did get the validation for our form to work correctly by using the following;

buttonClick() {
    this.validator.validateObject(this).then(results => {
        console.log('button clicked', this.validationController);

        let valid = true;

        // results is an array of validation results. Each result has a
        // valid property set to true if the rule is valid.
        for (let result of results) {
            console.log('result', result);
            valid = valid && result.valid;
        }

        //this.canSave = valid;
    });
}

While this works, it feels like we’re doing a lot more than necessary to get the validation working.

A full sample of a test page that works in 1 of our apps but not in the other is the following;

.html;

<template>
<div>
    <input type='text' name='testInput' value.two-way="testInput & validate" />

    <button click.trigger="buttonClick()" id='btnTest'>Test Button</button> 
</div>    
</template>

.ts

import { autoinject, bindable } from "aurelia-framework";
import { ValidationController, ValidationControllerFactory, ValidationRules, Validator } from "aurelia-validation";
import InputValidationRenderer from 'resources/extensions/validationRenderer';
import { EventAggregator } from 'aurelia-event-aggregator';
@autoinject()
export class TestPage {
	
	validationController: ValidationController;
	testInput: string = "";    
	validator: Validator;

	constructor(private controllerFactory: ValidationControllerFactory, private eventAggregator: EventAggregator, validator: Validator) { 
		this.validator = validator;
		this.setupValidation(controllerFactory);        
	}

	private setupValidation(controllerFactory: ValidationControllerFactory) {
		this.validationController = controllerFactory.createForCurrentScope();
		this.validationController.addRenderer(new InputValidationRenderer());
		this.addValidationRules();
	}

	private addValidationRules() {
		ValidationRules
			.ensure((x: this) => x.testInput).displayName('Display Name')
			.required()
			.maxLength(200)
			.matches(/^[\w-]{3,}$/).withMessage(`\${$displayName} can only use alphanumeric, underscore, and dash characters.`)
			.on(this);
	}

	buttonClick() {
		this.validationController.validate().then((result) => {
			console.log('button clicked', this.validationController);

			if (result.valid === true) {
				console.log('valid');
			} else {
				console.log('not valid');
			}
		});

//        this.validator.validateObject(this).then(results => {
//            console.log('button clicked', this.validationController);
//
//            let valid = true;
//
//            // results is an array of validation results. Each result has a
//            // valid property set to true if the rule is valid.
//            for (let result of results) {
//                console.log('result', result);
//                valid = valid && result.valid;
//            }
//
//            //this.canSave = valid;
//        });
	}
}

We’ve simplified the test page to the point where it’s just a single input with a button, made sure the aurelia-validation version is the same (it’s 1.5.0 in the application where the validationController.validate does work correctly), and still we’re not able to fire validation by using the validationController in the other app. The one thing we have not tried yet is set up a brand new app and trying the exact same test page again, but why would the same setup of a page work in IE11 in 1 app, but not in another app?

1 Like

Hello @Roy, from your problem description it seems that the bindings are not getting registered to the controller you are using to validate. However, as you are creating the controller for the current scope, that would have been the case. There is easy way to verify if that’s the case. You can practically pass on your controller to the validate binding behavior like this:

<input type='text' name='testInput' value.two-way="testInput & validate:validationController " />

Refer http://aurelia.io/docs/plugins/validation#validate-binding-behavior for more information.

Regardless that works or not, may I ask you to share a minimal repo that reproduces this behavior? If can also share a dumber gist app, if you like. This will help us track down the root cause of this issue.

1 Like

Not sure if dumber is going to work with IE. Best would be to share a GitHub repo with the repro

1 Like

The dumber-gist doesn’t support IE.

1 Like

Thanks for the feedback, I’ll look into @Sayan751’s validate:validationController suggestion and will create a stripped down version of our app when I get the chance.

1 Like

I use controller.errors instead of result.

this.validationController.validate().then(result => {
    if(this.validationController.errors && this.validationController.errors.length > 0) {
        console.log('not valid');
    } else {
        console.log('valid');
    }
})

I’m not sure if this is the answer.

1 Like