This Week in Janky Javascript...

While working on our recent project, gettogethr, our team saw a number of opportunities to make the user experience feel much quicker and more customizable. Of course, in order to see these through, we knew we’d need to call upon our new friend Javascript and her metal-armed brother (A)JAX.

A la Google Docs, we wanted to provide the ability to change the title of a shared event on the fly, ensuring the name change persists in the database and upon page reload.

The first step to achieve this effect was to build a jQuery double-click listener on the title element which is initiated upon page load. When activated, a text box input is created with some attributes (in order to show the old/exisiting title) and replaces the title html element on the page.

1
2
3
4
5
6
7
8
9
10
11
Gathering.prototype.addTitleListener = function( ) {
  this.$gatheringTitle.dblclick(function( ) {
    var oldTitle = this.$gatheringTitle.text( );
    var textbox = document.createElement('input');
    textbox.type = 'text';
    textbox.id = 'title';
    textbox.value = oldTitle;
    this.$gatheringTitle.html(textbox);
    $('#title').on('keypress', titleKeypressListener.bind(this) );
  }.bind(this) );
};

Next, we assign a jQuery listener to the keypresses on that newly created input box (‘#title’). When the enter key is hit (e.keyCode === 13), the current value of the text box and the id of the current event (captured via an identifying id) are assigned to variables to be used in an AJAX call to our gatherings controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var titleKeypressListener = function(e) {
  if(e.keyCode === 13) {
    var title = $('#title').val( );
    var URL =  this.gatheringId;
    $.ajax({
      method: 'patch',
      url: URL,
      dataType: 'script',
      data: {
        gathering: {
          id: this.gatheringId,
          title: title
        }},
      success: function( ){
        this.$gatheringTitle.html($('#title').val( ));
      }.bind(this)
    });
  }
};

This AJAX call sends the newly entered title, via patch request, to our controller. There, we identify the correct gathering via the established params, and update the object with our new title (gathering_params). Finally, upon success, we replace the text input element with the new title.

1
2
3
4
5
6
7
8
9
10
def update
  @gathering = Gathering.find(params [ :id ] )
  respond_to do | format |
    if @gathering.update(gathering_params)
        ....
      format.js { head 204 }
        ....
    end
  end
end

From here, we could changing the title as many times as you want because the double click listener is still active.

Resources: