Custom validity helpers for Vue.js and Svelte

Custom validity helpers for Vue.js and Svelte
Play this article

HTML5 comes with a nifty feature to show custom form validation messages on form submission (see cover image). This looks different in each browser/OS - but it is a standard HTML5 feature, fully supported in all modern browsers.

This is easy enough to use through javascript:

element.setCustomValidity('That is the wrong name!');

But when using a front end framework like Vue.js or Svelte, this means that we first need to get a reference to the DOM element and make sure that the element is mounted before executing above javascript.

Wouldn't it be nice if this could just be set as an attribute directly on each input element? Something like this:

<input validity="That is the wrong name!" />

Here's how you can do just that:

Vue.js

Run before loading your app, to make this globally available:

Vue.directive('validity', function (el, binding) {
  el.setCustomValidity(binding.value?binding.value:'');
})

In a Vue component (.vue file):

<template>
  <input type="text"
         v-model="name" 
         v-validity="name!=='joe'?'That is the wrong name!':''" />
</template>         

<script>
  export default {
    data: function () {
      return {
        name: ''
      }
    }
  }
<script>

Svelte

In a "shared.js" file:

export function Validity(node, val) {
    if(!!val) node.setCustomValidity(val);
    return {
        update(newVal) {
            node.setCustomValidity(newVal?newVal:'');
        }
    };
}

In a ".svelte" component file:

<input type="text"
       bind:value={name}
       use:Validity={name!=='joe'?'That is the wrong name!':''}>

<script>
  import {Validity} from './shared.js';
  let name='';
</script>