Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jdanyow
Last active July 3, 2023 13:02
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 38 You must be signed in to fork a gist
  • Save jdanyow/381fdb1a4b0865a4c25026187db865ce to your computer and use it in GitHub Desktop.
Save jdanyow/381fdb1a4b0865a4c25026187db865ce 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 {
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>
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');
aurelia.start().then(() => aurelia.setRoot());
}
<template>
<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>
<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>
</form>
</template>
import {inject} from 'aurelia-dependency-injection';
import {
ValidationControllerFactory,
ValidationController,
ValidationRules
} from 'aurelia-validation';
import {BootstrapFormRenderer} from './bootstrap-form-renderer';
@inject(ValidationControllerFactory)
export class RegistrationForm {
firstName = '';
lastName = '';
email = '';
controller = null;
constructor(controllerFactory) {
this.controller = controllerFactory.createForCurrentScope();
this.controller.addRenderer(new BootstrapFormRenderer());
}
submit() {
this.controller.validate();
}
}
ValidationRules
.ensure(a => a.firstName).required()
.ensure(a => a.lastName).required()
.ensure(a => a.email).required().email()
.on(RegistrationForm);
@Ashwini-zedua
Copy link

is there any validation for image file size in this plug in?

@cornillemichiel
Copy link

Do you have an updated bootstrap-form-renderer compatible with bootstrap 4.0.0 where they completely revamped the form classes and added compatibility for HTML5 :invalid and :valid pseudo-classes? Completely at a loss here.

@migajek
Copy link

migajek commented Mar 20, 2018

@cornillemichiel I have bootstrap 4 beta 2 and it has support for is-invalid class along :invalid selector.
so here's an adjusted source

import { ValidationController } from 'aurelia-validation';
import { Container } from 'aurelia-dependency-injection';
import { ValidationControllerFactory } from 'aurelia-validation';
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;
      } 

      // add the is-invalid class to the enclosing form-group div
      element.classList.add('is-invalid');
  
      const formGroup = element.closest('.form-group');      
      if (!formGroup) {
        return;
      }

      // add help-block
      const message = document.createElement('div');
      message.className = 'invalid-feedback';
      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 is-invalid class from the enclosing form-group div
        if (formGroup.querySelectorAll('.invalid-feedback').length === 0) {
          element.classList.remove('is-invalid');
        }
      }
    }
}

export class BootstrapValidationControllerFactory extends ValidationControllerFactory {
  constructor(container: Container) {
    super(container);      
  }
  public static get(container: Container) {
      return new BootstrapValidationControllerFactory(container);
  }
  
  createForCurrentScope(): ValidationController {
      let ctrl = super.createForCurrentScope();
      ctrl.addRenderer(new BootstrapFormRenderer());        
      return ctrl;
  }
}

export class BootstrapValidationController extends ValidationController {
  public static get(container: Container) {              
      return new BootstrapValidationControllerFactory(container).createForCurrentScope();
  }
}
(BootstrapValidationController as any)['protocol:aurelia:resolver'] = true;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment