Last active
April 6, 2018 03:56
-
-
Save 3cp/ba86ba3ad3a6b165f19b2e7370d9fc6c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<require from="./dyn-field"></require> | |
<form> | |
<dyn-field | |
repeat.for="prop of properties" | |
label.bind="prop.label" | |
value.bind="model | get:model:prop.expression" | |
errors.bind="errors | get:errors:prop.expression"></dyn-field> | |
</form> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {inject} from 'aurelia-dependency-injection'; | |
import {Parser} from 'aurelia-binding'; | |
// normally you just do | |
// import Validation from 'bcx-validation'; | |
// @inject(Validation) | |
// Look in main.js for the the hook up DI of "Validation" to global name BcxValidation | |
@inject('Validation') | |
export class App { | |
model = { | |
firstName: 'John', | |
lastName: 'Doe', | |
address: { | |
address1: '1 Main Street', | |
address2: '', | |
city: 'Burlington', | |
state: 'VT', | |
zip: '05401' | |
} | |
}; | |
properties = [ | |
{ label: 'First Name', expression: 'firstName' }, | |
{ label: 'Last Name', expression: 'lastName' }, | |
{ label: 'Address 1', expression: 'address.address1' }, | |
{ label: 'Address 2', expression: 'address.address2' }, | |
{ label: 'City', expression: 'address.city' }, | |
{ label: 'State', expression: 'address.state' }, | |
{ label: 'Zip', expression: 'address.zip' } | |
]; | |
validationRule = { | |
firstName: 'mandatory', | |
lastName: 'mandatory', | |
address: { | |
address1: 'mandatory', | |
city: 'mandatory', | |
state: [ | |
'mandatory', | |
{ | |
validate: 'within', | |
items: ['VT', 'WA'], | |
message: 'not a valid US state (demo only supports VT and WA, modify your rule to support full list)' | |
} | |
], | |
zip: ['mandatory', {validate: /^\d{5}$/, message: "not a valid US zip code"}] | |
} | |
} | |
constructor(validation) { | |
this.validator = validation.generateValidator(this.validationRule); | |
} | |
// Since model object is complex, we use dirty check to update errors, | |
// you can use @computedFrom('firstName', 'lastName', 'address.address1', ...) if you want efficiency. | |
// Sometime, dirty check is the only choice if your model is like | |
// {name: '', employees: [ dynamic_list_of_employees ]}. | |
// BTW, bcx-validation can validate the above model. | |
get errors() { | |
return this.validator(this.model); | |
} | |
} | |
@inject(Parser) | |
export class GetValueConverter { | |
constructor(parser) { | |
this.parser = parser; | |
} | |
toView(_: any, model: any, propertyExpression: string): any { | |
let getExp = this.parser.parse(propertyExpression); | |
if (!model) return; // modified to deal with missing model (the empty errors obj) | |
return getExp.evaluate({ bindingContext: model }); | |
} | |
fromView(value: any, model: any, propertyExpression: string): any { | |
let setExp = this.parser.parse(propertyExpression + ' = $value'); | |
setExp.evaluate({ | |
bindingContext: model, | |
overrideContext: { $value: value } | |
}); | |
return model; | |
} | |
} | |
export class LocalDebugValueConverter { | |
toView(value: any): any { | |
console.info(`[DEBUG-toView]`, JSON.stringify(value)); | |
return value; | |
} | |
fromView(value: any): any { | |
console.info(`[DEBUG-fromView]`, JSON.stringify(value)); | |
return value; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="from-group ${errors ? 'has-error' : ''}"> | |
<label class="control-label">${label}</label> | |
<input type="text" class="form-control" value.bind="value"> | |
<span if.bind="errors" class="help-block"> | |
<span repeat.for="err of errors">${err}<br if.bind="!$last"></span> | |
</span> | |
</div> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {bindable, bindingMode} from 'aurelia-framework'; | |
export class DynField { | |
@bindable({defaultBindingMode: bindingMode.twoWay}) value; | |
@bindable errors; | |
@bindable label; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> | |
label, input { | |
display: block; | |
margin-bottom: 10px; | |
} | |
</style> | |
</head> | |
<body aurelia-app="main"> | |
<h1>Loading...</h1> | |
<!-- lodash and bcx-expression-evalutor are dependencies of bcx-validation --> | |
<!-- for demo in gistrun, load them before requrejs --> | |
<!-- for real app, just do npm install bcx-validation --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script> | |
<script src="https://npm-cdn.herokuapp.com/[email protected]/dist/index.js"></script> | |
<script src="https://npm-cdn.herokuapp.com/[email protected]/dist/index.js"></script> | |
<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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function configure(aurelia) { | |
aurelia.use | |
.standardConfiguration() | |
.developmentLogging() | |
.plugin('aurelia-validation'); | |
// For demostration in gistrun, bcx-validation is loaded in index.html before requirejs. | |
// bcx-validation is in UMD format, when no AMD/commonjs loader available, it creates | |
// global name BcxValidation. | |
// It is optional to register bcx-validation as transient. | |
// the default DI behavior is singleton, which works out of the box. | |
// But if you customize a validation instance by addValidator/addHelper, | |
// it is better to use transient instance to isolate the customization. | |
aurelia.container.registerTransient('Validation', BcxValidation); | |
aurelia.start().then(() => aurelia.setRoot()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment