Merge pull request #137 from dod-ccpo/ui/field-validation-setup
Ui/field validation setup
This commit is contained in:
commit
cda0b6301b
82
js/components/text_input.js
Normal file
82
js/components/text_input.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import MaskedInput, { conformToMask } from 'vue-text-mask'
|
||||||
|
import inputValidations from '../lib/input_validations'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'textinput',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
MaskedInput
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
name: String,
|
||||||
|
validation: {
|
||||||
|
type: String,
|
||||||
|
default: () => 'anything'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: () => ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
showError: false,
|
||||||
|
showValid: false,
|
||||||
|
mask: inputValidations[this.validation].mask,
|
||||||
|
renderedValue: this.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted: function () {
|
||||||
|
const value = this.$refs.input.value
|
||||||
|
if (value) {
|
||||||
|
this._checkIfValid({ value, invalidate: true })
|
||||||
|
this.renderedValue = conformToMask(value, this.mask).conformedValue
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
// When user types a character
|
||||||
|
onInput: function (value) {
|
||||||
|
this._checkIfValid({ value })
|
||||||
|
},
|
||||||
|
|
||||||
|
// When field is blurred (un-focused)
|
||||||
|
onChange: function (e) {
|
||||||
|
// Only invalidate the field when it blurs
|
||||||
|
this._checkIfValid({ value: e.target.value, invalidate: true })
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
_checkIfValid: function ({ value, invalidate = false}) {
|
||||||
|
// Validate the value
|
||||||
|
const valid = this._validate(value)
|
||||||
|
|
||||||
|
// Show error messages or not
|
||||||
|
if (valid) {
|
||||||
|
this.showError = false
|
||||||
|
} else if (invalidate) {
|
||||||
|
this.showError = true
|
||||||
|
}
|
||||||
|
this.showValid = valid
|
||||||
|
|
||||||
|
// Emit a change event
|
||||||
|
this.$emit('fieldChange', {
|
||||||
|
value,
|
||||||
|
valid,
|
||||||
|
name: this.name
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
_validate: function (value) {
|
||||||
|
// Strip out all the mask characters
|
||||||
|
let rawValue = inputValidations[this.validation].unmask.reduce((currentValue, character) => {
|
||||||
|
return currentValue.split(character).join('')
|
||||||
|
}, value)
|
||||||
|
|
||||||
|
return inputValidations[this.validation].match.test(rawValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,13 @@
|
|||||||
import classes from '../styles/atat.scss'
|
import classes from '../styles/atat.scss'
|
||||||
import Vue from 'vue/dist/vue'
|
import Vue from 'vue/dist/vue'
|
||||||
|
|
||||||
|
import textinput from './components/text_input'
|
||||||
|
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
el: '#app-root',
|
el: '#app-root',
|
||||||
|
components: {
|
||||||
|
textinput
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
closeModal: function(name) {
|
closeModal: function(name) {
|
||||||
this.modals[name] = false
|
this.modals[name] = false
|
||||||
|
20
js/lib/input_validations.js
Normal file
20
js/lib/input_validations.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import createNumberMask from 'text-mask-addons/dist/createNumberMask'
|
||||||
|
import emailMask from 'text-mask-addons/dist/emailMask'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
anything: {
|
||||||
|
mask: false,
|
||||||
|
match: /^(?!\s*$).+/,
|
||||||
|
unmask: [],
|
||||||
|
},
|
||||||
|
dollars: {
|
||||||
|
mask: createNumberMask({ prefix: '$', allowDecimal: true }),
|
||||||
|
match: /^-?\d+\.?\d*$/,
|
||||||
|
unmask: ['$',',']
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
mask: emailMask,
|
||||||
|
match: /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/,
|
||||||
|
unmask: [],
|
||||||
|
}
|
||||||
|
}
|
@ -13,8 +13,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"npm": "^6.0.1",
|
"npm": "^6.0.1",
|
||||||
"parcel": "^1.9.7",
|
"parcel": "^1.9.7",
|
||||||
|
"text-mask-addons": "^3.8.0",
|
||||||
"uswds": "^1.6.3",
|
"uswds": "^1.6.3",
|
||||||
"vue": "^2.5.17"
|
"vue": "^2.5.17",
|
||||||
|
"vue-text-mask": "^6.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"node-sass": "^4.9.2"
|
"node-sass": "^4.9.2"
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
<body class="{% if g.modalOpen %} modalOpen{% endif %}">
|
<body class="{% if g.modalOpen %} modalOpen{% endif %}">
|
||||||
|
|
||||||
<div id='app-root'>
|
<div id='app-root'>
|
||||||
|
|
||||||
{% block template_vars %}{% endblock %}
|
{% block template_vars %}{% endblock %}
|
||||||
|
|
||||||
{% include 'navigation/topbar.html' %}
|
{% include 'navigation/topbar.html' %}
|
||||||
@ -33,7 +34,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'footer.html' %}
|
{% include 'footer.html' %}
|
||||||
|
|
||||||
{% block modal %}{% endblock %}
|
{% block modal %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -130,15 +130,29 @@
|
|||||||
|
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<div class='usa-input'>
|
<textinput inline-template validation='dollars' value='1231231'>
|
||||||
|
<div v-bind:class="['usa-input usa-input--validation--' + validation, { 'usa-input--error': showError, 'usa-input--success': showValid }]">
|
||||||
<label for='basic-text-1'>
|
<label for='basic-text-1'>
|
||||||
Basic Text Input
|
Dollars Text Input
|
||||||
<span class='usa-input__help'>
|
<span class='usa-input__help'>
|
||||||
This is some help text to explain what this form field is and why you should fill it out.
|
This is some help text to explain what this form field is and why you should fill it out.
|
||||||
</span>
|
</span>
|
||||||
|
<template v-if='showError'>{{ Icon('alert') }}</template>
|
||||||
|
<template v-if='showValid'>{{ Icon('ok') }}</template>
|
||||||
</label>
|
</label>
|
||||||
<input id='basic-text-1' type='text' placeholder='this is a sample of what you should enter'/>
|
<masked-input
|
||||||
|
v-on:input='onInput'
|
||||||
|
v-on:change='onChange'
|
||||||
|
v-model='renderedValue'
|
||||||
|
id='basic-text-1'
|
||||||
|
type='text'
|
||||||
|
ref='input'
|
||||||
|
placeholder='$'
|
||||||
|
:guide="true"
|
||||||
|
:mask="mask">
|
||||||
|
</masked-input>
|
||||||
</div>
|
</div>
|
||||||
|
</textinput>
|
||||||
|
|
||||||
<div class='usa-input usa-input--error'>
|
<div class='usa-input usa-input--error'>
|
||||||
<label for='basic-text-2'>
|
<label for='basic-text-2'>
|
||||||
|
@ -6325,6 +6325,10 @@ terser@^3.7.3:
|
|||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
source-map-support "~0.5.6"
|
source-map-support "~0.5.6"
|
||||||
|
|
||||||
|
text-mask-addons@^3.8.0:
|
||||||
|
version "3.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/text-mask-addons/-/text-mask-addons-3.8.0.tgz#17b61ef665a4f36811f2ea1f01a223b4be61ab26"
|
||||||
|
|
||||||
text-table@~0.2.0:
|
text-table@~0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||||
@ -6675,6 +6679,10 @@ vm-browserify@0.0.4, vm-browserify@~0.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
indexof "0.0.1"
|
indexof "0.0.1"
|
||||||
|
|
||||||
|
vue-text-mask@^6.1.2:
|
||||||
|
version "6.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-text-mask/-/vue-text-mask-6.1.2.tgz#2cc18a1ca04ea66798518a9373929a12256d14b9"
|
||||||
|
|
||||||
vue@^2.5.17:
|
vue@^2.5.17:
|
||||||
version "2.5.17"
|
version "2.5.17"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.17.tgz#0f8789ad718be68ca1872629832ed533589c6ada"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user