Simple zero-dependency input mask for Vue.js and vanilla JS.

Overview

Maska

Simple zero-dependency input mask for Vue.js and vanilla JS. Demo and examples.

  • No dependencies
  • Small size (~2 Kb gziped)
  • Ability to define custom tokens
  • Supports repeat symbols and dynamic masks
  • Works on any input (custom or native)

Install

npm install maska

To load latest version from CDN you can use:

">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/maska.js">script>

Usage with Vue 2.x

If you load Vue.js via ">

<template>
    <form>
        <input v-maska="'###'">
    form>
template>

<script>
import { maska } from 'maska'

export default {
    directives: { maska }
}
script>

With Vue you could use computed property as mask value. In this case mask will be reactive.

Usage with Vue 3.x

With Vue 3.x you need to explicitly add Maska plugin or directive to your app:

const app = Vue.createApp({...})
// use as plugin
app.use(Maska);
// or as directive
// app.directive('maska', Maska.maska);
app.mount('#app');

Usage with vanilla JS

Just load script maska.js and init it, passing element(s) or document.querySelector expression:

var mask = Maska.create('.masked');

Mask could be set as data-mask attribute on element:

<input data-mask='##/##/####'>

or can be set by mask option on initialization:

var mask = Maska.create('.masked', {
    mask: '##/##/####'
});

You can pass custom tokens while initialization:

var mask = Maska.create('.masked', {
    tokens: { 'Z': { pattern: /[а-яА-Я]/ }}
});

You can destroy mask like that:

var mask = Maska.create('.masked');
mask.destroy();

Mask syntax

Default tokens:

{
    '#': { pattern: /[0-9]/ },
    'X': { pattern: /[0-9a-zA-Z]/ },
    'S': { pattern: /[a-zA-Z]/ },
    'A': { pattern: /[a-zA-Z]/, uppercase: true },
    'a': { pattern: /[a-zA-Z]/, lowercase: true },
    '!': { escape: true },
    '*': { repeat: true }
}
  • Escape symbol escapes next token (mask !# will render #)
  • Repeat symbol allows repeating current token until it’s valid (e.g. mask #* for all digits or A* A* for CARDHOLDER NAME)

You can add your own tokens by passing them in maska directive or create method at initialization (see above). Important: pattern field should be JS regular expression (/[0-9]/) or string without delimiters ("[0-9]").

Transform function for tokens

While specifying custom tokens you can also add a symbol-transformation behavior such as uppercase, lowercase, or even define a transform function:

{
    'T': { pattern: /[0-9]/, transform: (char) => String(Number(char) % 2) } // '1234567890' -> '1010101010'
}

Use mask programmatically

You can use mask function directly by importing it (or using Maska.mask if you use script tag)

    import { mask } from 'maska'

    const maskedValue = mask(value, '###')

Getting raw (unmasked) value

To get raw value read data-mask-raw-value property of input. You can subscribe to @maska event to know when this value updates. Please see examples page.

Dynamic masks

To use several masks on single input, pass array instead of string as mask value.

You could use it with Vue directives:

">
<input v-maska="['+1 (###) ##-##-##', '+1 (###) ###-##-##']">

<input v-maska="{ mask: ['!#HHHHHH', '!#HHHHHH-HH'], tokens: { 'H': { pattern: /[0-9a-fA-F]/, uppercase: true }}}">

and with vanilla JS attribute, but make sure that mask value is proper JSON, so use double quotes inside array:

">
<input data-mask='["# cm", "#.# cm", "#.## cm"]'>

Known issues

When used on input of type number could have inconsistent behavior in different browsers. Use attribute inputmode if you just need a numeric keyboard for given input.

Source of Inspiration

Comments
  • Upgrade to Vue 3.1.4 + maska 1.4.4 = broken

    Upgrade to Vue 3.1.4 + maska 1.4.4 = broken

    Hi, same problem here. I just upgrade Vue to 3.1.4 and v-maska to 1.4.4, any view using v-maska throws error:

    Uncaught (in promise) TypeError: Cannot read property 'match' of undefined at n.value (maska.esm.js?795b:6) at h (maska.esm.js?795b:6) at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:155) at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:164) at invokeDirectiveHook (runtime-core.esm-bundler.js?5c40:3952) at Array.eval (runtime-core.esm-bundler.js?5c40:4972) at flushPostFlushCbs (runtime-core.esm-bundler.js?5c40:358) at flushJobs (runtime-core.esm-bundler.js?5c40:394)

    And the application dies.

    opened by ntgraph 10
  • Complex Custom Token

    Complex Custom Token

    Hello,

    i would like to use the custom token function to validate an input field for a valid time.

    v-maska="{ mask: 'UU:UU', tokens: { 'U' : { pattern: /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/ }}}"

    This is my code, but it doesn't work. Can i even pass a regex as pattern as shown above?

    thx for your answer :)

    Markus

    opened by schw4be 5
  • No formatting on model changes

    No formatting on model changes

    First of all: thanks for the awesome library it helps me to get over my frustrations of integrating Cleave with vue.js :-)

    One thing I noticed: when I have a text field bound to a v-model and there are other fields writing into this model, the formatting is not applied to the updated state. Are there any plans to support this in the future? And if not: is there a way to call the maska formatter by hand on a string variable directly? This would help me to apply the formatting before writing it back to the model.

    opened by jonsalvas 5
  • Optional mask

    Optional mask

    Is it possible to create an optional mask like: #.## cm where the user can write: 1.32cm or 1.3cm? And also for a more complex one. I want to make it so the user can type 67.300 kg or 67kg and the variations for kg.

    enhancement 
    opened by theprobugmaker 5
  • Is it possible to retrieve the raw value?

    Is it possible to retrieve the raw value?

    When using the v-maska directive, the model value is the same as the display value. Can we configure it to display the masked value but output the raw value?

    opened by skyrpex 4
  • Show mask characters immediately, not after the next character has been entered

    Show mask characters immediately, not after the next character has been entered

    Please see this GIF. We have a mask with a dot separator and the dot is only shown after we have entered the character after it. It would be great if we can see the dot once we have entered the first 2 characters and then 4 character.

    RPReplay_Final1600682337 2020-09-21 12_06_43

    opened by grouchal 4
  • Mask is not applied on vue 3 on first load

    Mask is not applied on vue 3 on first load

    i'm using version 1.4.2, when the value is set in the model inside setup function, the mask is not applied, i need to re render the component changing the :key parameter in some parent node to force the rendering. It should apply the mask when the component is loaded :)

    opened by hoomersinpsom 3
  • ESM Package

    ESM Package

    Why

    The original implementation of "module" target on package.json didn't apply babel transpilation. In webpack projects, babel doesn't run over node_modules/** files.

    Now the package is shipped with ESM and UMD package formats with babel and without babel. This covers more usage scenarios.

    Rollup was used instead of webpack because it is more flexible to generate multiples targets of the same entry file, and generate a smaller build file.

    Changes

    • Remove webpack
    • Setup rollup
    • Generate UMD and ESM dist files
    • Generate ES6 dist files (without babel)
    • Add

    Generated files

    With Babel

    • dist/maska.js - UMD (for compatibility reasons)
    • dist/maska.umd.js - UMD
    • dist/maska.esm.js - ESM

    Without Babel

    • dist/es6/maska.js - UMD
    • dist/es6/maska.umd.js - UMD
    • dist/es6/maska.esm.js - ESM
    opened by vinicius73 3
  • How to use it in Nuxt 3?

    How to use it in Nuxt 3?

    Is possible to use it with Nuxt 3?

    I tried to make a plugin, the plugin seems to load correctly, because if I duplicate te line nuxtApp.vueApp.use(Maska) appears the error [Vue warn]: Plugin has already been applied to target app..

    /plugins/maska.ts

    import Maska from 'maska'
    
    export default defineNuxtPlugin((nuxtApp) => {
        nuxtApp.vueApp.use(Maska)
    });
    

    I tried to make the plugin with the directive instead, it also seems to load correctly because duplicant the line nuxtApp.vueApp.directive('maska', maska) appears the error [Vue warn]: Directive "maska" has already been registered in target app..

    import { maska } from 'maska'
    
    export default defineNuxtPlugin((nuxtApp) => {
        nuxtApp.vueApp.directive('maska', maska)
    });
    

    But in both cases the mask don't work, look like a normal input.

    opened by Trixpua 2
  • How set max length in mask

    How set max length in mask

    Hi all, how set max length mask input I need the word to be no longer than 30 characters [{ mask: 'SX*', tokens: { X: { pattern: /[a-zA-Z0-9-_-]/, transform: (char: string) => char.toLowerCase() }, S: { pattern: /[a-zA-Z]/, transform: (char: string) => char.toLowerCase() } } }]

    opened by 7rows 2
  • Input gets incorrect caret position with attached reactive

    Input gets incorrect caret position with attached reactive

    Hi. I couldn't understand what is a reason for such behavior, but if we have any reactive which changes it's state on focus event, and for example css class binded to this reactive, when we focus our input (by click) caret goes to start of input.

    If we remove css class binding(or maska directive :) ) it works fine.

    Reproduction link - https://codesandbox.io/s/competent-turing-6kmb2?file=/src/javascript/components/Coupon.vue You can view it yourself by clicking inputs on repro link.

    This becomes a big problem when you want a build custom input component which need to support many states, i found only one way to fix it - change reactive state inside setTimeout (even nextTick won't solve the problem), but it introduces many other problems.

    https://user-images.githubusercontent.com/38207071/139776307-34fb42a6-b163-4049-a26d-d003fd564b80.mov

    opened by onemantooo 2
  • Mask breaks input values while using ! (escape) between other symbols

    Mask breaks input values while using ! (escape) between other symbols

    Hello! While I was using the mask, I came across a case where I wanted to hardcode X in the middle of the mask. When a hard-coded symbol is at the very beginning of the mask, everything works fine, but when it is in the middle all the symbols after ! are escaped instead of just the next one. It is only happening while using with an input.

    testing direct call:

    test('X!XXX', () => {
        expect(mask('9', 'X!XXX', tokens)).toBe('9X')
    })
    

    works fine

    You can reproduce the issue using demo: example: "!XXXX"

    input:9aZ output: X9aZ

    but

    example: "X!XXX"

    input:9 output: 9XXX

    I can not input any other characters/digits or delete it. Does anyone have any idea how to fix it/ make it work properly? Have a good day!

    opened by MikeW210 1
  • Vue 3:

    Vue 3: "Failed to resolve directive: maska"

    Hello, I have installed "maska": "^1.5.0" and I have the following in my vue 3 main.js:

    import Maska from 'maska';
    const app = createApp(App);
    app.directive('maska', Maska.maska)
    

    and then in a component: <CFormInput id="companyein" v-model="model.employerNumber" placeholder="##-#######" v-maska="'##-#######'" />

    With this setup I'm getting error "Failed to resolve directive: maska" and the component won't open.

    opened by vsirghii 4
  • Is it possible to use a mask on static text display fields?

    Is it possible to use a mask on static text display fields?

    I want to use the mask to display phone numbers etc formatted the same way I format the input field, but it doesn't seem to work when used with a static field. Is there any way to make it work?

    opened by musik92 0
  • Mask applied to one input affects another input if hidden with v-if

    Mask applied to one input affects another input if hidden with v-if

    If two inputs have v-if/v-else and only one of them has v-maska applied, then upon hiding the element that has the directive the other one will be affected by the mask.

    Probably closely related to https://github.com/beholdr/maska/issues/77.

    Reproduction link codesandbox

    opened by anatolykopyl 1
  • Browser tab freeze if element with v-maska is hidden with v-if

    Browser tab freeze if element with v-maska is hidden with v-if

    Can be avoided by using v-show instead, but this is not a perfect solution.

    For example I want to have a search input that is masked when I'm searching for hashtags and an unmasked input for everything else:

    <template>
      <input
        v-if="category === 'hashtags'"
        v-model="query"
        v-maska="hashtagMask"
        type="text"
        placeholder="search"
      >
      <input
        v-else
        v-model="query"
        type="text"
        placeholder="search"
      >
    </template>
    
    <script>
    export default {
      data() {
        return {
          category: 'all',
          query: '',
          hashtagMask: { mask: '!#H*', tokens: { H: { pattern: /[0-9a-zA-Zа-яА-Я_]/ } } }
        }
      }
    }
    </script>
    

    This component will freeze the browser upon switching categories and entering text into the input without the v-maska directive.

    opened by anatolykopyl 1
Releases(v1.5.0)
Owner
Alexander Shabunevich
Alexander Shabunevich
Tiny (2k gzipped) and dependency free mask input for Vue.js

The Mask A lightweight (2KB gzipped) and dependency free mask input created specific for Vue.js Docs and Demo JsFiddle Install yarn add vue-the-mask o

Vue.js Tips 1.6k Sep 20, 2022
The awesome-mask runs with Vue.js and uses the vanilla-masker to make your form awesome with masks.

The awesome-mask runs with Vue.js and uses the vanilla-masker to make your form awesome with masks. You can use patterns like: <input type="text" v-ma

Wirecard Brasil 164 Aug 3, 2022
Easy formatted numbers, currency and percentage with input/directive mask for Vue.js

vue-number-format Vue Number Format is used to format a number using fixed-point notation. It can be used to format a number with a specific number of

CodersTM 34 Sep 24, 2022
Input mask for React, Angular, Ember, Vue, & plain JavaScript

⚠️ This library is not maintained. Pull-requests and issues are not monitored. Alternatives to text-mask include: https://github.com/uNmAnNeR/imaskjs

Text Mask 8.2k Sep 30, 2022
🔡 Tiny input mask library for Vue.js (directive)

?? Tiny input mask library for Vue.js (directive)

Max Liashuk 824 Sep 24, 2022
Tiny (2k gzipped) input/directive mask for currency

v-money Mask for Vue.js Features Lightweight (<2KB gzipped) Dependency free Mobile support Component or Directive flavors Accept copy/paste Editable F

Vue.js Tips 741 Sep 23, 2022
A lightweight and dependency free input masking library created specific for Vue

Vue Input Facade A lightweight and dependency free input masking library created specific for Vue Docs and Demo Installing npm i vue-input-facade yarn

Ronald Jerez 139 Sep 14, 2022
vue-r-mask - Directive with template similar to javascript regular expression.

vue-r-mask mask directive for vue.js Template similar to javascript regular expression. /\d{2}/ Directive useful for your own input or textarea. Arbit

null 22 May 1, 2022
Vue.js component for jQuery mask plugin

Vue jQuery Mask Component Vue.js component for jQuery Mask Plugin Demo on JSFiddle Version matrix Vue.js version Package version Branch 2.x 1.x 1.x 3.

Ankur Kumar 19 Mar 4, 2022
Vue.js directive to add inputmask library to your inputs (vanilla javascript).

vue-inputmask Vue.js directive to add a mask to your inputs (vanilla javascript). It's a binding for the inputmask library by Robin Herbots https://gi

Simon Cleriot 117 Jul 17, 2022
Nice-Numeric-Input is a modern, rich featured and highly customisable numeric input built on Vue.

Nice-Numeric-Input is a modern, rich featured and highly customisable numeric input built on Vue. Capable of formatting as the user types, including currency formatting. With no extra dependencies other than Vue itself.

Jack Steel 4 Dec 9, 2021
Vue Currency Input component allows an easy input of currency formatted numbers

Vue Currency Input The Vue Currency Input component allows an easy input of currency formatted numbers. It provides both standalone component (<curren

WeblineIndia 1 May 25, 2022
A Simple Input Form For Vue 3

vue-base-input (Vue 3) Base-input: I made it, for simplify a create form on my differents projects. Base-input return if your value is valid and value

Olivier MARION 1 Dec 13, 2021
Click to show input text box Vue Component ... inspired by Trello. This is my first time publishing Vue Component via npm package and let me know if you encounter any issues, bugs, or improvement. Thanks!

label-edit Click to show input text box Vue Component ... inspired by Trello. This is my first time publishing Vue Component via npm package and let m

Myo Kyaw Htun 22 Apr 24, 2022
A fully customizable, OTP (one-time-password) input component built with Vue 3.x and Vue Composition API.

vue-otp-input A fully customizable, OTP (one-time-password) input component built with Vue 3.x and Vue Composition API. Installation To install the la

Ejiro Asiuwhu 39 Sep 23, 2022
A Vue.js (>= 3.2) web component that wraps around an html input of type 'range' with label and styling options.

range-comp range-comp is Vue.js (>= 3.2) web component that wraps around an html input of type 'range' with label and styling options. range-comp can

null 0 May 9, 2022
A tags input component for Vue 3 with autocompletion, custom validation, templating and much more

vue-tags-input A tags input component for Vue 3 with autocompletion, custom validation, templating and much more Forked from @johmun/vue-tags-input, w

Sinclair Chen 16 Aug 31, 2022
Vue Fake input is a Vue.js based component to create custom inputs for individual characters.

Vue Fake Input Vue Fake input is a Vue.js based component to create custom inputs for individual characters. Table of Contents Installation Usage Lice

Cláudio Luiz Castro 84 Jul 26, 2022
Set of vue directives to add text restriction to your vue input

Vue-Input-Restriction-Directives Set of useful vue directives to add text restriction to your input No keyboard key validation, just regular expressio

Benjamin Arambide 5 Nov 19, 2021