validationerror-handlingpolymerpaper-elements

paper-input: different error-messages (w and w/o auto-validate)


is there any possibility to add different error-messages to a paper-input element? Let's assume the following:

I have a registration form, built with 5 paper-input fields. Two of them are e-mail fields (e-mail and e-mail validation). Now I put a pattern to both of the fields to validate against a valid e-mail address and I set both of the input fields to auto-validate. The error-message is a custom, translateable string. Finished it does look like this:

    <paper-input id="__form_field_email"
                 tabindex="3"
                 label="[[xTranslate('application.modules.users.new.fields.email')]]"
                 auto-validate
                 pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}"
                 error-message="[[xTranslate('application.modules.users.new.error_messages.email_not_valid')]]"></paper-input>

    <paper-input id="__form_field_email_validation"
                 tabindex="4"
                 label="[[xTranslate('application.modules.users.new.fields.email_validation')]]"
                 auto-validate
                 pattern="[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}"
                 error-message="[[xTranslate('application.modules.users.new.error_messages.email_not_valid')]]"></paper-input>

Everything works fine, except the user enters two different e-mail addresses in the fields. There is a paper-button at the end with an on-tap listener. When clicked, the form gets validated. But: if the e-mail addresses don't match, I can't just swap the error message for one (or both) field(s), as then the error message doesn't apply if the user then enters an invalid address.

Is there any possibility to add another, maybe "standalone" error-message? I thought about paper-input-error, but the invalid property is readOnly and can't be set.

Thanks for any hint.


Solution

  • Addressing the final part of your question, you can always control the validity of an element by writing your own custom validator. For example, one defined like this:

    <link rel="import" href="../../bower_components/polymer/polymer-element.html">
    <link rel="import" href="../../bower_components/iron-validator-behavior/iron-validator-behavior.html">
    
    <dom-module id="my-value-match-validator">
      <script>
        /**
         * `my-value-match-validator` Description
         *
         * @summary ShortDescription.
         * @customElement
         * @polymer
         * @extends {Polymer.Element}
         */
        class MyValueMatchValidator extends Polymer.mixinBehaviors([Polymer.IronValidatorBehavior], Polymer.Element) {
          /**
           * String providing the tag name to register the element under.
           */
          static get is() {
            return 'my-value-match-validator';
          }
    
          /**
           * Object describing property-related metadata used by Polymer features
           */
          static get properties() {
            return {
              name: {
                type: String,
              },
              valueToMatch: {
                type: String,
                value: '',
              },
              allowEmpty: {
                type: Boolean,
                value: false,
              },
              _compareValue: {
                type: String,
                'computed': '_computeCompareValue(valueToMatch, allowEmpty)'
              }
            };
          }
    
          connectedCallback() {
            super.connectedCallback();
            var validatorName = MyValueMatchValidator.is;
            if (this.name) {
              validatorName = this.name;
            }
            new Polymer.IronMeta({ type: 'validator', key: validatorName, value: this });
          }
    
          _computeCompareValue(valueToMatch, allowEmpty) {
            if (allowEmpty) {
              return '';
            }
            return valueToMatch;
          }
    
          validate(value) {
            if (null == value) {
              value = '';
            }
            return this._compareValue === value;
          }
    
        }
    
        window.customElements.define(MyValueMatchValidator.is, MyValueMatchValidator);
      </script>
    
    </dom-module>
    

    Can be used like this:

    <my-value-match-validator name="match_password" value-to-match="[[password]]" allow-empty="[[!enableConfirmPassword]]"></my-value-match-validator>
    
    <paper-input tabindex="7" id="new_password" label="Change Password" value="{{password}}" type="password" validator="min-length-validator"
    error-message="Use at least 6 characters" auto-validate></paper-input>
    <paper-input disabled="[[!enableConfirmPassword]]" tabindex="8" id="confirm_new_password" label="Confirm new password" type="password"
    auto-validate validator="match_password" error-message="The two passwords need to match" value=""></paper-input>