DEV Community

Cover image for Custom validity helpers for Vue.js and Svelte
Jesper Høy
Jesper Høy

Posted on • Edited on • Originally published at jesperhoy.com

Custom validity helpers for Vue.js and Svelte

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!');
Enter fullscreen mode Exit fullscreen mode

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!" />
Enter fullscreen mode Exit fullscreen mode

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:'');
})
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

Svelte

In a "shared.js" file:

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

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>
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
roblevintennis profile image
Rob Levin

It's nice that you should the setCustomValidity (I see so many html5 validation tuts which only mention the html5 fields themselves but of course to do anything useful you need setCustomValidity!).

Isn't your Validity in svelte an action? Might be worth updating article to mention that.

For the Vue.directive I've not used before. How does this compare to using the composition api (or is that actually what's happening behind the scenes?)