Skip to content

Instantly share code, notes, and snippets.

@stefek99
Forked from jdanyow/app.html
Created July 11, 2016 15:21
Show Gist options
  • Save stefek99/f69c6622ee5142e01c9cf3dec96edaaa to your computer and use it in GitHub Desktop.
Save stefek99/f69c6622ee5142e01c9cf3dec96edaaa to your computer and use it in GitHub Desktop.
Aurelia Validation Demo
<template>
<require from="./registration-form"></require>
<registration-form></registration-form>
</template>
export class App {
}
import {inject} from 'aurelia-dependency-injection';
import {validationRenderer} from 'aurelia-validation';
@validationRenderer
@inject(Element)
export class BootstrapFormValidationRenderer {
constructor(boundaryElement) {
this.boundaryElement = boundaryElement;
}
render(error, target) {
if (!target || !(this.boundaryElement === target || this.boundaryElement.contains(target))) {
return;
}
// tag the element so we know we rendered into it.
target.errors = (target.errors || new Map());
target.errors.set(error);
// add the has-error class to the bootstrap form-group div
const formGroup = target.querySelector('.form-group') || target.closest('.form-group');
formGroup.classList.add('has-error');
// add help-block
const message = document.createElement('span');
message.classList.add('help-block');
message.classList.add('validation-error');
message.textContent = error.message;
message.error = error;
formGroup.appendChild(message);
}
unrender(error, target) {
if (!target || !target.errors || !target.errors.has(error)) {
return;
}
target.errors.delete(error);
// remove the has-error class on the bootstrap form-group div
const formGroup = target.querySelector('.form-group') || target.closest('.form-group');
formGroup.classList.remove('has-error');
// remove all messages related to the error.
let messages = formGroup.querySelectorAll('.validation-error');
let i = messages.length;
while(i--) {
let message = messages[i];
if (message.error !== error) {
continue;
}
message.error = null;
message.remove();
}
}
}
// Polyfill for Element.closest and Element.matches
// https://github.com/jonathantneal/closest/
(function (ELEMENT) {
ELEMENT.matches = ELEMENT.matches || ELEMENT.mozMatchesSelector || ELEMENT.msMatchesSelector || ELEMENT.oMatchesSelector || ELEMENT.webkitMatchesSelector;
ELEMENT.closest = ELEMENT.closest || function closest(selector) {
var element = this;
while (element) {
if (element.matches(selector)) {
break;
}
element = element.parentElement;
}
return element;
};
}(Element.prototype));
import {BootstrapFormValidationRenderer} from './bootstrap-form-validation-renderer';
export function configure(config) {
config.container.registerHandler(
'bootstrap-form',
container => container.get(BootstrapFormValidationRenderer));
}
<!doctype html>
<html>
<head>
<title>Aurelia</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<style>
registration-form {
display: block;
max-width: 300px;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body aurelia-app="main">
<h1>Loading...</h1>
<script src="https://jdanyow.github.io/rjs-bundle/node_modules/requirejs/require.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/config.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/aurelia.js"></script>
<script src="https://jdanyow.github.io/rjs-bundle/bundles/babel.js"></script>
<script>
require(['aurelia-bootstrapper']);
</script>
</body>
</html>
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.plugin('aurelia-validation')
.plugin('aurelia-validatejs')
.feature('bootstrap-validation');
aurelia.start().then(() => aurelia.setRoot());
}
<template>
<require from="./validation-summary.html"></require>
<h1>Register!</h1>
<form submit.delegate="submit()"
validation-renderer="bootstrap-form"
validation-errors.bind="errors">
<validation-summary errors.bind="errors"
autofocus.bind="controller.validateTrigger === 'manual'">
</validation-summary>
<div class="form-group">
<label class="control-label" for="first">First Name</label>
<input type="text" class="form-control" id="first" placeholder="First Name"
value.bind="firstName & validate">
</div>
<div class="form-group">
<label class="control-label" for="last">Last Name</label>
<input type="text" class="form-control" id="last" placeholder="Last Name"
value.bind="lastName & validate">
</div>
<div class="form-group">
<label class="control-label" for="email">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email"
value.bind="email & validate">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-default" click.delegate="reset()">Reset</button>
</form>
</template>
import {inject, NewInstance} from 'aurelia-dependency-injection';
import {ValidationController, validateTrigger} from 'aurelia-validation';
import {required, email, ValidationRules} from 'aurelia-validatejs';
@inject(NewInstance.of(ValidationController))
export class RegistrationForm {
@required
firstName = '';
@required
lastName = '';
@required
@email
email = '';
constructor(controller) {
this.controller = controller;
// the default mode is validateTrigger.blur but
// you can change it:
// controller.validateTrigger = validateTrigger.manual;
// controller.validateTrigger = validateTrigger.change;
}
submit() {
let errors = this.controller.validate();
// todo: call server...
}
reset() {
this.firstName = '';
this.lastName = '';
this.email = '';
this.controller.reset();
}
}
// ValidationRules
// .ensure('firstName').required()
// .ensure('lastName').required()
// .ensure('email').required().email()
// .on(RegistrationForm);
<template bindable="errors, autofocus">
<div class="alert alert-danger" tabindex="-1"
show.bind="errors.length"
focus.one-way="autofocus && errors.length > 0">
<ul class="list-unstyled">
<li repeat.for="errorInfo of errors">
<a class="text-danger" href="#" click.delegate="errorInfo.target.focus()">
${errorInfo.error.message}
</a>
</li>
</ul>
</div>
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment