How to add custom validator to paper-input?
Asked Answered
A

2

12

Need to add a custom validator which does some complex validation based on the values of other fields in the html.

Tried adding custom validator function as an attribute to the paper-input element but it wont get called at all.

    <dom-module id='custom-ele'>
            <paper-input is="iron-input" id='input_1' label='Label_1' validator='validate_1'></paper-input>
            <paper-input is="iron-input" id='input_2' label='Label_2' validator='validate_2'></paper-input>
            ...
    </dom-module>
    <script>
    Polymer({

        is: 'custom-ele',

        validate_1: function() {
            //validation code
        },

        validate_2: function() {
           //validation code 
        }

    });
    </script>
Ajar answered 12/8, 2015 at 2:29 Comment(0)
B
14

The validator has to implement IronValidatorBehavior (see docs). Also, if you want to validate automatically, you need to set the auto-validate attribute. To achieve your goal you could create a custom validator for each type of validation that you want to use. Alternatively, you could create a generic custom validator and set the validate function upon initialisation. Here's an example.

Polymer({

    is: 'custom-validator',

    behaviors: [
        Polymer.IronValidatorBehavior
    ]
});

<dom-module id='validation-element'>
    <template>
        <custom-validator id="valid1" validator-name="validator1"></custom-validator>
        <custom-validator id="valid2" validator-name="validator2"></custom-validator>
        <paper-input auto-validate id='input_1' label='Label_1' validator='validator1'></paper-input>
        <paper-input auto-validate id='input_2' label='Label_2' validator='validator2'></paper-input>
    </template>
</dom-module>
<script>

    Polymer({

        is: 'validation-element',

        validate1: function(value) {
            //validation code
            console.log("validate1");
            return value.length > 3;
        },

        validate2: function(value) {
            //validation code
            console.log("validate2");
            return value.length > 5;
        },

        ready: function() {
            this.$.valid1.validate = this.validate1.bind(this);
            this.$.valid2.validate = this.validate2.bind(this);
        }

    });

</script>

You can find a working example in this plunk.

Boating answered 12/8, 2015 at 9:38 Comment(8)
Your example works perfectly in my code. The only thing I'd like to mention is the first Polymer object should be placed in a separate html file, just like what you did in the plunk example. Thank you!Envelope
The example will be clearer, if the return values in validate1 and validate2 are set to false at the very beginning.Stooge
@Maria, this example stop working if I set type="number" to paper-input... for example any input after first 2 dots will not call validator function.Thus following could be set: "11.....212..2..2.2..2...". Do you know how to make validation for type="number" paper-input? Thx.Ilo
@Ilo I did a quick test and saw that if type is set to number it will not accept any non-number input. See this plunk. So I did not manage to reproduce your input using the keyboard. Or did you do that programmatically?Boating
@JosephHui Thanks for the suggestion. I have updated the code (also in the plunk) to only return true if at least 4 characters are entered in the first input and at least 6 in the second.Boating
@Maria, try to type '------' or 'eeeee' or '.....' your last plunker and you will see that validate function doesn't called in these cases (watch console.log)Ilo
@Ilo ah yes, I see it now. Might be worth reporting this to the Polymer team on Github. I checked with the debugger and the problem seems to be related to the fact that the input that is wrapped by the paper-input will return an empty value for anything that is not a number.Boating
And here's the issue on github.Boating
I
7

Ok, my answer might not be the "Polymer way" but it works and is more the "traditional programmatic" way.

The short list of ideas for this solution:

  1. paper-input aka iron-input look-up the value of the validator attribute in the iron-meta global object
  2. Each Polymer.IronValidatorBehavior has a name (validatorName), a type ('validator') and a validate function
  3. Each Polymer.IronValidatorBehavior registers itself in the corresponding 'validator' list in the iron-meta object

So this is a short code I derived from the points above:

var validator = {
    validatorName: 'my-custom-validator',
    validatorType: 'validator',
    validate:      function(value) { ...my validation code... }
};
new Polymer.IronMeta({
    type: validator.validatorType,
    key: validator.validatorName,
    value: validator
});

You can put this code in any 'attached' or 'created' event handler. But run it before any validation is done of course...

Then you can write

<paper-input validator="my-custom-validator"></paper-input>

If you wanna check if your validator is register with the input, navigate down the dom-tree in any dev-tool and hit: $0.hasValidator() and $0.validator to see if your validator has been successfully registered with the input.

Irinairis answered 19/8, 2015 at 14:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.