I have very complex forms in my application with update functionality where user may change only few fields click on save button to submit data to server. My application uses backbone, syphon, JQuery and underscoreJs.
What is the best way to control what fields can be sent to server using only with these libraries which can be used across several pages within my application? Something like reusable functionality will be helpful.
I have tried model.changedAttributes()
function which doesn't seem to be working as expected. Most of the times, it is returning false. I have the following code where form data gets serialized using syphon then will be converted into my app specific format to send to API.
formSave: function(e) {
var data = changeToWriteApiFormat(Backbone.Syphon.serialize($(e.currentTarget).closest('form.event_form')[0]));
this.model.clear();
this.model.id = this.parentObj.model.id;
this.model.set(data);
if (this.model.isValid(true)) {
this.model.save(removeObjIndexCollection(data), {
url: this.model.url().replace(gc.readApiUrl, gc.publishApiUrl),
patch: true,
beforeSend: ToolsHelper.setPublishHeader,
success: function(model, response) {
$('#event_success').show();
$('#event_failure').hide();
},
error: function(model, response) {
$('#event_failure').show();
$('#event_success').hide();
}
}
}
model.changedAttributes() does only work if you had some attributes set before on this.model, but since you cleard them via this.model.clear(); it will return false.
Also "save" will only be executed if validate returns valid, you don't have to call isValid extra.
The "patch:true" attribute is correct, but will also work only if you have set the previous values.
try this:
formSave: function(e) {
var data = changeToWriteApiFormat(Backbone.Syphon.serialize($(e.currentTarget).closest('form.event_form')[0]));
this.parentObj.model.save(removeObjIndexCollection(data), {
url: this.model.url().replace(gc.readApiUrl, gc.publishApiUrl),
patch: true,
beforeSend: ToolsHelper.setPublishHeader,
success : function(model, response) {
$('#event_success').show();
$('#event_failure').hide();
},
error : function(model, response) {
$('#event_failure').show();
$('#event_success').hide();
}
}
}
Edit: here an example of changedAttributes:
var model = new Backbone.Model();
model.set({
val1 : 'init',
val2 : 'init'
});
// .. whatever
var newChangesFromForm = {
val2 : "changed",
val1 : 'init' // won't be set, because it's the same value
};
model.on('change', function() {
var changes = model.changedAttributes();
alert(JSON.stringify(changes));
});
model.set(newChangesFromForm);