Backbone Forms with model listeners?

173 views
Skip to first unread message

Varr Willis

unread,
Apr 22, 2014, 1:05:51 AM4/22/14
to backbon...@googlegroups.com
I've attempted to add a listener to the initialize function of my Backbone.Form with no success.

The client side model validation works correctly and then triggers the model.save() which works correctly, but when I send back a JSON response with an error array and a HTTP 400 Response it should trigger the 'error' listener on the Backbone.Form, but it doesn't.

In a prior iteration of the code I used some 'error' and 'success' callbacks in the model.save() which worked fine, but I'd like to be able to trigger the Backbone.Forms built-in validation to render the error message corresponding to the field as it does for client-side validation.

NOTE: This is meant to accept an API key and then confirm the API key is valid on the server before being fully accepted which is why I'd be sending back an error from the server versus handling it in the client-side validation.

See my bolded notes below.

Any help would be greatly appreciated.

=============
    var Admin_Options_Model = Backbone.Model.extend({
        schema: {"imc_opt_apikey": {"type": "Text", "dataType": "text", "title": "API Key", "fieldClass": null}},
        defaults: {"imc_opt_apikey": ""},
        url: ajaxurl + '?action=general_options_form_process',
        validation: {"imc_opt_apikey": [{"minLength": 32, "msg": "Invalid API Key. The key must be at least 32 characters"}]}
    });
    
    var admin_options = new Admin_Options_Model();
    
    var adminOptionsForm = new Backbone.Form({
        fieldsets: [{"legend": "General Options", "fields": ["imc_opt_apikey"]}],
        model: admin_options,
        idPrefix: '',
        initialize: function() {
            //- THIS LISTENER DOESN'T SEEM TO WORK
            this.listenTo(this.model, 'error', this.handleModelError);
        },
        handleModelError: function(model, xhr, options) {
            //- THIS NEVER GETS CALLED WHEN I SEND BACK AN HTTP ERROR RESPONSE CODE (ie 400)
            console.log('In handleModelError()');
        }
    }).render();
    
    Backbone.Validation.bind(adminOptionsForm);
    
    $('div.wrap').append(adminOptionsForm.el);
    
    $('.wrap form.form-horizontal').append("<p class='submit'><input type='submit' id='formsubmit' value='Submit' /></p>");
    
    $('#formsubmit').click(function(e) {
        e.preventDefault();
        var errors = adminOptionsForm.commit({validate: true});
        if (_.isEmpty(errors)) {
            //- I AM FORCING THE SERVER RESPONSE FOR THIS TO BE AN HTTP 400 RESPONSE AND A JSON ARRAY OF: 
            // [{"imc_opt_apikey":"There was an error"}]
            admin_options.save(admin_options.attributes);
        } else {
            console.log('There were errors');
        }
    });
==============

Charles Davison

unread,
Apr 22, 2014, 4:34:33 AM4/22/14
to backbon...@googlegroups.com
I think the problem is that you're defining the initialize() function in the modal instance.  You should extend Backbone.Form and put it there before initializing it:


var AdminOptionsForm = Backbone.Form.extend({
  initialize: function(options) {
    Backbone.Form.initialize.prototype.call(this, options);

    this.listenTo(this.model, 'error', this.handleModelError);
  },
  handleModelError: function(model, xhr, options) {
    console.log('In handleModelError()');
  }
});


var adminOptionsForm = new AdminOptionsForm(...)



--
You received this message because you are subscribed to the Google Groups "Backbone-forms" group.
To unsubscribe from this group and stop receiving emails from it, send an email to backbone-form...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Varr Willis

unread,
Apr 22, 2014, 2:25:52 PM4/22/14
to backbon...@googlegroups.com
Thanks for the quick reply Charlie. 

I implemented your changes but am now getting this in the console:

"TypeError: Backbone.Form.initialize is undefined"

Is there something else I'm missing?

Charles Davison

unread,
Apr 22, 2014, 3:53:12 PM4/22/14
to backbon...@googlegroups.com

Oh yeah, I typed it wrong, it should be

Backbone. Form.prototype.initialize.call(this)

Varr Willis

unread,
Apr 22, 2014, 4:50:26 PM4/22/14
to backbon...@googlegroups.com
That worked! You're a life saver Charlie! Thanks!

One last question, what HTTP response code would you recommend for a server side validation error?  I'm currently using 400, but I'd rather not use a code that triggers an actual browser error.

Charles Davison

unread,
Apr 22, 2014, 5:08:18 PM4/22/14
to backbon...@googlegroups.com

400 sounds right, especially if it's an API you're querying. You can handle the response in the browser to prevent an error

Varr Willis

unread,
Apr 22, 2014, 5:41:42 PM4/22/14
to backbon...@googlegroups.com
Ok great.

I guess I have one other question. I would like to update the form with the errors I get back from the server validation, the same way that the client-side validation updates the form with the errors (see the attachment).

I'm trying something like this:

   var AdminOptionsForm = Backbone.Form.extend({
    initialize: function(options) {
        Backbone. Form.prototype.initialize.call(this, options);
        this.listenTo(this.model, 'error', this.handleModelError);
    },
    handleModelError: function(model, xhr, options) {
        console.log('In handleModelError()');
        console.log(xhr);
        adminOptionsForm.error = xhr.responseJSON;
        adminOptionsForm.render();
    }
});

What's the correct way to do that? I've looked through the documentation here (https://github.com/powmedia/backbone-forms/tree/v0.14.0#validation) and don't see anything like that mentioned.

Varr Willis

unread,
Apr 22, 2014, 6:42:11 PM4/22/14
to backbon...@googlegroups.com
Forgot the attachment.
Backbone.Form.Error.png

Varr Willis

unread,
Apr 22, 2014, 6:58:10 PM4/22/14
to backbon...@googlegroups.com
Nevermind Charlie,

I was able to implement Jeff Garber's suggestion here (https://groups.google.com/d/msg/backbone-forms/DzxYB5rLnHM/L6Tp5jH4U44J) and it worked!

Thanks for your help and your great form framework!


Reply all
Reply to author
Forward
0 new messages