I'm using Ember.js to display a list of customers. Inside this template, I have a modal to create new customers. Now, when creating invalid customers (e.g. duplicate name), the errors should be shown in the template. How can I get this to work?
model
Docket.Customer = DS.Model.extend({
name: DS.attr('string'),
initial: DS.attr('string'),
description: DS.attr('string'),
errors: {},
becameInvalid: function(errors) {
this.set('errors', errors.get('errors'));
console.log(this.get('errors'));
}
});
console output
template
<h1>Customers<button data-uk-modal="{target:'#customer-modal'}" class="icon-plus">New customer</button></h1>
<div id="customer-modal" class="uk-modal">
<div class="uk-modal-dialog uk-modal-dialog-slide">
<a class="uk-modal-close uk-close"></a>
<form class="uk-form" {{action "save" on="submit"}}>
<fieldset>
<legend>New customer</legend>
<div class="uk-form-row">
{{view Ember.TextField valueBinding="name" name="name" class="uk-width-1-1" placeholder="Name" required="" }}
{{#if errors}}foo{{/if}}
{{#if errors.name}}{{errors.name}}{{/if}}
</div>
<div class="uk-form-row">
{{view Ember.TextField valueBinding="initial" name="initial" class="uk-width-1-1" placeholder="Initial" required="" }}
</div>
<div class="uk-form-row">
{{view Ember.TextArea valueBinding="description" name="description" class="uk-width-1-1" placeholder="Description"}}
</div>
<div class="uk-form-row">
<button type="submit" class="icon-check">Save</button>
</div>
</fieldset>
</form>
</div>
</div>
<ul class="entries">
{{#each}}
<li>
<div class="actions">
<button {{action "remove" id}} class="icon-close"></button>
</div>
<div class="link" {{action "edit" id}} data-uk-modal="{target:'#customer-modal'}">
<span class="initial">{{initial}}</span>{{name}}
</div>
</li>
{{else}}
<li>No customers</li>
{{/each}}
</ul>
You can create a custom handlebars helper, like the following:
Ember.Handlebars.helper('show-errors', function(errors) {
var html = '';
if (errors) {
html += '<ul>';
$.each(errors, function(key, values) {
html += '<li>' + key + ' - ' + values.join(',') + '</li>'
});
html += '</ul>'
}
return html.htmlSafe();
})
So just use {{show-errors recordInstance.errors}}
in some template to use it.
In the first moment, there isn't errors so nothing will be displayed. When your record has a error, errors
hash will be populed and the template will be updated.
Give a look in this fiddle http://jsfiddle.net/marciojunior/vh6aL/
You should consider moving your validations to the controller
. Form validations and validations in general are very contextual. Customer
model might have different set of validations depending on which part of your app you're in.
If you decide to move validations to the controller
, you would need to create an observer that is going to watch the changes of a particular property/properties and run validations accordingly.
Note: I'm talking about client side validations (doesn't involve talking to the server before validations conditions are met), not server side ones.
App.CustomerController = Ember.ObjectController.extend({
errors: [],
runNameValidation: function() {
// run validations for 'name'
// if validations fail, push error to 'errors' array
// on the controller
}.observes('model.name')
});
There's a validations library that takes care of it for you (it abstracts out validations bit and wraps it into a validations mixin for better reuse). Also, if you use for form specifically, you should consider looking at easyForm.
Update:
If you want to use server side validations, then all you need to add to your template is:
{{model.errors}}
When you try to save ED model and it server fails to do it, model
is going to have errors
array which you can use. Also, I would suggest creating the errors
component, instead of creating the errors
helper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With