patternjavascriptMinor
Handling a text field and submit button with Ajax
Viewed 0 times
handlingfieldajaxwithtextsubmitbuttonand
Problem
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
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.
Showing and hiding of parts is driven by the CSS:
So far this achieves:
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
would look like
which looks really verbose plus it's super-easy to forget the unwieldy
This article served some inspiration, but felt rather ha
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 partlabel.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 ha
Solution
There are two schools of thought
Your example here is programmatic, where JavaScript is binding events after the DOM load. The problem I have with programmatic is, using your words, although it "keeps the behavior away from the markup" it moves the markup into the behavior. The interface that is needed to reuse the same JavaScript is now tied to what is defined on the page. Using declarative, your example being
Here the events can be organized into a class object to remove them from the global namespace. Scope can be controlled by passing in the model as a parameter.
presenter.js
page.html
- Programmatic
- Declarative
Your example here is programmatic, where JavaScript is binding events after the DOM load. The problem I have with programmatic is, using your words, although it "keeps the behavior away from the markup" it moves the markup into the behavior. The interface that is needed to reuse the same JavaScript is now tied to what is defined on the page. Using declarative, your example being
onclick="something(args);", I can more easily follow a Model View Presenter (MVP) pattern where the view simply forwards all events to the Presenter to perform the business logic.Here the events can be organized into a class object to remove them from the global namespace. Scope can be controlled by passing in the model as a parameter.
presenter.js
function Presenter(parameter) {
// private variables
var myVar;
// public method
this.submit = function() {
};
// private method
function doSomething() {
}
}page.html
...
var presenter = new Presenter(...);
...
Click meCode Snippets
function Presenter(parameter) {
// private variables
var myVar;
// public method
this.submit = function() {
};
// private method
function doSomething() {
}
}...
<script type="text/javascript" src=".../presenter.js"></script>
<script type="text/javascript">
var presenter = new Presenter(...);
</script>
...
<button onclick="presenter.onButtonClick();">Click me</button>Context
StackExchange Code Review Q#28030, answer score: 2
Revisions (0)
No revisions yet.