javascripthtmlvalidationxpages

re-use regular expression on clientside for onkeyup event


For my xpages/jsf application I have setup for an xe:input control the following validation:

<xp:this.validators>
    <xp:validateConstraint
        regex="${application.regex_email}"
        message="please follow the rules">
    </xp:validateConstraint>
    <xp:validateRequired
        message="follow the rules">
    </xp:validateRequired>
</xp:this.validators>

The regular expression I use:

regex_email=^([\\w-]+(?:\\.[\\w-]+)*)@(acme\\.org|acme\\.com)

(so I allow only email addresses from acme.org and asme.com domains).

This works fine but I want to apply the same to validation to the client-side, so in the onkeyup event that same (or similar) regex is used. But I do not know how. Can anyone explain how to?

Basically I want to prevent that users enter capitals in the allowed mail domains.


Solution

  • Here is a very basic javascript implementation of such validation (triggered when the input looses focus but you can use the event of your choosing)

    // Note the 'i' flag to ignore case
    const emailPattern = /^([\w-]+(?:\.[\w-]+)*)@(acme\.org|acme\.com)/i;
    
    const emailInput = document.getElementById('email');
    const errorSpan = document.getElementById('error');
    const inputForm = document.getElementById('form');
    
    function isEmailValid() {
      const inputContent = emailInput.value;
      return emailPattern.test(inputContent);
    }
    
    function normalizeEmailInput() {
      const value = (emailInput.value ?? '').trim();
      const match = emailPattern.exec(value);
      // lower case domain only, but you could lower case the whole string and ignore what I did with the pattern
      emailInput.value = match !== null ? `${match[1]}@${match[2].toLowerCase()}` : value;
    }
    
    emailInput.addEventListener('blur', () => {
      normalizeEmailInput();
      errorSpan.style.display = isEmailValid() ? 'none' : 'inline';
    });
    
    emailInput.addEventListener('keyup', () => {
      normalizeEmailInput();
    });
    
    inputForm.addEventListener('submit', (evt) => {
      if (isEmailValid()) {
        alert('all good');
      } else {
        alert('Invalid email');
        evt.preventDefault();
      }
    });
    #error {
      color: red;
      display: none;
    }
    <form id="form">
    <input id="email" type="text" /><br />
    <span id="error">Invalid email</span><br />
    <button type="submit">Submit</button>
    </form>