ReefPointsBlog

Using Backbone Views With Rails jQuery-ujs

Russ Jones

I often meet Rails developers that have unwittingly jumped on the unobtrusive javascript bandwagon. They throw ':remote => true' on a form and benefit from its conventions, but don't know how to make it really work for them. They're probably still inclined to write out procedural jQuery code the same way they were doing it before jquery-ujs became popular. There's a helpful wiki page that describes its custom events and how to use them, but they probably don't know about it.

Maybe they've worked on improving some client side code with Backbone recently, and maybe they're trying to do things the Backbone way but don't know how to tie that together with existing Rails views. Here's a quick example of how Backbone views can listen for jquery-ujs custom events. You can view a working fiddle here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
var FormView = Backbone.View.extend({
  el: '#form',

  events: {
    // Fired automatically when a file-type input is detected with a
    // non-blank value. You can use this hook to implement a handler that
    // will deal with those non-blank file inputs. Returning false will
    // disallow standard form submission.
    'ajax:aborted:file'     : 'ajaxAbortedFile',

    // Fired when there are required inputs which have been left blank.
    // You can use this handler to deal with those blank required inputs.
    // Returning false will submit the form anyway.
    'ajax:aborted:required' : 'ajaxAbortedRequired',

    // First event fired for any remote enabled form. Stopping this event
    // will cancel the ajax request
    'ajax:before'           : 'ajaxBefore',

    // Fired before the ajax request is sent. Stopping this event will
    // cancel the ajax request. Commonly used to customize certain request
    // headers
    'ajax:beforeSend'       : 'ajaxBeforeSend',

    // Fired after completion, if the HTTP response was a success
    'ajax:success'          : 'ajaxSuccess',

    // Fired after completion, if the server returned an error
    'ajax:error'            : 'ajaxError',

    // Fired after the request has been completed, no matter what outcome
    'ajax:complete'         : 'ajaxComplete'
  },

  ajaxAbortedFile: function(e, elements){
  },

  ajaxAbortedRequired: function(e, elements){
  },

  ajaxBefore: function(e){
  },

  ajaxBeforeSend: function(e, xhr, settings){
  },

  ajaxSuccess: function(e, data, status, xhr){
  },

  ajaxError: function(e, xhr, status, error){
  },

  ajaxComplete: function(e, xhr, status){
  }
});

$(function(){
    window.view = new FormView();
});
1
2
3
4
<form id="form" action="#" method="POST" data-remote="true">
  <p><input type="text" value="..."></p>
  <p><input type="submit" value="Continue &rarr;"></p>
</form>