0

I have several views in my Ember application. One of my views in registration view. I define it with a template.
I am also using jquery validate plugin so that I can validate easily forms like the registration form.
In order to let the registration view work with validations, I added a js script that initialize validate on the registration form.
When I load my application directly to the registration view (myapp/index.html#/registration) the validations are initialized and working fine.
The problem is when I load the application into different page (myapp/index.html#/list for example) and then press the button the change the state to registration, then the validations are not working and sumbitting an empty form is possible.
For some reasons the registration validation initialize are not working when the first view that loaded is not the registration view.
Any idea why? How can I solve this?

EDIT: Here is some code
This is the View:

<script type="text/x-handlebars" data-template-name="registration">
        <form class="form-horizontal" id="registerForm">
            <fieldset>
                <legend>registration</legend>
                <div class="control-group">
                    <label class="control-label" for="user_name">User Name</label>
                    <div class="controls">
                        <input type="text" class="input-xlarge" id="user_name" name="user_name"/>
                    </div>
                </div>  
                <div class="control-group">
                    <label class="control-label" for="user_email">Email</label>
                    <div class="controls">
                        <input type="text" class="input-xlarge" id="user_email" name="user_email" title="Tooltip text"/>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="password">Password</label>
                    <div class="controls">
                        <input type="password" class="input-xlarge" id="password" name="password" title="Password tooltip"/>
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="password_confirm">Password Confirmation</label>
                    <div class="controls">
                        <input type="password" class="input-xlarge" id="password_confirm" name="password_confirm" title="Confirmation tooltip">
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label"></label>
                    <div class="controls">
                        <button type="submit" class="btn btn-success">Create Account</button>
                    </div>
                </div>
            </fieldset>
        </form>
    </script>

This is initialization script for the registration view:

$(document).ready(function() {

    $("#registerForm input").tipsy({gravity: 'e'});

    // Validation
    $("#registerForm").validate({
        rules : {
            user_name : "required",
            user_email : {
                required : true,
                email : true
            },
            password : {
                required : true,
                minlength : 6
            },
            password_confirm : {
                required : true,
                equalTo : "#password"
            }
        },

        errorClass : "help-inline",
        errorElement : "span",
        highlight : function(element, errorClass, validClass) {
            $(element).parents('.control-group').removeClass('success');
            $(element).parents('.control-group').addClass('error');
        },
        unhighlight : function(element, errorClass, validClass) {
            $(element).parents('.control-group').removeClass('error');
            $(element).parents('.control-group').addClass('success');
        }
    });
}); 

This is app code relevant to registration:

App.RegistrationController = Em.Controller.extend();
App.RegistrationView = Em.View.extend({
    templateName: 'registration'
});
App.Router = Em.Router.extend({
    enableLogging: true,
    location: 'hash',

    root: Em.Route.extend({
        // EVENTS
        gotoList: Ember.Route.transitionTo('list'),
        gotoAbout: Ember.Route.transitionTo('about'),
        gotoPost: Ember.Route.transitionTo('post'),
        gotoRegistration: Ember.Route.transitionTo('registration'),

        // STATES
        index: Em.Route.extend({
            route: '/',
            redirectsTo: 'list'
        }),
        list: Em.Route.extend({
            route: '/list',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('list');
            }
        }),
        about: Em.Route.extend({
            route: '/about',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('about');
            }
        }),
        post: Em.Route.extend({
            route: '/post',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('post');
            }
        }),
        registration: Em.Route.extend({
            route: '/registration',
            connectOutlets: function(router, context) {
                router.get('applicationController').connectOutlet('registration');
            }
        })
    })
});

The problem is that when I surf to "#\list" and then go to registration, it looks like the registration initialization script didn't executed although I add reference to this script in my html. Any idea why?

Naor
  • 23,465
  • 48
  • 152
  • 268
  • 2
    First, without code, it's very difficult to give you an answer. What validation script ? How do it interact with your ember App ? The second thing I have to say, is that in an other question, you don't know anything about main concepts of ember (bindings, observers, computed properties). It hink you have first to go with that and play a little, before building a more complex app. That beeing said, if you can provide a jsfiddle, or at least post some fragments here, I'll be pleased to try to help you. – sly7_7 Aug 03 '12 at 06:54
  • @sly7_7: You must be very smart if you can understand without code that I don't know anything about main concepts of ember. I will try to put some code and then I will glad if you'le explain me the things I don't know. – Naor Aug 03 '12 at 17:47
  • @sly7_7: Added some code. Appriciate reply. Tnx. – Naor Aug 03 '12 at 17:59
  • I apologize, but on this question: http://stackoverflow.com/questions/11768384/highlight-current-item-in-navbar-using-ember-js#comment15679918_11768384 , I try to explain you some things about bindings and computed properies, and you tell me: "@sly7_7: Thanks for the explanation but what is 'selectedBinding: "controller.selected"', 'property("item", "parentView.selected")' and "cacheable()"? – Naor 22 hours ago". So perhaps I misunderstood, but for me it means that you were not aware of ember concepts. – sly7_7 Aug 03 '12 at 23:23

1 Answers1

0

At first sight, it seems that your validation script is executed when the dom is ready.

So, if you go first with /registration, the form is displayed, and when ready, the script works fine, because all form elements are present in the Dom.

But when you first enter with /list, it displays the list, then dom is ready, and your script is executed. But all the validation stuff searches for #registration, which is not on the page, an does nothing. Then when you switch to /registration, the script is not evaluated again (basically routing to a state is not like refreshing the page, but only update the dom).

I think if you write the validation code inside the didInsertElement function of the RegistrationView, then it should work.

App.RegistrationView = Em.View.extend({
  templateName: 'registration',

  didInsertElement: function () {
    this.$("#registerForm input").tipsy({gravity: 'e'});
    // Validation
    this.$("#registerForm").validate({
      rules : {
        user_name : "required",
        user_email : {
           required : true,
           email : true
        },
        password : {
           required : true,
           minlength : 6
        },
        password_confirm : {
           required : true,
           equalTo : "#password"
        }
      },

      errorClass : "help-inline",
      errorElement : "span",
      highlight : function(element, errorClass, validClass) {
        $(element).parents('.control-group').removeClass('success');
        $(element).parents('.control-group').addClass('error');
      },
      unhighlight : function(element, errorClass, validClass) {
        $(element).parents('.control-group').removeClass('error');
        $(element).parents('.control-group').addClass('success');
      }
    });
  }
});

Update: here is an almost working jsfiddle. Almost working, because I don't know exactly how does jquery-validation work. But the validation code is executed. http://jsfiddle.net/Sly7/3JhzM/

sly7_7
  • 11,961
  • 3
  • 40
  • 54
  • Tnx, I will try it. Where can I find full documents of ALL features of ember js? – Naor Aug 04 '12 at 00:24
  • the main resources is in http://emberjs.com/, docs, guides, and api (which is perhaps the most important to better understand what is going on under the hood, and to find more advanced features). The other resources are on github: https://github.com/emberjs/ember.js/wiki/Links, and finally, in you want to further, I'd say to read the sources, the issues, the PR to stay in touch of what is changing. – sly7_7 Aug 04 '12 at 00:36
  • 1
    Shouldn't I call _super.didInsertElement()? – Naor Aug 04 '12 at 01:22
  • In this case, this will change nothing, as in the parent Class (Ember.View) the didInsertElement function is simply a empty function which does nothing. see https://github.com/emberjs/ember.js/blob/master/packages/ember-views/lib/views/view.js#L1328 . BUT, you're right in the general case, when extending a Class you should call to _super(), otherwise the behavior defined in the parent class will not be applied. Just to be precise, to call the parent function, in ember this is calling this._super(), not _super.function() – sly7_7 Aug 04 '12 at 07:19