Compare commits

..

No commits in common. 'main' and 'feature/field-error' have entirely different histories.

@ -1,4 +1,4 @@
# Tiny Components - Validator
# Tiny Validator
Created with [Riot.js](https://riot.js.org)
@ -10,13 +10,13 @@ For Validation this Component uses [Validate.js](https://validatejs.org/)
## Install
```bash
npm install @tiny-components/validator --save
npm install tiny-validator --save
```
## You can use it like this
## How to use
```javascript
<form class="form" onsubmit={ (event) => ( state.validator.submit(event) ) }>>
<form onsubmit={ (event) => { state.validator.handle(event) }} novalidate>
<div class="field">
<label>
email
@ -38,51 +38,17 @@ npm install @tiny-components/validator --save
import Validator from './validator.js'
export default {
state: {
validator: { }
},
onBeforeMount() {
// creating formValidator
this.state.validator = new FormValidator(this.$('.form'), {
'email': {
'presence': true,
'email': true
this.state.validator = new Validator({
email: {
presence: true
email: true
},
'password': {
'presence': true
password: {
presence: true
}
})
// adding on success
this.state.validator.onSuccess((event, data) => {
this.handleSuccess(event, data)
})
// adding on error
this.state.validator.onError((event, errors, data) => {
this.handleError(event, errors, data)
})
},
/**
*
*/
handleSuccess(event, data)
{
event.preventDefault()
this.update()
},
/**
*
*/
handleError(event, errors, data)
{
this.update()
}, this)
}
}
</script>
```

@ -0,0 +1 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}

File diff suppressed because one or more lines are too long

@ -0,0 +1,29 @@
<!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="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<form class="form" novalidate>
<div class="field">
<label>
email
<input type="email" name="email" />
</label>
<field-error name="email"></field-error>
</div>
<div class="field">
<label>
password
<input type="password" name="password" />
</label>
<field-error name="password"></field-error>
</div>
<button type="submit">Send</button>
</form>
<script type="text/javascript" src="demo.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,85 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tiny Components | Validator</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link href="/example.css" rel="stylesheet" type="text/css">
</head>
<body>
<header class="header">
<div class="bar">
<div class="bar__start">
<h1 class="m-top-4 m-bottom-4 h4">
@tiny-components/validator
</h1>
</div>
<div class="bar__main justify-end">
<a class="button button--small m-left-sm-3 m-bottom-0" href="https://gitea.node001.net/tiny-components/validator" rel="noopener" target="_blank">
Gitea
<svg class="m-left-3 icon fill-text" aria-hidden="true">
<use xlink:href="symbol-defs.svg#icon-gitea"></use>
</svg>
</a>
</div>
</div>
</header>
<div class="container">
<div class="grid">
<div class="col-12">
<h2>
Form
</h2>
<form class="form-html" novalidate method="post">
<div class="field-group">
<label class="field-label">
email
<input type="email" class="field-text" name="email" />
</label>
<field-error name="email"></field-error>
</div>
<div class="field-group">
<label class="field-label">
password
<input type="password" class="field-text" name="password" />
</label>
<field-error name="password"></field-error>
</div>
<button class="button" type="submit">
Send
</button>
</form>
<div id="result" class="panel color-text-contrast background-color-success hidden">
<div class="panel__body">
<div class="content m-bottom-last-child-0">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="grid">
<div class="col-12">
<h2>
Form - Inside a Riot Component
</h2>
<form-component></form-component>
</div>
</div>
</div>
<script type="text/javascript" src="/example.js"></script>
</body>
</html>

@ -1,4 +1,4 @@
{
"/example/example.js": "/example/example.js",
"/example/example.css": "/example/example.css"
"/demo/demo.js": "/demo/demo.js",
"/demo/demo.css": "/demo/demo.css"
}

390
package-lock.json generated

@ -1,27 +1,26 @@
{
"name": "@tiny-components/validator",
"version": "0.2.0",
"name": "@tentakelfabrik/tiny-validator",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@tiny-components/validator",
"version": "0.2.0",
"name": "@tentakelfabrik/tiny-validator",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@tiny-components/plain-ui": "^0.5.0",
"form-serialize": "^0.7.2",
"riot": "^6.1.2",
"riot": "^5.1.2",
"validate.js": "^0.13.1"
},
"devDependencies": {
"@riotjs/compiler": "^6.1.3",
"@riotjs/webpack-loader": "^6.0.0",
"@riotjs/compiler": "^5.1.3",
"@riotjs/webpack-loader": "^5.0.0",
"cross-env": "^7.0.3",
"laravel-mix": "^6.0.5",
"postcss": "^8.4.12",
"postcss": "^8.2.1",
"sass": "^1.32.0",
"sass-loader": "^12.4.0"
"sass-loader": "^8.0.2"
}
},
"node_modules/@babel/code-frame": {
@ -358,9 +357,10 @@
}
},
"node_modules/@babel/parser": {
"version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz",
"integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg==",
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
"integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
},
@ -1125,28 +1125,28 @@
}
},
"node_modules/@riotjs/compiler": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/@riotjs/compiler/-/compiler-6.1.3.tgz",
"integrity": "sha512-88974LTsuEOXQ07l9tJctyGtaLXy9LCcuiMbxJ0sEdQAS0OYP9SefBnW2a/7oWqrt5HQBxeOQ5zpSdSbs1LJeA==",
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/@riotjs/compiler/-/compiler-5.1.3.tgz",
"integrity": "sha512-YPOgwqpzs7LeA9JZV2qK2qW6o1iQ+6XEpqTopIC2V21hMwA4/9onGFOIzHf0MF0SX0NLzaou1zD6wY5w+G/+ug==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@riotjs/parser": "^4.3.1",
"@riotjs/util": "2.0.4",
"@riotjs/util": "2.0.0",
"acorn": "^8.0.4",
"cssesc": "^3.0.0",
"cumpa": "^1.0.1",
"curri": "^1.0.1",
"dom-nodes": "^1.1.3",
"globals": "^13.12.0",
"recast": "^0.20.5",
"globals": "^13.3.0",
"recast": "^0.20.4",
"source-map": "^0.7.3"
}
},
"node_modules/@riotjs/dom-bindings": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@riotjs/dom-bindings/-/dom-bindings-6.0.3.tgz",
"integrity": "sha512-ajBgXquwkj8ZaGDhGWJc8n74dCZxvxzoE2hT26T+aAfHVAz5Nhk6jWjmggZ42nN4AX9CQJUMEGY9KJeHDj1ABg==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@riotjs/dom-bindings/-/dom-bindings-5.0.1.tgz",
"integrity": "sha512-YDlGYnlZZc7aAhJ+GffyMxyDeR78U7yaKo+NDuoIL2pAceY3KYWXwmZS/3KdjenARxo0h/xZRvJrv77+jkx5Jw==",
"dependencies": {
"@riotjs/util": "^2.0.4"
"@riotjs/util": "^2.0.0"
}
},
"node_modules/@riotjs/parser": {
@ -1163,20 +1163,17 @@
}
},
"node_modules/@riotjs/util": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@riotjs/util/-/util-2.0.4.tgz",
"integrity": "sha512-C+YpN8p30T1+qtuPaHS2uobRHG+EpQhtXsu+Ul7sOStb1PnqptXut2YHSffQ6Xlu+FoOlP/BcMu+RVYvzWPmkg=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/util/-/util-2.0.0.tgz",
"integrity": "sha512-+FtbujwoRT/Gi2/tarL0I30GIBCFFLUGtuhEJbosT09cUcP839oML871Yc7w5Zxb/IHFV1GS0p1ZGWe3JeeEjw=="
},
"node_modules/@riotjs/webpack-loader": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/webpack-loader/-/webpack-loader-6.0.0.tgz",
"integrity": "sha512-ktmbHSexRKPK7QEymAPJq3v/S6aQcmfB0OX2p8zUoKYKlfzEYmdCRjAg4vo9Xw82r4ueYDW5GIdMvoLGWqovIA==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/webpack-loader/-/webpack-loader-5.0.0.tgz",
"integrity": "sha512-Bko2jXcXY5YyfE41P/7HvMxpN8oa/oyaYWMVKmGzldHjVPmCD3VLhnh7YK3VMG04cdxIEHuBag8/WWsqAg1LRQ==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0"
},
"peerDependencies": {
"@riotjs/compiler": "^6.0.0"
}
},
"node_modules/@riotjs/webpack-loader/node_modules/loader-utils": {
@ -1193,14 +1190,6 @@
"node": ">=8.9.0"
}
},
"node_modules/@tiny-components/plain-ui": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@tiny-components/plain-ui/-/plain-ui-0.5.0.tgz",
"integrity": "sha512-he2chVLtq3KV7yWgFIfPKi5UuHEwmNyoegpjKSByYWHK+/3fH/kK+0UCmmiJd6ZbuvBTaJKtYikpJYZhkVfaFQ==",
"dependencies": {
"normalize.css": "^8.0.1"
}
},
"node_modules/@types/autoprefixer": {
"version": "9.7.2",
"resolved": "https://registry.npmjs.org/@types/autoprefixer/-/autoprefixer-9.7.2.tgz",
@ -1840,7 +1829,6 @@
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz",
"integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
@ -3597,6 +3585,20 @@
"node": ">=8.9.0"
}
},
"node_modules/css-loader/node_modules/postcss": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.1.tgz",
"integrity": "sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==",
"dev": true,
"dependencies": {
"colorette": "^1.2.1",
"nanoid": "^3.1.20",
"source-map": "^0.6.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/css-loader/node_modules/schema-utils": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
@ -3626,6 +3628,15 @@
"node": ">=10"
}
},
"node_modules/css-loader/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/css-select": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
@ -5378,17 +5389,14 @@
"dev": true
},
"node_modules/globals": {
"version": "13.13.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.5.0.tgz",
"integrity": "sha512-TMJe2Iu/qCIEFnG7IQ62C9N/iKdgX5wSvmGOVuk75+UAGDW+Yv/hH5+Ky6d/8UMqo4WCzhFCy+pHsvv09zhBoQ==",
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globby": {
@ -7239,9 +7247,9 @@
"optional": true
},
"node_modules/nanoid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz",
"integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==",
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
@ -7414,11 +7422,6 @@
"node": ">=6"
}
},
"node_modules/normalize.css": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
"integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
},
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@ -7959,12 +7962,6 @@
"node": ">=0.12"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@ -8019,24 +8016,14 @@
}
},
"node_modules/postcss": {
"version": "8.4.12",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
}
],
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.1.tgz",
"integrity": "sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==",
"dev": true,
"dependencies": {
"nanoid": "^3.3.1",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
"colorette": "^1.2.1",
"nanoid": "^3.1.20",
"source-map": "^0.6.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@ -10444,6 +10431,15 @@
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
"dev": true
},
"node_modules/postcss/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@ -10636,9 +10632,9 @@
}
},
"node_modules/recast": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz",
"integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==",
"version": "0.20.4",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.20.4.tgz",
"integrity": "sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ==",
"dependencies": {
"ast-types": "0.14.2",
"esprima": "~4.0.0",
@ -10959,13 +10955,13 @@
}
},
"node_modules/riot": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/riot/-/riot-6.1.2.tgz",
"integrity": "sha512-JYGKN6D2FwNP+eH2suh13jhQPXnaAeXdwCIWH0vz2UvhLBY9mTFZv6/dPAyEluHTf9bjAJOriFc4PDXox5Fjqw==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/riot/-/riot-5.1.2.tgz",
"integrity": "sha512-6ztxtDt/Vl78Qzm0N370sqU+wVSmqVKzCOMPKTxObqXvCGTi+qnzLe7aPIfZPPWYwr7O5gA8Lt396MIR3SKxcA==",
"dependencies": {
"@riotjs/compiler": "^6.1.3",
"@riotjs/dom-bindings": "6.0.3",
"@riotjs/util": "^2.0.4",
"@riotjs/compiler": "^5.1.3",
"@riotjs/dom-bindings": "5.0.1",
"@riotjs/util": "^2.0.0",
"bianco.attr": "^1.0.0",
"bianco.query": "^1.0.0",
"cumpa": "^1.0.1",
@ -11028,41 +11024,28 @@
}
},
"node_modules/sass-loader": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz",
"integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==",
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
"integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
"dev": true,
"dependencies": {
"klona": "^2.0.4",
"neo-async": "^2.6.2"
"clone-deep": "^4.0.1",
"loader-utils": "^1.2.3",
"neo-async": "^2.6.1",
"schema-utils": "^2.6.1",
"semver": "^6.3.0"
},
"engines": {
"node": ">= 12.13.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"fibers": ">= 3.1.0",
"node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
"sass": "^1.3.0",
"sass-embedded": "*",
"webpack": "^5.0.0"
},
"peerDependenciesMeta": {
"fibers": {
"optional": true
},
"node-sass": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
}
"node": ">= 8.9.0"
}
},
"node_modules/sass-loader/node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/sax": {
@ -11562,15 +11545,6 @@
"node": ">= 8"
}
},
"node_modules/source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-resolve": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@ -12197,9 +12171,6 @@
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/type-is": {
@ -13406,9 +13377,10 @@
}
},
"@babel/parser": {
"version": "7.17.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz",
"integrity": "sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg=="
"version": "7.12.11",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
"integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==",
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.12.12",
@ -14153,28 +14125,28 @@
}
},
"@riotjs/compiler": {
"version": "6.1.3",
"resolved": "https://registry.npmjs.org/@riotjs/compiler/-/compiler-6.1.3.tgz",
"integrity": "sha512-88974LTsuEOXQ07l9tJctyGtaLXy9LCcuiMbxJ0sEdQAS0OYP9SefBnW2a/7oWqrt5HQBxeOQ5zpSdSbs1LJeA==",
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/@riotjs/compiler/-/compiler-5.1.3.tgz",
"integrity": "sha512-YPOgwqpzs7LeA9JZV2qK2qW6o1iQ+6XEpqTopIC2V21hMwA4/9onGFOIzHf0MF0SX0NLzaou1zD6wY5w+G/+ug==",
"requires": {
"@babel/parser": "^7.16.4",
"@riotjs/parser": "^4.3.1",
"@riotjs/util": "2.0.4",
"@riotjs/util": "2.0.0",
"acorn": "^8.0.4",
"cssesc": "^3.0.0",
"cumpa": "^1.0.1",
"curri": "^1.0.1",
"dom-nodes": "^1.1.3",
"globals": "^13.12.0",
"recast": "^0.20.5",
"globals": "^13.3.0",
"recast": "^0.20.4",
"source-map": "^0.7.3"
}
},
"@riotjs/dom-bindings": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@riotjs/dom-bindings/-/dom-bindings-6.0.3.tgz",
"integrity": "sha512-ajBgXquwkj8ZaGDhGWJc8n74dCZxvxzoE2hT26T+aAfHVAz5Nhk6jWjmggZ42nN4AX9CQJUMEGY9KJeHDj1ABg==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@riotjs/dom-bindings/-/dom-bindings-5.0.1.tgz",
"integrity": "sha512-YDlGYnlZZc7aAhJ+GffyMxyDeR78U7yaKo+NDuoIL2pAceY3KYWXwmZS/3KdjenARxo0h/xZRvJrv77+jkx5Jw==",
"requires": {
"@riotjs/util": "^2.0.4"
"@riotjs/util": "^2.0.0"
}
},
"@riotjs/parser": {
@ -14187,14 +14159,14 @@
}
},
"@riotjs/util": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@riotjs/util/-/util-2.0.4.tgz",
"integrity": "sha512-C+YpN8p30T1+qtuPaHS2uobRHG+EpQhtXsu+Ul7sOStb1PnqptXut2YHSffQ6Xlu+FoOlP/BcMu+RVYvzWPmkg=="
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/util/-/util-2.0.0.tgz",
"integrity": "sha512-+FtbujwoRT/Gi2/tarL0I30GIBCFFLUGtuhEJbosT09cUcP839oML871Yc7w5Zxb/IHFV1GS0p1ZGWe3JeeEjw=="
},
"@riotjs/webpack-loader": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/webpack-loader/-/webpack-loader-6.0.0.tgz",
"integrity": "sha512-ktmbHSexRKPK7QEymAPJq3v/S6aQcmfB0OX2p8zUoKYKlfzEYmdCRjAg4vo9Xw82r4ueYDW5GIdMvoLGWqovIA==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@riotjs/webpack-loader/-/webpack-loader-5.0.0.tgz",
"integrity": "sha512-Bko2jXcXY5YyfE41P/7HvMxpN8oa/oyaYWMVKmGzldHjVPmCD3VLhnh7YK3VMG04cdxIEHuBag8/WWsqAg1LRQ==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0"
@ -14213,14 +14185,6 @@
}
}
},
"@tiny-components/plain-ui": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@tiny-components/plain-ui/-/plain-ui-0.5.0.tgz",
"integrity": "sha512-he2chVLtq3KV7yWgFIfPKi5UuHEwmNyoegpjKSByYWHK+/3fH/kK+0UCmmiJd6ZbuvBTaJKtYikpJYZhkVfaFQ==",
"requires": {
"normalize.css": "^8.0.1"
}
},
"@types/autoprefixer": {
"version": "9.7.2",
"resolved": "https://registry.npmjs.org/@types/autoprefixer/-/autoprefixer-9.7.2.tgz",
@ -14833,8 +14797,7 @@
"acorn": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz",
"integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==",
"dev": true
"integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ=="
},
"aggregate-error": {
"version": "3.1.0",
@ -16318,6 +16281,17 @@
"json5": "^2.1.2"
}
},
"postcss": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.1.tgz",
"integrity": "sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==",
"dev": true,
"requires": {
"colorette": "^1.2.1",
"nanoid": "^3.1.20",
"source-map": "^0.6.1"
}
},
"schema-utils": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
@ -16337,6 +16311,12 @@
"requires": {
"lru-cache": "^6.0.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
@ -17801,9 +17781,9 @@
"dev": true
},
"globals": {
"version": "13.13.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.5.0.tgz",
"integrity": "sha512-TMJe2Iu/qCIEFnG7IQ62C9N/iKdgX5wSvmGOVuk75+UAGDW+Yv/hH5+Ky6d/8UMqo4WCzhFCy+pHsvv09zhBoQ==",
"requires": {
"type-fest": "^0.20.2"
}
@ -19323,9 +19303,9 @@
"optional": true
},
"nanoid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.2.tgz",
"integrity": "sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==",
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
"dev": true
},
"nanomatch": {
@ -19469,11 +19449,6 @@
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
"dev": true
},
"normalize.css": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
"integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
},
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@ -19906,12 +19881,6 @@
"sha.js": "^2.4.8"
}
},
"picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@ -19956,14 +19925,22 @@
"dev": true
},
"postcss": {
"version": "8.4.12",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.1.tgz",
"integrity": "sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==",
"dev": true,
"requires": {
"nanoid": "^3.3.1",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
"colorette": "^1.2.1",
"nanoid": "^3.1.20",
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"postcss-calc": {
@ -22096,9 +22073,9 @@
}
},
"recast": {
"version": "0.20.5",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.20.5.tgz",
"integrity": "sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==",
"version": "0.20.4",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.20.4.tgz",
"integrity": "sha512-6qLIBGGRcwjrTZGIiBpJVC/NeuXpogXNyRQpqU1zWPUigCphvApoCs9KIwDYh1eDuJ6dAFlQoi/QUyE5KQ6RBQ==",
"requires": {
"ast-types": "0.14.2",
"esprima": "~4.0.0",
@ -22357,13 +22334,13 @@
}
},
"riot": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/riot/-/riot-6.1.2.tgz",
"integrity": "sha512-JYGKN6D2FwNP+eH2suh13jhQPXnaAeXdwCIWH0vz2UvhLBY9mTFZv6/dPAyEluHTf9bjAJOriFc4PDXox5Fjqw==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/riot/-/riot-5.1.2.tgz",
"integrity": "sha512-6ztxtDt/Vl78Qzm0N370sqU+wVSmqVKzCOMPKTxObqXvCGTi+qnzLe7aPIfZPPWYwr7O5gA8Lt396MIR3SKxcA==",
"requires": {
"@riotjs/compiler": "^6.1.3",
"@riotjs/dom-bindings": "6.0.3",
"@riotjs/util": "^2.0.4",
"@riotjs/compiler": "^5.1.3",
"@riotjs/dom-bindings": "5.0.1",
"@riotjs/util": "^2.0.0",
"bianco.attr": "^1.0.0",
"bianco.query": "^1.0.0",
"cumpa": "^1.0.1",
@ -22417,13 +22394,24 @@
}
},
"sass-loader": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz",
"integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==",
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
"integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
"dev": true,
"requires": {
"klona": "^2.0.4",
"neo-async": "^2.6.2"
"clone-deep": "^4.0.1",
"loader-utils": "^1.2.3",
"neo-async": "^2.6.1",
"schema-utils": "^2.6.1",
"semver": "^6.3.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"sax": {
@ -22866,12 +22854,6 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
},
"source-map-js": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true
},
"source-map-resolve": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",

@ -1,26 +1,25 @@
{
"name": "@tiny-components/validator",
"version": "0.2.0",
"description": "Form Validation with Riotjs",
"name": "@tentakelfabrik/tiny-validator",
"version": "1.0.0",
"description": "Form Validator with validator.js for riotjs",
"repository": {
"type": "git",
"url": "git@github.com:node001-net/tiny-components-validator.git"
"url": "git@github.com:tentakelfabrik/tiny-validator.git"
},
"author": "Björn Hase",
"license": "MIT",
"dependencies": {
"@tiny-components/plain-ui": "^0.5.0",
"form-serialize": "^0.7.2",
"riot": "^6.1.2",
"riot": "^5.1.2",
"validate.js": "^0.13.1"
},
"devDependencies": {
"@riotjs/compiler": "^6.1.3",
"@riotjs/webpack-loader": "^6.0.0",
"@riotjs/compiler": "^5.1.3",
"@riotjs/webpack-loader": "^5.0.0",
"cross-env": "^7.0.3",
"laravel-mix": "^6.0.5",
"postcss": "^8.4.12",
"postcss": "^8.2.1",
"sass": "^1.32.0",
"sass-loader": "^12.4.0"
"sass-loader": "^8.0.2"
}
}
}

@ -0,0 +1,117 @@
import validate from 'validate.js'
import serialize from 'form-serialize'
/**
* Form Validator with RiotJS Components
*
*
*
*
*/
class FormValidator
{
/**
*
* @param {[type]} formSelector [description]
* @param {[type]} constraits [description]
*/
constructor(formSelector, constraits)
{
// getting selector to find form-element
this.formSelector = formSelector
// constraits for validate.js
this.constraits = constraits
// get form and elements
this.form = document.querySelector(this.formSelector)
this.elements = this.form.querySelectorAll('field-error')
// adding submit event
this.form.addEventListener('submit', (event) => {
this.onSubmit(event)
})
// adding event if a element is updated
this.form.addEventListener('field-update', (event) => {
this.onFieldUpdate(event)
})
}
/**
*
* @param {[type]} event [description]
* @return {[type]} [description]
*/
onSubmit(event)
{
let errors = validate(serialize(event.target, {
hash: true
}), this.constraits, {
fullMessages: false
})
if (errors) {
event.preventDefault()
// send each element a event
this.elements.forEach((element) => {
let elementErrors = false
// check for errors by name
if (errors[element.attributes.name.nodeValue]) {
elementErrors = errors[element.attributes.name.nodeValue]
}
this.dispatchCustomEvent(elementErrors, element)
})
}
}
/**
*
*
* @param {Event} event
*
*/
onFieldUpdate(event)
{
// workaround, make sure that value for single is undefined if it is empty
if (event.detail.value == '') {
event.detail.value = undefined
}
let errors = validate.single(event.detail.value, this.constraits[event.detail.name])
// search for element by name and dispatch event
this.elements.forEach((element) => {
if (element.attributes.name.nodeValue == event.detail.name) {
this.dispatchCustomEvent(errors, element)
}
})
}
/**
* dispatch event to single element
*
* @param {Array} errors
* @param {Element} element
*
*/
dispatchCustomEvent(errors, element)
{
let detail = false
if (errors) {
detail = errors
}
const formValidationEvent = new CustomEvent('form-validation', {
'detail': detail
})
element.dispatchEvent(formValidationEvent)
}
}
export default FormValidator

@ -0,0 +1,17 @@
import * as riot from 'riot'
import FormValidator from './../FormValidator'
import FieldError from './../field-error.riot'
riot.register('field-error', FieldError)
riot.mount('field-error')
const formValidation = new FormValidator('form', {
'email': {
'presence': true,
'email': true
},
'password': {
'presence': true
}
})

@ -0,0 +1,6 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
/*# sourceMappingURL=normalize.min.css.map */
body {
}

@ -1,31 +0,0 @@
import * as riot from 'riot'
import FormValidator from './formValidator'
import FieldError from './fieldError.riot'
import FormComponent from './formComponent.riot'
// register & mount riot component
riot.register('field-error', FieldError)
riot.mount('field-error')
// creating formValidation
const formValidation = new FormValidator(document.querySelector('.form-html'), {
'email': {
'presence': true,
'email': true
},
'password': {
'presence': true
}
}, true)
formValidation.onSuccess((event, data) => {
event.preventDefault()
// show message and content of data from form
document.querySelector('#result .content').innerHTML = '<p>' + JSON.stringify(data) + '</p>'
document.querySelector('#result').classList.remove('hidden')
})
riot.register('form-component', FormComponent)
riot.mount('form-component')

@ -1,6 +0,0 @@
@import
'../node_modules/@tiny-components/plain-ui/src/scss/plain-ui';
.hidden {
display: none;
}

@ -1,5 +1,5 @@
<field-error>
<div class="field-error" if={ state.errors.length > 0 }>
<div class="field__error" if={ state.errors.length > 0 }>
<ul>
<li each={ error in state.errors }>
{ error }
@ -9,13 +9,12 @@
<script>
/**
*
* Shows errors of Validation and raise a element to
* trigger single validation of field
*
* <field-error name="name" closest="<optional>" nofieldupdate></field-error>
* <field-error name="name" nofieldupdate></field-error>
*
* @author Björn Hase, me@herr-hase.wtf
* @author Björn Hase, Tentakelfabrik, me@tentakelfabrik.de
*
*/
@ -25,39 +24,22 @@
errors: [
],
// css class for
closest: '.field-group',
},
/**
*
*
* @param {Object} props
* @param {Object} state
*
*/
onBeforeMounted(props, state)
{
if (props.closest) {
state.closest = props.closest
}
},
/**
*
*
* @param {Object} props
* @param {Object} state
* @param {Object} props [description]
* @param {Object} state [description]
*
*/
onMounted(props, state)
{
// getting parent element for entire field
const parent = this.root.closest(state.closest)
const parent = this.root.closest('.field')
// getting current element by name
const element = parent.querySelector('[name="' + props.name + '"]')
const element = document.querySelector('[name="' + props.name + '"]')
// getting form
const form = element.closest('form')

@ -1,108 +0,0 @@
<form-component>
<div>
<form class="form" novalidate method="post" onsubmit={ (event) => ( state.validator.submit(event) ) }>
<div class="field-group">
<label class="field-label">
email
<input type="email" class="field-text" name="email" />
</label>
<field-error name="email"></field-error>
</div>
<div class="field-group">
<label class="field-label">
password
<input type="password" class="field-text" name="password" />
</label>
<field-error name="password"></field-error>
</div>
<button class="button" type="submit">
Send
</button>
</form>
<div class="loading" if={ state.isLoading }>
<span></span>
<span></span>
<span></span>
</div>
<div if={ state.result } class="panel color-text-contrast { state.class }">
<div class="panel__body">
<div class="content m-bottom-last-child-0">
{ state.result }
</div>
</div>
</div>
</div>
<script>
import * as riot from 'riot'
import FormValidator from './formValidator.js'
export default {
state:
{
result: undefined,
validator: undefined,
class: undefined
},
onMounted()
{
// creating formValidator
this.state.validator = new FormValidator(this.$('.form'), {
'email': {
'presence': true,
'email': true
},
'password': {
'presence': true
}
})
// adding on success
this.state.validator.onSuccess((event, data) => {
this.handleSuccess(event, data)
})
// adding on error
this.state.validator.onError((event, errors, data) => {
this.handleError(event, errors, data)
})
},
/**
*
* @param {object} event
* @param {array} data
*
*/
handleSuccess(event, data)
{
event.preventDefault()
this.state.class = 'background-color-success'
this.state.result = JSON.stringify(data)
this.update()
},
/**
*
*
* @param {object} event
* @param {array} errors
* @param {array} data
*
*/
handleError(event, errors, data)
{
this.state.class = 'background-color-danger'
this.state.result = JSON.stringify(errors)
this.update()
}
}
</script>
</form-component>

@ -1,189 +0,0 @@
import validate from 'validate.js'
import serialize from 'form-serialize'
/**
* Form Validator with RiotJS Components
*
*
* @author HerrHase
*
*/
class FormValidator
{
/**
*
* @param {[type]} formSelector [description]
* @param {[type]} constraits [description]
*/
constructor(formElement, constraits, addSubmitEvent = false)
{
// constraits for validate.js
this.constraits = constraits
// get form and elements
this.formElement = formElement
// if form not found
if (!this.formElement) {
console.error('FormValidator: form not found!')
}
this.elements = this.formElement.querySelectorAll('field-error')
// adding event if a element is updated
this.formElement.addEventListener('field-update', (event) => {
this._onFieldUpdate(event)
})
// adding submit event
if (addSubmitEvent) {
this.formElement.addEventListener('submit', (event) => {
this._onSubmit(event)
})
}
}
/**
* trigger submit
*
* @param {object} event
*
*/
submit(event)
{
this._onSubmit(event)
}
/**
*
* @param {function} onError
*
*/
onError(onError)
{
this._onError = onError
}
/**
* settin onSuccess callback and add submit-event on form
*
* @param {function} onSuccess
*
*/
onSuccess(onSuccess)
{
// adding onSuccess
this._onSuccess = onSuccess
}
/**
*
* @param {function} onError
*
*/
onBeforeSubmit(onBeforeSubmit)
{
this._onBeforeSubmit = onBeforeSubmit
}
/**
* handle submit
*
*
* @param {Event} event
*
*/
_onSubmit(event)
{
// getting data from target of submit event
const data = serialize(event.target, {
hash: true
})
// options for validate.js
const options = {
fullMessages: false
}
if (this._onBeforeSubmit) {
this._onBeforeSubmit()
}
// check form and getting errors
validate.async(data, this.constraits, options).then(
() => {
this._onSuccess(event, data)
},
(errors) => {
event.preventDefault()
// if onError is set, tha
if (this._onError) {
this._onError(event, errors, data)
}
// send each element a event
this.elements.forEach((element) => {
let elementErrors = false
// check for errors by name
if (errors[element.attributes.name.nodeValue]) {
elementErrors = errors[element.attributes.name.nodeValue]
}
this._dispatchCustomEvent(elementErrors, element)
})
}
)
}
/**
* send update to fields
*
*
* @param {Event} event
*
*/
_onFieldUpdate(event)
{
// workaround, make sure that value for single is undefined if it is empty
if (event.detail.value == '') {
event.detail.value = undefined
}
let errors = validate.single(event.detail.value, this.constraits[event.detail.name])
// search for element by name and dispatch event
this.elements.forEach((element) => {
if (element.attributes.name.nodeValue == event.detail.name) {
this._dispatchCustomEvent(errors, element)
}
})
}
/**
* dispatch event to single element
*
* @param {Array} errors
* @param {Element} element
*
*/
_dispatchCustomEvent(errors, element)
{
let detail = false
if (errors) {
detail = errors
}
const formValidationEvent = new CustomEvent('form-validation', {
'detail': detail
})
element.dispatchEvent(formValidationEvent)
}
}
export default FormValidator

@ -26,8 +26,8 @@ mix.webpackConfig({
}
})
mix.js('src/example.js', 'example')
.sass('src/example.scss', 'example')
mix.js('src/demo/demo.js', 'demo')
.sass('src/demo/demo.scss', 'demo')
.options({
terser: {
extractComments: false,

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save