I'm developing a SPA application where Backbone.js is the main piece of the architecture.
We also have some Twitter Bootstrap flavor among which we have Button groups[1]. So the html has these buttons acting as checkboxes or radios.
In order to transparently bind Backbone models to Backbone views containing these buttons over the use of Backbone.ModelBinder[2] I hacked out the following piece of code:
# Twitter Bootstrap compatibility
addButtonGroupModelBindingSupport = ->
$(@el).one 'mousedown keydown', '.btn-group[data-toggle="buttons-radio"] button', ->
$(@).closest('.btn-group').find('button').prop 'type', 'radio'
installTwitterBootstrapModelBindingSupport = ->
backboneView = Backbone.View
ButtonGroupModelBinderSupportView = Backbone.View.extend
constructor: ->
backboneView.apply @, arguments
addButtonGroupModelBindingSupport.call @
return
Backbone.View = ButtonGroupModelBinderSupportView
installTwitterBootstrapModelBindingSupport()
This code is internal to the module that exports the ModelBinder so it's executed only once. I mixin the behavior I need in Backbone.View so the specious JavaScript is injected in an unobstrusive way.
So I'm telling those buttons that they are not buttons anymore. As far as I could tell Chrome Firefox and IE are ok with that.
Fooled, ModelBinder properly handles that buttons as checkboxes or radios and everything works as needed.
It would be great to hear from more experienced front-end developers if this hack seems too much tricky.
[1] http://twitter.github.com/bootstrap/components.html#buttonGroups
I can't say it's wrong that way if it works for you in all of your target browsers/platforms, but it is certainly unusual. I see a few downsides in this approach:
types
for button are submit
, reset
and button
. See specification here$('input').something()
won't find your hacked buttonAFAIK, the usual way of handling this kind of scenario (where you need the input element but want to have a prettier UI element in the view) is to have both elements synchronized in the page - the pretty styled div and the actual input (invisible). Here are some examples of that: Select2, Fancy Checkboxes and Radio Buttons. Since it's more common, this might be a better approach for your problem, even if it requires a little more js to be written.