$('#something').dialog({ buttons: [ { text: 'Apply', click: function() { /* ... */ } }, { text: 'Cancel', click: function() { /* ... */ } }, ] });This has problems:
- It's a confusion of responsibilities between View and Controller roles. Specifying button text is very much "View territory", while defining dialog actions belongs to the Controller role.
- It obstructs internationalization. If one now wanted a German version of the web app, it wouldn't be enough simply to translate everything in the HTML body. One would have to also maintain multiple versions of the page scripts, one for each (natural) language.
$('#something').dialog({ buttons: [ { text: 'Anwenden', click: function() { /* ... */ } }, { text: 'Abbrechen', click: function() { /* ... */ } }, ] });Yuk.
All problems in computer science can be solved by another level of indirection.I figured out a way to separate concerns by (ab)using a button's
class
attribute. Inside the dialog-defining HTML, I explicitly list the buttons in a container marked as being of class
translatable-buttons
:<div class="translatable-buttons"> <button class="translatable-apply" type="button">Apply</button> <button class="translatable-delete" type="button">Delete</button> <button class="translatable-cancel" type="button">Cancel</button> </div>These explicitly marked-up buttons shouldn't be shown in the dialog though, since jQuery UI wants to add the dialog's buttons itself, so apply some CSS:
.translatable-buttons { display: none; }Buttons have to do something when pressed:
var buttonspecs = { 'translatable-apply': { click: function() {}, }, 'translatable-delete': { click: function() {}, }, 'translatable-cancel': { click: function() {}, }, };And finally jQuery UI needs to see this in a language it can understand, so a bit of list processing glues it all together:
var buttons = []; // Grab button text from HTML and add it as a text: property. $.each(buttonspecs, function(i, buttonspec) { buttons.push($.extend({}, buttonspec, { text: $('.translatable-buttons button.'+i, speciesdialog).text() })); }); var speciesdialog = $('#speciesdialog').dialog({ buttons: buttons, });The key is to define the behaviours in the page script and link it to an abstract button name, rather than to concrete button text. This is the purpose for the
translatable-apply
etc. keys in the buttonspecs
object. The $.each
call then merges these button behaviours with the button text read from the DOM and concatenates all the results into the buttons
array.The excerpts shown here are from my chemistry calculator, in the Keq section.