Can I bind form inputs to models in Backbone.js without manually tracking blur events?
Solution 1
I'm not sure how SC does it but probably they listen for events too.
window.SomeView = Backbone.View.extend({
events: {
"change input.content": "contentChanged"
},
initialize: function() {
_.bindAll(this, 'contentChanged');
this.inputContent = this.$('input.content');
},
contentChanged: function(e) {
var input = this.inputContent;
// if you use local storage save
this.model.save({content: input.val()});
// if you send request to server is prob. good idea to set the var and save at the end, in a blur event or in some sync. maintenance timer.
// this.model.set({content: input.val()});
}
});
Solution 2
There is an even nicer way to handle this if your model includes lots of properties in it.
SampleView = Backbone.View.extend({
el: "#formEl",
events: {
"change input": "changed",
"change select": "changed"
},
initialize: function () {
_.bindAll(this, "changed");
},
changed:function (evt) {
var changed = evt.currentTarget;
var value = $(evt.currentTarget).val();
var obj = {};
obj[changed.id] = value;
this.model.set(obj);
}
});
There is a reliance on your input elements having an id the same as the what the name of the property in your model is.
Solution 3
I think this is a cleaner (and maybe faster) way to create an object from an input element
changed: function(evt) {
var target = $(evt.currentTarget),
data = {};
data[target.attr('name')] = target.val();
this.model.set(data);
},
without jquery:
changed: function(evt) {
var target = evt.currentTarget,
data = {};
data[target.name] = target.value;
this.model.set(data);
},
Solution 4
Have you tried Backbone.ModelBinder? It´s a nice tool to do what you need: https://github.com/theironcook/Backbone.ModelBinder
Julien
Updated on July 27, 2020Comments
-
Julien almost 4 years
I have a backbone.js app (www.github.com/juggy/job-board) where I want to bind my form inputs directly to my model (a la Sproutcore).
Is it possible with Backbone.js (or other tools) without actually tracking each blur events on the inputs and updating the model manually? This seems like a lot of glue code.
Thanks,
Julien -
Julien over 13 yearsI ended up doing exactly that. I works great so far. As you said it saves on every change on the input. The errors are then displayed immediatly, which is good and bad (unmodified fields would display errors like can't be blank when creating a record).
-
clyfe over 13 years1. one can also try the blur event. 2. I've been pondering on this issue, it would be useful to have a "bindings" array has similar to the "events" hash that specify updates between view parts and model attributes with sync-type parameters (at_change, at_blur etc). say similar to
bindings: [["div#title", "model.title", "change", "<-"], ["input#description", "model.description", "change", "<->"]]
or something like that, it should be pretty easy to implement. -
Julien over 13 yearsI think you can use Handlebar.js as a templating engine. It has this kind of bindings.
-
bradgonesurfing almost 13 yearsI'd like to see this library! Is it available yet?
-
serverpunk almost 13 yearsPosting generated output isn't particularly helpful for CoffeeScript examples of any size - it's ugly and hard to read because the output is intended for an interpreter, not for reading. You'd never write JavaScript that way by hand. For that reason, it baffles me that so many Coffeescript examples do this at the end with the customary "JavaScript - eww!"
-
bradgonesurfing almost 13 yearsYou can't make anyone happy these days. Just post coffeescript raymond complains. Make an edit and include the translation and insin complains. Given that the question was about form binding in backbone my answer was on topic and probably the most idiomatic backbone solution. The question was about jquery and backbone not javascript specifically.
-
Jens Alm almost 13 yearsUnfortunately it isn't ready for general consumption yet, but we hope to have it up by august (gotta ship the product first before I can take the time to clean it up and generalize it properly)
-
UpTheCreek over 12 years@clyfe - hi, shouldn't the events read
"change input.content": "contentChanged"
? Unless I'm missing something. -
btiernay almost 12 yearsWould var obj = {}[changed.id] = value; work better than: var obj = "{\""+changed.id +"\":\""+value+"\"}"; var objInst = JSON.parse(obj);
-
LoG almost 12 yearsYou should never rely on something like:
"{\""+changed.id +"\":\""+value+"\"}"
at least serialize/escape the value string if you must. -
Bill Ortell over 11 yearsOn changed will accommodate more 'html form elements' altogether - moreover 'blur', 'focus', 'onkeyup' - but, if you continue down this path, it's possible for you to just to implement the age-old 'setTimeout' and 'clearTimeout' solution with a delay on whether to trigger the event or not - ESPECIALLY if you have potentially more than one person 'saving' / 'updating' the model at a time... to constantly save on 'onChange' is really a burden on ur server/site. (just sayin')
-
Joe Johnson over 11 yearsYou don't need to pass an object to model.set(). In other words, you could use the following: this.model.set(target.name,target.value);
-
bradgonesurfing about 11 yearsBackbone is old hat these days. You should be using angularjs if you want super powered bindings.
-
chug2k over 10 yearsKind of random question, but does one really need the
_bindAll
? Maybe it's something that's changed since this was written, but I thinkdelegateEvents
takes care of bindingthis
for you. -
JamieJag about 10 yearsThis same idea has been augmented and implemented as a plug-in: lostechies.com/derickbailey/2011/07/24/…
-
John Cromartie about 10 years@porcoesphino excuse me? I don't think I participated on this post.
-
Bodey Baker about 10 years@JohnCromartie, yeah the post isn't there anymore. It was something like "this is an awful way to implement it" without any explanation why. I'll delete my comment but first: Do you still think it's awful? If so, why?