Skip to content

Instantly share code, notes, and snippets.

@dtaalbers
Last active September 18, 2016 16:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save dtaalbers/6f32a7865a306daa1062e84a10b6c493 to your computer and use it in GitHub Desktop.
Save dtaalbers/6f32a7865a306daa1062e84a10b6c493 to your computer and use it in GitHub Desktop.
Aurelia Validation Demo using a model in the viewmodel
import { ValidationRules } from 'aurelia-validation';
export class Address {
street;
city;
}
ValidationRules
.ensure(a => a.street).required()
.ensure(a => a.city).required()
.on(Address);
<template>
<router-view></router-view>
</template>
import {Router} from 'aurelia-router';
export class App {
router = null;
configureRouter(config, router) {
this.router = router;
config.title = 'Aurelia';
config.map([
{ route: ['', 'home'], name: 'Home', moduleId: './home' },
{ route: 'create', name: 'create', moduleId: './create' },
{ route: 'edit', name: 'edit', moduleId: './edit'}
]);
}
}
import {
ValidationRenderer,
RenderInstruction,
ValidationError
} from 'aurelia-validation';
export class BootstrapFormRenderer {
render(instruction) {
for (let { error, elements } of instruction.unrender) {
for (let element of elements) {
this.remove(element, error);
}
}
for (let { error, elements } of instruction.render) {
for (let element of elements) {
this.add(element, error);
}
}
}
add(element, error) {
const formGroup = element.closest('.form-group');
if (!formGroup || formGroup.classList.contains('hide-error')) {
return;
}
// add the has-error class to the enclosing form-group div
formGroup.classList.add('has-error');
// add help-block
const message = document.createElement('span');
message.className = 'help-block validation-message';
message.textContent = error.message;
message.id = `validation-message-${error.id}`;
formGroup.appendChild(message);
}
remove(element, error) {
const formGroup = element.closest('.form-group');
if (!formGroup) {
return;
}
// remove help-block
const message = formGroup.querySelector(`#validation-message-${error.id}`);
if (message) {
formGroup.removeChild(message);
// remove the has-error class from the enclosing form-group div
if (formGroup.querySelectorAll('.help-block.validation-message').length === 0) {
formGroup.classList.remove('has-error');
}
}
}
}
<template>
<form submit.delegate="submit()">
<h1>${title}</h1>
<div class="form-group">
<label class="control-label" for="last">Name</label>
<input type="text" class="form-control" placeholder="Name"
value.bind="driver.name & validate">
</div>
<div class="form-group">
<label class="control-label" for="last">Custom address? ${driver.customAddress}</label>
<input type="checkbox" checked.bind="driver.customAddress">
</div>
<hr>
<h4>Custom address</h4>
<div class="form-group">
<label class="control-label" for="last">Street</label>
<input type="text" class="form-control" placeholder="Street"
value.bind="driver.address.street & validate">
</div>
<div class="form-group">
<label class="control-label" for="last">City</label>
<input type="text" class="form-control" placeholder="Street"
value.bind="driver.address.city & validate">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<button class="btn btn-danger" click.delegate="back()">Back</button>
</form>
</template>
import {Driver} from './driver';
import {inject, NewInstance} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {ValidationController,} from 'aurelia-validation';
import {BootstrapFormRenderer} from './bootstrap-form-renderer';
@inject(NewInstance.of(ValidationController), Router)
export class Create {
title = 'Create';
controller = null;
router = null;
driver = new Driver();
constructor(controller, router) {
this.controller = controller;
this.controller.addRenderer(new BootstrapFormRenderer());
this.router = router;
}
submit () {
this.controller.validate();
}
back() {
this.router.navigateToRoute('Home');
}
}
import { ValidationRules } from 'aurelia-validation';
import {Address} from './address';
export class Driver {
name;
address = new Address();
customAddress = false;
}
ValidationRules
.ensure(d => d.name)
.required()
.ensure(d => d.address)
.required()
.when(d => d.customAddress)
.on(Driver);
<template>
<form submit.delegate="submit()">
<h1>${title}</h1>
<div class="form-group">
<label class="control-label" for="last">Name</label>
<input type="text" class="form-control" placeholder="Name"
value.bind="driver.name & validate">
</div>
<div class="form-group">
<label class="control-label" for="last">Custom address? ${driver.customAddress}</label>
<input type="checkbox" checked.bind="driver.customAddress">
</div>
<hr>
<h4>Custom address</h4>
<div class="form-group">
<label class="control-label" for="last">Street</label>
<input type="text" class="form-control" placeholder="Street"
value.bind="driver.address.street & validate">
</div>
<div class="form-group">
<label class="control-label" for="last">City</label>
<input type="text" class="form-control" placeholder="Street"
value.bind="driver.address.city & validate">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<button class="btn btn-danger" click.delegate="back()">Back</button>
</form>
</template>
import {inject, NewInstance} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {Driver} from './driver';
import {ValidationController} from 'aurelia-validation';
import {BootstrapFormRenderer} from './bootstrap-form-renderer';
@inject(NewInstance.of(ValidationController), Router)
export class Edit {
title = "Edit"
router = null;
controller = null;
driver = new Driver();
constructor(controller, router) {
this.controller = controller;
this.controller.addRenderer(new BootstrapFormRenderer());
this.router = router;
}
submit () {
this.controller.validate();
}
back() {
this.router.navigateToRoute('Home');
}
}
<template>
<h1>${title}</h1>
<button class="btn btn-primary" click.delegate="navigateTo('create')">Create</button>
<button class="btn btn-primary" click.delegate="navigateTo('edit')">Edit</button>
</template>
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
@inject(Router)
export class Home {
router = null;
constructor(router) {
this.router = router;
}
navigateTo(route) {
this.router.navigateToRoute(route);
}
title = 'Home page';
}
<!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">
</head>
<body aurelia-app="main" class="container">
<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');
aurelia.start().then(() => aurelia.setRoot());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment