Skip to content

Instantly share code, notes, and snippets.

@alexdiliberto
Last active October 2, 2017 04:25
Show Gist options
  • Save alexdiliberto/57ab359f4a2cf940c59e1aa21abe3034 to your computer and use it in GitHub Desktop.
Save alexdiliberto/57ab359f4a2cf940c59e1aa21abe3034 to your computer and use it in GitHub Desktop.
skipValidate ember-changeset-validations demo
import Ember from 'ember';
import Changeset from 'ember-changeset';
import lookupValidator from 'ember-changeset-validations';
export default Ember.Component.extend({
init() {
this._super(...arguments);
let user = Ember.get(this, 'user');
let validations = Ember.get(this, 'validations');
/*
NOTE: It is currently necessary to create the changeset programatically through Javascript until the following PR is merged: https://github.com/DockYard/ember-changeset-validations/pull/147. Once merged we can simply use the template helper
```{{#with (changeset model validator) as |changeset|}}```
*/
this.changeset = new Changeset(user, lookupValidator(validations), validations, { skipValidate: true } );
}
});
import Ember from 'ember';
const {
Component,
get,
run
} = Ember;
const DEBOUNCE_TIMER = 400;
export default Component.extend({
changeset: null,
property: null,
actions: {
debounce(event) {
let val = event.target.value;
run.debounce(this, '_updateChangeset', val, DEBOUNCE_TIMER);
}
},
_updateChangeset(value) {
let property = get(this, 'property');
let changeset = get(this, 'changeset');
changeset.set(property, value);
}
});
import Ember from 'ember';
import AdultValidations from '../validations/adult';
import ChildValidations from '../validations/child';
import { reservedEmails } from '../validators/uniqueness';
import { schema } from '../models/user';
const { get } = Ember;
const { keys } = Object;
export default Ember.Controller.extend({
AdultValidations,
ChildValidations,
reservedEmails,
actions: {
save(changeset) {
let snapshot = changeset.snapshot();
return changeset
.cast(keys(schema))
.validate()
.then(() => {
if (get(changeset, 'isValid')) {
return changeset.execute();
}
}).catch(() => {
changeset.restore(snapshot);
});
},
reset(changeset) {
return changeset.rollback();
},
validateProperty(changeset, property) {
console.log(`validate ${property}`);
console.log(changeset.validate(property).then(function(x) { console.log(x); return x; }));
return changeset.validate(property);
}
}
});
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export const schema = {
firstName: attr('string'),
lastName: attr('string'),
email: attr('string'),
age: attr('number'),
job: attr('string')
};
export default Model.extend(schema);
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').createRecord('user', {
firstName: 'Jim',
lastName: 'Bob',
age: 10
});
}
});
{{marketing-copy reservedEmails=reservedEmails}}
<hr>
{{!--
Try changing `type` to `child` and `validations` to `ChildValidations`
--}}
{{edit-user
user=model
validations=AdultValidations
type="adult"
save=(action "save")
reset=(action "reset")
validateProperty=(action "validateProperty")
}}
<h4>{{type}} user: <code>{{user.firstName}} {{user.lastName}}, age {{user.age}} is a {{user.job}}</code></h4>
{{validated-field
type="text"
changeset=changeset
property="firstName"
validateProperty=(action validateProperty changeset "firstName")
}}
{{validated-field
type="text"
changeset=changeset
property="lastName"
validateProperty=(action validateProperty changeset "lastName")
}}
{{validated-field
type="text"
changeset=changeset
property="email"
validateProperty=(action validateProperty changeset "email")
}}
{{validated-field
type="text"
changeset=changeset
property="job"
validateProperty=(action validateProperty changeset "job")
}}
{{validated-field
type="number"
changeset=changeset
property="age"
validateProperty=(action validateProperty changeset "age")
}}
<div class="row">
<button {{action save changeset}} disabled={{changeset.isInvalid}} class="button-primary">Save</button>
<button {{action reset changeset}}>Reset</button>
</div>
<h2>ember-changeset-validations demo<br><small>skipValidate=true</small></h2>
<iframe src="https://ghbtns.com/github-btn.html?user=DockYard&repo=ember-changeset&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=DockYard&repo=ember-changeset-validations&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe>
<p><strong>NOTE:</strong> Right now it is necessary to create the <code>new Changeset()</code> programatically through Javascript until the <a href="https://github.com/DockYard/ember-changeset-validations/pull/147">following PR is merged</a>. Once merged we can simply use the template helper <code>\{{#with (changeset model validator) as |changeset|}}</code></p>
<p><code>ember-changeset</code> and <code>ember-changeset-validations</code> provide an easy way to validate and set changes to your data. Unlike CP or observer based validations, you don't need to write anything special to prevent data from immediately becoming invalid. Validators are simply functions, no CPs or observers required. Try clearing the inputs below, entering invalid values, or even just focusing out. Email is an async validation.</p>
<p>
Reserved emails: {{#each reservedEmails as |email|}}
<code>{{email}}</code>
{{/each}}
</p>
<label for={{concat type "-" property}}>{{property}}</label>
<input
class="u-full-width"
type={{type}}
id={{concat type "-" property}}
value={{get changeset property}}
oninput={{action (mut (get changeset property)) value="target.value"}}
onblur={{action validateProperty}}>
{{#if (get changeset.error property)}}
<small>
<ul>
{{#each (get (get changeset.error property) "validation") as |message|}}
<li>{{message}}</li>
{{/each}}
</ul>
</small>
{{/if}}
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0",
"skeleton-css": "https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css"
},
"addons": {
"ember-data": "2.12.1",
"ember-changeset-validations": "1.2.8",
"ember-one-way-controls": "0.8.3"
}
}
import Ember from 'ember';
import { validateNumber } from 'ember-changeset-validations/validators';
import UserValidations from './user';
const { assign } = Ember;
export default assign({}, UserValidations, {
age: validateNumber({ gte: 18 })
});
import Ember from 'ember';
import { validateNumber } from 'ember-changeset-validations/validators';
import UserValidations from './user';
const { assign } = Ember;
export default assign({}, UserValidations, {
age: validateNumber({ lt: 18 })
});
import {
validatePresence,
validateLength,
validateFormat
} from 'ember-changeset-validations/validators';
import validateUniqueness from '../validators/uniqueness';
export default {
firstName: [
validateLength({ min: 2 }),
validatePresence(true)
],
lastName: [
validatePresence(true),
validateLength({ min: 2 })
],
email: [
validateUniqueness(),
validateFormat({ type: 'email' })
],
job: validatePresence(true)
}
import Ember from 'ember';
const { RSVP: { resolve } } = Ember;
export const reservedEmails = ['[email protected]', '[email protected]'];
export default function validateUniqueness() {
return (key, newValue, oldValue, changes) => {
let isAvailable = reservedEmails.indexOf(newValue) === -1;
return resolve(isAvailable || 'is taken');
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment