Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing Backbone to render a form on model change causes form UI errors
    text
    copied!<p>I have a simple view that binds itself to redraw when the model changes as most guides indicate:</p> <pre><code>this.model.bind('change', this.render, this); </code></pre> <p>This view has a form with an input box and a submit button. I am binding to the 'change' event of the input box to change the related item on the model. (I can do this manually or with the ModelBinder project, works the same either way.) </p> <p>A user changes the value in the form input box, then clicks on the submit button. The model is updated, the view and form are re-rendered. The submit button's click event is squashed. </p> <p>I'm using Backbone's events property:</p> <pre><code>events : { 'submit form' : 'save' }, </code></pre> <p>I know that the event is getting ignored because the DOM element that was clicked on is no longer there. I can place a small setTimeout inside of render() to prevent the HTML from being swapped out and things work as expected, but this requires a wait.</p> <p>I can't be the first person to struggle with this - what's the standard way of capturing form 'change' events, updating the model, and redrawing the view without losing some key click or keypress information?</p> <p>Similarly if I have several form items the user is unable to tab between the items after changing the contents as the form is redrawn. </p> <h2>Update 1 - 3 Days later</h2> <p>Still trying to find a good solution. Things I've tried: </p> <ul> <li>moving or cloning the contents of the view to a different area on the page. The click event is still never received. </li> <li>registering the click event with $(document).on or $(document).live instead of the standard view events object</li> <li>separating out the form so that the entire form (inputs and buttons) stays together without being redrawn. Redraw parent elements (which rely on form values) and re-insert already drawn form. This fixes the related issue of being unable to tab across an element, but doesn't fix click events. </li> <li>works as desired in firefox 4, but not ie9 or chrome. *</li> </ul> <h2>Update 2 - With example code</h2> <p>One of the comments asked for some code. I've massively simplified the code into one page and included it below. The actual application is much more complicated. With code as simple below I could just manually re-render parts of the page on change. In the actual application I'm using dustjs templates and even if I don't re-render the form, but do re-render elements that contain the form I have issues clicking on the submit. I'm hoping for a 'pattern' that is typical for backbone applications, including complicated pages and models and forms. </p> <p>Most of the 'demo' apps and even the sites that I've seen using backbone appear to be mostly presentation focused apps that don't actually gather a lot of input from the user. If you know of a good data-collection focused application/demo based on backbone that would be helpful.</p> <p>Code:</p> <pre><code>&lt;!doctype html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;script src="libs/jquery.js"&gt;&lt;/script&gt; &lt;script src="libs/underscore.js"&gt;&lt;/script&gt; &lt;script src="libs/backbone.js"&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;div id="container"&gt;&lt;/div&gt; &lt;script type="text/template" id="edit_user_template"&gt; &lt;h3&gt;Edit User &lt;%=id%&gt; : &lt;%=name%&gt;&lt;/h3&gt; &lt;form&gt; Name: &lt;input type="text" name="name" value="&lt;%=name%&gt;"&gt;&lt;br/&gt; Email: &lt;input type="text" name="email" value="&lt;%=email%&gt;"&gt;&lt;br/&gt; &lt;input type="submit"&gt; &lt;/form&gt; &lt;/script&gt; &lt;script&gt; var UserModel = Backbone.Model.extend({}); var model = new UserModel({id: '1', name:'Joe', email:'a@a.com'}); var UserView = Backbone.View.extend({ events : { 'submit form' : 'save', 'change input' : 'inputChange' }, initialize: function(){ this.model.bind('change', this.render, this); }, render: function(){ var template = _.template($('#edit_user_template').html(), this.model.toJSON()); this.$el.html(template); }, inputChange : function(evt){ var target = $(evt.currentTarget); this.model.set(target.attr('name'), target.val()); }, save : function(event){ console.log('saving'); event.preventDefault(); //this.model.save(); } }); var view = new UserView({model: model, el: '#container'}); view.render(); &lt;/script&gt; &lt;/body&gt; &lt;/html&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload