commit
c5b237dd2b
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
@ -0,0 +1,59 @@
|
|||||||
|
# Tiny Validator
|
||||||
|
|
||||||
|
Created with [Riot.js](https://riot.js.org)
|
||||||
|
|
||||||
|
Validate Form or a Single Form-Field, Error Messages can be show just in time
|
||||||
|
or after Submit entire Form.
|
||||||
|
|
||||||
|
For Validation this Component uses [Validate.js](https://validatejs.org/)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install tiny-validator --save
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
```
|
||||||
|
<demo>
|
||||||
|
<form onsubmit={ (event) => { state.validator.handle(event) }} novalidate>
|
||||||
|
<div class="field">
|
||||||
|
<label>
|
||||||
|
email
|
||||||
|
<input type="email" name="email" onkeyup={ (event) => { state.validator.handle(event, 'email') }} />
|
||||||
|
</label>
|
||||||
|
<field-error errors={ state.validator.errors('email') } ></field-error>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>
|
||||||
|
password
|
||||||
|
<input type="password" name="email" onkeyup={ (event) => { state.validator.handle(event, 'password') }} />
|
||||||
|
</label>
|
||||||
|
<field-error errors={ state.validator.errors('password') } ></field-error>
|
||||||
|
</div>
|
||||||
|
<button type="submit">Send</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import Validator from './validator.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onBeforeMount() {
|
||||||
|
this.state.validator = new Validator({
|
||||||
|
name: {
|
||||||
|
presence: true
|
||||||
|
email: true
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
presence: true
|
||||||
|
}
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</demo>
|
||||||
|
```
|
||||||
|
|
||||||
|
![Demo](https://github.com/tentakelfabrik/tiny-validator/blob/master/demo.gif)
|
@ -0,0 +1,11 @@
|
|||||||
|
import * as riot from 'riot'
|
||||||
|
import Demo from './demo.riot'
|
||||||
|
|
||||||
|
import FieldError from './src/field-error.riot'
|
||||||
|
|
||||||
|
riot.register('field-error', FieldError)
|
||||||
|
riot.mount('field-error')
|
||||||
|
|
||||||
|
// let it rain
|
||||||
|
riot.register('demo', Demo)
|
||||||
|
riot.mount('demo')
|
@ -0,0 +1,37 @@
|
|||||||
|
<demo>
|
||||||
|
<form onsubmit={ (event) => { state.validator.handle(event) }} novalidate>
|
||||||
|
<div class="field">
|
||||||
|
<label>
|
||||||
|
email
|
||||||
|
<input type="email" name="email" onkeyup={ (event) => { state.validator.handle(event, 'email') }} />
|
||||||
|
</label>
|
||||||
|
<field-error errors={ state.validator.errors('email') } ></field-error>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>
|
||||||
|
password
|
||||||
|
<input type="password" name="email" onkeyup={ (event) => { state.validator.handle(event, 'password') }} />
|
||||||
|
</label>
|
||||||
|
<field-error errors={ state.validator.errors('password') } ></field-error>
|
||||||
|
</div>
|
||||||
|
<button type="submit">Send</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Validator from './src/validator'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onBeforeMount() {
|
||||||
|
this.state.validator = new Validator({
|
||||||
|
name: {
|
||||||
|
presence: true,
|
||||||
|
email: true
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
presence: true
|
||||||
|
}
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</demo>
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Demo | Tiny Validator</title>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
|
||||||
|
<link href="css/styles.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<demo></demo>
|
||||||
|
<script type="text/javascript" src="js/demo.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"/dist/js/demo.js": "/dist/js/demo.js"
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "tiny-validator",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Form Validator with validator.js for riotjs",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "npm run development",
|
||||||
|
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
|
"watch": "npm run development -- --watch",
|
||||||
|
"watch-poll": "npm run watch -- --watch-poll",
|
||||||
|
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
|
"prod": "npm run production",
|
||||||
|
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"form-serialize": "^0.7.2",
|
||||||
|
"riot": "^5.1.2",
|
||||||
|
"validate.js": "^0.13.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@riotjs/compiler": "^5.1.3",
|
||||||
|
"@riotjs/webpack-loader": "^5.0.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"laravel-mix": "^6.0.5",
|
||||||
|
"postcss": "^8.2.1"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
node_modules
|
||||||
|
fonts
|
@ -0,0 +1,42 @@
|
|||||||
|
<field-error>
|
||||||
|
<div class="field__error" if={ state.errors.length > 0 }>
|
||||||
|
<ul>
|
||||||
|
<li each={ error in state.errors }>{ error }</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows errors of Validation
|
||||||
|
*
|
||||||
|
* <field-error key="name" errors={ errors }></field-error>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
state: {
|
||||||
|
errors: [
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if errors from props has an error, if not reset errors in state
|
||||||
|
*
|
||||||
|
* @param {object} props
|
||||||
|
* @param {object} state
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
onBeforeUpdate(props, state) {
|
||||||
|
if (props.errors && props.errors.length > 0) {
|
||||||
|
state.errors = props.errors
|
||||||
|
} else {
|
||||||
|
state.errors = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</field-error>
|
@ -0,0 +1,92 @@
|
|||||||
|
import validate from 'validate.js'
|
||||||
|
import serialize from 'form-serialize'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate entire Form or a single Element
|
||||||
|
*
|
||||||
|
* Using validator.js
|
||||||
|
*
|
||||||
|
* @author Björn Hase, Tentakelfabrik, me@tentakelfabrik.de
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Validator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {array} rules
|
||||||
|
*/
|
||||||
|
constructor(rules, component) {
|
||||||
|
this._rules = rules
|
||||||
|
this._component = component
|
||||||
|
|
||||||
|
this._errors = {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle validation
|
||||||
|
*
|
||||||
|
* if key not set,
|
||||||
|
*
|
||||||
|
* @param {object} event
|
||||||
|
* @param {object} key
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
handle(event, key) {
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
let data = null, rules, errors
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
if (event.target.value) {
|
||||||
|
data = event.target.value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data = serialize(event.target, {
|
||||||
|
hash: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate single
|
||||||
|
if (key) {
|
||||||
|
rules = this._rules[key]
|
||||||
|
|
||||||
|
errors = validate.single(data, rules, {
|
||||||
|
flat: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (errors) {
|
||||||
|
this._errors[key] = errors
|
||||||
|
} else {
|
||||||
|
delete this._errors[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate entire form
|
||||||
|
} else {
|
||||||
|
this._errors = validate(data, this._rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update component
|
||||||
|
this._component.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {[type]} key
|
||||||
|
* @return {[type]}
|
||||||
|
*/
|
||||||
|
errors(key) {
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
return this._errors[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._errors
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Validator
|
@ -0,0 +1,35 @@
|
|||||||
|
const mix = require('laravel-mix');
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Mix Asset Management
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Mix provides a clean, fluent API for defining some Webpack build steps
|
||||||
|
| for your Laravel application. By default, we are compiling the Sass
|
||||||
|
| file for your application, as well as bundling up your JS files.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
mix.webpackConfig({
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: /\.riot$/,
|
||||||
|
exclude: '/node_modules/',
|
||||||
|
use: [{
|
||||||
|
loader: '@riotjs/webpack-loader',
|
||||||
|
options: {
|
||||||
|
hot: false
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
mix.js('demo.js', 'dist/js')
|
||||||
|
.options({
|
||||||
|
terser: {
|
||||||
|
extractComments: false,
|
||||||
|
},
|
||||||
|
processCssUrls: false
|
||||||
|
})
|
Loading…
Reference in new issue