Skip to content

Instantly share code, notes, and snippets.

@thinkOfaNumber
Forked from jdanyow/app.html
Last active January 30, 2018 03:07

Revisions

  1. thinkOfaNumber revised this gist Jan 30, 2018. 3 changed files with 9 additions and 1 deletion.
    1 change: 1 addition & 0 deletions app showing broken ensureObject
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    .
    1 change: 1 addition & 0 deletions registration-form.html
    Original file line number Diff line number Diff line change
    @@ -22,4 +22,5 @@

    <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <p>The form is valid: ${valid}</p>
    </template>
    8 changes: 7 additions & 1 deletion registration-form.js
    Original file line number Diff line number Diff line change
    @@ -19,12 +19,18 @@ export class RegistrationForm {
    }

    submit() {
    this.controller.validate();
    this.controller.validate().then(result => {
    this.valid = result.valid;
    });
    }
    }

    ValidationRules
    .ensure(a => a.firstName).required()
    .ensure(a => a.lastName).required()
    .ensure(a => a.email).required().email()
    .ensureObject().satisfies(a => {
    console.log("ensure object!!", a);
    return false;
    })
    .on(RegistrationForm);
  2. thinkOfaNumber revised this gist Jan 30, 2018. No changes.
  3. @jdanyow jdanyow revised this gist Dec 21, 2016. 1 changed file with 19 additions and 11 deletions.
    30 changes: 19 additions & 11 deletions bootstrap-form-renderer.js
    Original file line number Diff line number Diff line change
    @@ -1,25 +1,29 @@
    import {
    ValidationRenderer,
    RenderInstruction,
    ValidationError
    ValidateResult
    } from 'aurelia-validation';

    export class BootstrapFormRenderer {
    render(instruction) {
    for (let { error, elements } of instruction.unrender) {
    render(instruction: RenderInstruction) {
    for (let { result, elements } of instruction.unrender) {
    for (let element of elements) {
    this.remove(element, error);
    this.remove(element, result);
    }
    }

    for (let { error, elements } of instruction.render) {
    for (let { result, elements } of instruction.render) {
    for (let element of elements) {
    this.add(element, error);
    this.add(element, result);
    }
    }
    }

    add(element, error) {
    add(element: Element, result: ValidateResult) {
    if (result.valid) {
    return;
    }

    const formGroup = element.closest('.form-group');
    if (!formGroup) {
    return;
    @@ -31,19 +35,23 @@ export class BootstrapFormRenderer {
    // add help-block
    const message = document.createElement('span');
    message.className = 'help-block validation-message';
    message.textContent = error.message;
    message.id = `validation-message-${error.id}`;
    message.textContent = result.message;
    message.id = `validation-message-${result.id}`;
    formGroup.appendChild(message);
    }

    remove(element, error) {
    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-${error.id}`);
    const message = formGroup.querySelector(`#validation-message-${result.id}`);
    if (message) {
    formGroup.removeChild(message);

  4. @jdanyow jdanyow revised this gist Sep 6, 2016. 3 changed files with 2 additions and 81 deletions.
    14 changes: 2 additions & 12 deletions registration-form.html
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,6 @@
    <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>
    <form submit.delegate="submit()">
    <!--<ul><li repeat.for="error of controller.errors">${error.message}</li></ul>-->

    <div class="form-group">
    <label class="control-label" for="first">First Name</label>
    @@ -30,6 +21,5 @@ <h1>Register!</h1>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
    <button type="button" class="btn btn-default" click.delegate="reset()">Reset</button>
    </form>
    </template>
    56 changes: 0 additions & 56 deletions undefined
    Original file line number Diff line number Diff line change
    @@ -1,56 +0,0 @@
    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) {
    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');
    }
    }
    }
    }
    13 changes: 0 additions & 13 deletions validation-summary.html
    Original file line number Diff line number Diff line change
    @@ -1,13 +0,0 @@
    <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>
  5. @jdanyow jdanyow revised this gist Sep 6, 2016. 6 changed files with 133 additions and 119 deletions.
    56 changes: 56 additions & 0 deletions bootstrap-form-renderer.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    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) {
    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');
    }
    }
    }
    }
    75 changes: 0 additions & 75 deletions bootstrap-validation\bootstrap-form-validation-renderer.js
    Original file line number Diff line number Diff line change
    @@ -1,75 +0,0 @@
    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));
    7 changes: 0 additions & 7 deletions bootstrap-validation\index.js
    Original file line number Diff line number Diff line change
    @@ -1,7 +0,0 @@
    import {BootstrapFormValidationRenderer} from './bootstrap-form-validation-renderer';

    export function configure(config) {
    config.container.registerHandler(
    'bootstrap-form',
    container => container.get(BootstrapFormValidationRenderer));
    }
    4 changes: 1 addition & 3 deletions main.js
    Original file line number Diff line number Diff line change
    @@ -2,9 +2,7 @@ export function configure(aurelia) {
    aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .plugin('aurelia-validation')
    .plugin('aurelia-validatejs')
    .feature('bootstrap-validation');
    .plugin('aurelia-validation');

    aurelia.start().then(() => aurelia.setRoot());
    }
    54 changes: 20 additions & 34 deletions registration-form.js
    Original file line number Diff line number Diff line change
    @@ -1,44 +1,30 @@
    import {inject, NewInstance} from 'aurelia-dependency-injection';
    import {ValidationController, validateTrigger} from 'aurelia-validation';
    import {required, email, ValidationRules} from 'aurelia-validatejs';
    import {inject} from 'aurelia-dependency-injection';
    import {
    ValidationControllerFactory,
    ValidationController,
    ValidationRules
    } from 'aurelia-validation';
    import {BootstrapFormRenderer} from './bootstrap-form-renderer';

    @inject(NewInstance.of(ValidationController))
    @inject(ValidationControllerFactory)
    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...
    controller = null;

    constructor(controllerFactory) {
    this.controller = controllerFactory.createForCurrentScope();
    this.controller.addRenderer(new BootstrapFormRenderer());
    }

    reset() {
    this.firstName = '';
    this.lastName = '';
    this.email = '';
    this.controller.reset();
    submit() {
    this.controller.validate();
    }
    }


    // ValidationRules
    // .ensure('firstName').required()
    // .ensure('lastName').required()
    // .ensure('email').required().email()
    // .on(RegistrationForm);
    ValidationRules
    .ensure(a => a.firstName).required()
    .ensure(a => a.lastName).required()
    .ensure(a => a.email).required().email()
    .on(RegistrationForm);
    56 changes: 56 additions & 0 deletions undefined
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    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) {
    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');
    }
    }
    }
    }
  6. @jdanyow jdanyow revised this gist Jun 16, 2016. 1 changed file with 6 additions and 1 deletion.
    7 changes: 6 additions & 1 deletion bootstrap-validation\bootstrap-form-validation-renderer.js
    Original file line number Diff line number Diff line change
    @@ -13,6 +13,10 @@ export class BootstrapFormValidationRenderer {
    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');
    @@ -27,9 +31,10 @@ export class BootstrapFormValidationRenderer {
    }

    unrender(error, target) {
    if (!target || !(this.boundaryElement === target || this.boundaryElement.contains(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');
  7. @jdanyow jdanyow created this gist Jun 14, 2016.
    5 changes: 5 additions & 0 deletions app.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    <template>
    <require from="./registration-form"></require>

    <registration-form></registration-form>
    </template>
    2 changes: 2 additions & 0 deletions app.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    export class App {
    }
    70 changes: 70 additions & 0 deletions bootstrap-validation\bootstrap-form-validation-renderer.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    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;
    }

    // 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 || !(this.boundaryElement === target || this.boundaryElement.contains(target))) {
    return;
    }

    // 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));
    7 changes: 7 additions & 0 deletions bootstrap-validation\index.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    import {BootstrapFormValidationRenderer} from './bootstrap-form-validation-renderer';

    export function configure(config) {
    config.container.registerHandler(
    'bootstrap-form',
    container => container.get(BootstrapFormValidationRenderer));
    }
    27 changes: 27 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    <!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>
    10 changes: 10 additions & 0 deletions main.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    export function configure(aurelia) {
    aurelia.use
    .standardConfiguration()
    .developmentLogging()
    .plugin('aurelia-validation')
    .plugin('aurelia-validatejs')
    .feature('bootstrap-validation');

    aurelia.start().then(() => aurelia.setRoot());
    }
    35 changes: 35 additions & 0 deletions registration-form.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,35 @@
    <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>
    44 changes: 44 additions & 0 deletions registration-form.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,44 @@
    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);
    13 changes: 13 additions & 0 deletions validation-summary.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    <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>