Jesse
Jesse

Reputation: 408

Backbone can't find input field element from template

I have a view for a form. I load a new model into the view by:

app.fView = new app.FormView({model: new app.aName});
this.$("#formSpace").append(app.fView.render().el);

On the initialize function I expect it to spit initialize form! since the default name value is empty quotes, but instead I get initialize form! undefined suggesting that the form hadn't rendered by the time initialize starts.

Additionally, the createOnEnter function produces the desired output, but the createOnClick returns undefined. I'm baffled.

The View:

app.FormView = Backbone.View.extend({

tagName: 'div',

className: 'nameGenForm',

template: _.template($('#form-template').html()),

events: {
    "keyup #nameEntry"  : "createOnEnter",
    "click #addNameButton"  : "createOnClick",
    "submit #nameEntry"     : "submitFail"
},

render: function() {
    this.$el.html(this.template(this.model.toJSON()));
    return this;
},

initialize: function() {
    this.$namein = this.$("#inputName");        
    console.log('initialize form! ' + this.$("#inputName").val());
},  

submitFail: function() {

    return false;
},

createOnEnter: function(e) {
    console.log('enter! ' + this.$("#inputName").val());

    if (e.keyCode != 13) return;
    if (!this.$namein.val()) return;

    //this.createNew();
},

createOnClick: function(e) {

    console.log('createOnClick ' + this.$namein.val());
    if (!this.$namein.val()) return;
    console.log('clicked! ' + this.$namein.val());

    //this.createNew();
},

createNew: function() {
    app.Names.create({
        name: this.$namein.val(),
        gender: $('#nameEntry .genderButton[class*="active"]').val()
    });

    this.remove();
},

testing: function() {
    this.$("#nameEntry").submit( function() {
        alert('submitted again');
        return false;
    });
    console.log('current value ' + this.$("#inputName").val());
},

clear: function() {
    console.log('removing!');
    this.remove();
}

});

And here is the template

    <script type = "text/template" id = "form-template">
        <form class = "form-horizontal" id = "nameEntry">
            <div class = "control-group">
                <label class = "control-label" for = "inputName">Person's Name</label>
                <div class = "controls">
                    <input type = "text" id = "inputName" placeholder = "Name" value = "<%- name %>"/>
                </div>
            </div>
            <div class = "control-group">
                <label class = "control-label" for = "inputGender">Gender</label>
                <div class = "controls">
                    <div class = "btn-group" data-toggle = "buttons-radio">
                        <button type = "button" class = "genderButton btn <%= gender == 'Male' ? 'active' : '' %>" value = "Male">Male</button>
                        <button type = "button" class = "genderButton btn <%= gender == 'Female' ? 'active' : '' %>" value = "Female">Female</button>
                    </div>
                </div>
            </div>
            <div class = "control-group">
                <div class = "controls">
                    <button type = "button" class = "btn" id = "addNameButton">
                        <%= app.appState.get('action') === 'edit' ? 'Save' : 'Add Name' %>
                    </button>
                </div>
            </div>
        </form>
    </script>

Upvotes: 2

Views: 1909

Answers (1)

Charles Ouellet
Charles Ouellet

Reputation: 6508

Your this.$namein is initialized in your initialize method, which executes before render, so this.$("#inputName"); returns undefined.

Try to put your initialize code at the end of your render method instead.

render: function() {
   this.$el.html(this.template(this.model.toJSON()));
   this.$namein = this.$("#inputName"); 
   return this;
},

Upvotes: 8

Related Questions