mirror of
https://github.com/tenrok/maska.git
synced 2026-06-05 16:42:28 +03:00
Add dynamic mask
This commit is contained in:
@@ -5,7 +5,7 @@ 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
|
||||
- Supports repeat symbols and dynamic masks
|
||||
- Works on any input (custom or native)
|
||||
|
||||
## Install
|
||||
@@ -101,6 +101,24 @@ Default tokens:
|
||||
|
||||
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]"`).
|
||||
|
||||
## Dynamic masks
|
||||
|
||||
To use several masks on single input, pass array instead of string as mask value.
|
||||
|
||||
You could use it with Vue directives:
|
||||
|
||||
``` html
|
||||
<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:
|
||||
|
||||
``` html
|
||||
<input data-mask='["# cm", "#.# cm", "#.## cm"]'>
|
||||
```
|
||||
|
||||
## Source of Inspiration
|
||||
|
||||
- [vue-the-mask](https://vuejs-tips.github.io/vue-the-mask/)
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+16
-2
@@ -25,9 +25,9 @@
|
||||
<div class="field">
|
||||
<label class="label">Phone with code: {{ phone }}</label>
|
||||
<div class="control">
|
||||
<input v-maska="'+1 (###) ###-##-##'" class="input" type="tel" autocomplete="tel" v-model="phone">
|
||||
<input v-maska="['+1 (###) ##-##-##', '+1 (###) ###-##-##']" class="input" type="tel" autocomplete="tel" v-model="phone">
|
||||
</div>
|
||||
<p class="help is-family-code">v-maska="'+1 (###) ###-##-##'"</p>
|
||||
<p class="help is-family-code">v-maska="['+1 (###) ##-##-##', '+1 (###) ###-##-##']"</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Hex color (custom tokens): {{ color }}</label>
|
||||
@@ -65,6 +65,13 @@
|
||||
</div>
|
||||
<p class="help is-family-code">data-mask="#*"</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Dynamic mask</label>
|
||||
<div class="control">
|
||||
<input data-mask='["# cm", "#.# cm", "#.## cm"]' class="masked input">
|
||||
</div>
|
||||
<p class="help is-family-code">data-mask='["# cm", "#.# cm", "#.## cm"]'</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="field">
|
||||
@@ -88,6 +95,13 @@
|
||||
</div>
|
||||
<p class="help is-family-code">data-mask="###"</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">CPF/CNPJ</label>
|
||||
<div class="control">
|
||||
<input data-mask='["###.###.###-##", "##.###.###/####-##"]' class="masked input">
|
||||
</div>
|
||||
<p class="help is-family-code">data-mask='["###.###.###-##", "##.###.###/####-##"]'</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "maska",
|
||||
"version": "1.0.3",
|
||||
"version": "1.1.0",
|
||||
"description": "Simple zero-dependency input mask for Vue.js and vanilla JS",
|
||||
"keywords": [
|
||||
"mask",
|
||||
|
||||
+4
-4
@@ -4,11 +4,11 @@ import { isString } from './utils'
|
||||
function getOpts (mask) {
|
||||
const opts = {}
|
||||
|
||||
if (isString(mask)) {
|
||||
opts.mask = mask
|
||||
} else if (mask.mask) {
|
||||
opts.mask = mask.mask
|
||||
if (mask.mask) {
|
||||
opts.mask = Array.isArray(mask.mask) ? JSON.stringify(mask.mask) : mask.mask
|
||||
opts.tokens = mask.tokens ? { ...mask.tokens } : {}
|
||||
} else {
|
||||
opts.mask = Array.isArray(mask) ? JSON.stringify(mask) : mask
|
||||
}
|
||||
|
||||
return opts
|
||||
|
||||
+31
@@ -1,4 +1,35 @@
|
||||
export default function mask (value, mask, tokens, masked = true) {
|
||||
return (processMask(mask).length > 1)
|
||||
? dynamic(mask)(value, mask, tokens, masked)
|
||||
: process(value, mask, tokens, masked)
|
||||
}
|
||||
|
||||
function processMask (mask) {
|
||||
try {
|
||||
return JSON.parse(mask)
|
||||
} catch {
|
||||
return [mask]
|
||||
}
|
||||
}
|
||||
|
||||
function dynamic (mask) {
|
||||
const masks = processMask(mask).sort((a, b) => a.length - b.length)
|
||||
|
||||
return function (value, mask, tokens, masked = true) {
|
||||
let i = 0
|
||||
while (i < masks.length) {
|
||||
const currentMask = masks[i]
|
||||
i++
|
||||
const nextMask = masks[i]
|
||||
if (!(nextMask && process(value, nextMask, tokens, true).length > currentMask.length)) {
|
||||
return process(value, currentMask, tokens, masked)
|
||||
}
|
||||
}
|
||||
return '' // empty masks
|
||||
}
|
||||
}
|
||||
|
||||
function process (value, mask, tokens, masked = true) {
|
||||
let im = 0
|
||||
let iv = 0
|
||||
let ret = ''
|
||||
|
||||
@@ -109,3 +109,14 @@ test('123abc -> # (A*)', () => {
|
||||
test('Raw 123abc ##(A*)', () => {
|
||||
expect(mask('123abc', '##(A*)', tokens, false)).toBe('12ABC')
|
||||
})
|
||||
|
||||
test('Dynamic floats', () => {
|
||||
expect(mask('1', '["# cm", "#.# cm", "#.## cm"]', tokens)).toBe('1 cm')
|
||||
expect(mask('12', '["# cm", "#.# cm", "#.## cm"]', tokens)).toBe('1.2 cm')
|
||||
expect(mask('123', '["# cm", "#.# cm", "#.## cm"]', tokens)).toBe('1.23 cm')
|
||||
})
|
||||
|
||||
test('Dynamic CPF/CNPJ', () => {
|
||||
expect(mask('12345678901', '["###.###.###-##", "##.###.###/####-##"]', tokens)).toBe('123.456.789-01')
|
||||
expect(mask('12345678901234', '["###.###.###-##", "##.###.###/####-##"]', tokens)).toBe('12.345.678/9012-34')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user