Skip to content

Instantly share code, notes, and snippets.

@jdanyow
Last active July 14, 2017 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdanyow/2d323c31549dbfe9c7483296b095a6bf to your computer and use it in GitHub Desktop.
Save jdanyow/2d323c31549dbfe9c7483296b095a6bf to your computer and use it in GitHub Desktop.
Aurelia Validation Demo - Rule Conditions
<template>
<h2>Address</h2>
<form submit.delegate="submit()">
<ul><li repeat.for="error of controller.errors">${error.message}</li></ul>
<label><input type="checkbox" checked.bind="address.personalData"> Personal Data?</label>
<div class="form-group" show.bind="address.personalData">
<label class="control-label" for="street">Street</label>
<input type="text" class="form-control" id="street" placeholder="Street"
value.bind="address.street & validate:rules">
</div>
<div class="form-group" show.bind="address.personalData">
<label class="control-label" for="houseNumber">House #</label>
<input type="text" class="form-control" id="houseNumber" placeholder="House #"
value.bind="address.houseNumber & validate:rules">
</div>
<div class="form-group">
<label class="control-label" for="city">City</label>
<input type="text" class="form-control" id="city" placeholder="City"
value.bind="address.city & validate:rules">
</div>
<div class="form-group">
<label class="control-label" for="zip">Zip</label>
<input type="text" class="form-control" id="zip" placeholder="Zip"
value.bind="address.zip & validate:rules">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</template>
import {bindable, inject} from 'aurelia-framework';
import {ValidationControllerFactory} from 'aurelia-validation';
import {BootstrapFormRenderer} from './bootstrap-form-renderer';
@inject(ValidationControllerFactory)
export class AddressForm {
@bindable address;
constructor(controllerFactory) {
this.controller = controllerFactory.createForCurrentScope();
this.controller.addRenderer(new BootstrapFormRenderer());
}
submit() {
this.controller.validate();
}
}
import {ValidationRules} from 'aurelia-validation';
export class Address {
street = '';
houseNumber = '';
zip = '';
city = '';
personalData = false;
}
ValidationRules
.ensure('street').required().when(a => a.personalData)
.ensure('houseNumber').required().when(a => a.personalData)
.ensure('city').required()
.ensure('zip').required()
.on(Address)
<template>
<require from="./address-form"></require>
<address-form address.bind="address"></address-form>
</template>
import {Address} from './address';
export class App {
address = new Address();
}
import {
ValidationRenderer,
RenderInstruction,
ValidateResult
} from 'aurelia-validation';
export class BootstrapFormRenderer {
render(instruction: RenderInstruction) {
for (let { result, elements } of instruction.unrender) {
for (let element of elements) {
this.remove(element, result);
}
}
for (let { result, elements } of instruction.render) {
for (let element of elements) {
this.add(element, result);
}
}
}
add(element: Element, result: ValidateResult) {
if (result.valid) {
return;
}
const formGroup = element.closest('.form-group');
if (!formGroup) {
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 = result.message;
message.id = `validation-message-${result.id}`;
formGroup.appendChild(message);
}
remove(element: Element, result: ValidateResult) {
if (result.valid) {
return;
}
const formGroup = element.closest('.form-group');
if (!formGroup) {
return;
}
// remove help-block
const message = formGroup.querySelector(`#validation-message-${result.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');
}
}
}
}
<!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>
address-form {
display: block;
border: 1px solid lightgray;
border-radius: 3px;
max-width: 300px;
margin: 0 auto 15px auto;
padding: 15px;
}
</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');
aurelia.start().then(() => aurelia.setRoot());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment