There's this Ajax-heavy, jQuery-based site which I'm about to work on. There hasn't been much structure in the JavaScript code so far (lots of functions at global scope, hard-coded in the HTML onclick="something(args);"
. How can I improve upon that and introduce some structure?
Here's what I've tried. This part is supposed to handle a single element which consists of a text field (span) which is replaced by an input on focus and runs an AJAX update call when a submit button is clicked or enter is pressed.
$(function() {
var box = $('.foobar-info'),
input = box.find('input'),
label = box.find('span#name'),
button = box.find('button');
label.click(start_edit);
button.click(submit);
input.keypress2(KEYS.enter, submit);
function start_edit() {
box.addClass('is-edit');
}
function submit() {
MyAjaxModule.edit_foobar(save_success,
{'id': GLOBAL_FOO_ID, 'value': input.val()});
}
function save_success(data) {
label.text(input.val());
box.removeClass('is-edit');
}
});
Showing and hiding of parts is driven by the CSS:
.foobar-info .state-display {display: inline;}
.foobar-info .state-edit {display: none;}
.foobar-info.is-edit .state-display {display: none;}
.foobar-info.is-edit .state-edit {display: inline;}
So far this achieves:
- keeps the behaviour away from the markup
- keeps relevant behaviour together in one block
On the other hand, I don't think it's testable or particularly easy to re-use with different configurations.
I've attempted to rewrite this to use objects and this.
lookups instead of the big closure, but didn't end up in a code that would please me. For example, this part
label.click(start_edit);
would look like
this.label.click(this.start_edit.bind(this));
which looks really verbose plus it's super-easy to forget the unwieldy .bind(this)
part.
This article served some inspiration, but felt rather hacky to me, mostly because relying on global name lookups.
Questions:
- Any particular problems with my approach except what I've mentioned so far? How can I solve it?
- Is there a canonical way to structure the code which I'll be happy to incorporate?