Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show error messages in template after becameInvalid method

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

enter image description here

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>
like image 545
Slevin Avatar asked Feb 15 '23 11:02

Slevin


2 Answers

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/

like image 74
Marcio Junior Avatar answered May 16 '23 07:05

Marcio Junior


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.

like image 40
Alex Navasardyan Avatar answered May 16 '23 06:05

Alex Navasardyan