31

Twitter Bootstrap Radio Button Form Inputs

I’ve been loving the Twitter Bootstrap buttons so I came up with a quick technique that turns them into actual working form input elements.

HTML

Just like a normal Boostrap button group, but with a few added attributes.

1
2
3
4
5
<div class="btn-group" data-toggle-name="is_private" data-toggle="buttons-radio" >
  <button type="button" value="0" class="btn" data-toggle="button">Public</button>
  <button type="button" value="1" class="btn" data-toggle="button">Private</button>
</div>
<input type="hidden" name="is_private" value="0" />

Yes, nested names like bookmark[is_private] work just fine.

Javascript

On document load we apply the button logic and state based on the hidden input’s value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
jQuery(function($) {
  $('div.btn-group[data-toggle-name=*]').each(function(){
    var group   = $(this);
    var form    = group.parents('form').eq(0);
    var name    = group.attr('data-toggle-name');
    var hidden  = $('input[name="' + name + '"]', form);
    $('button', group).each(function(){
      var button = $(this);
      button.live('click', function(){
          hidden.val($(this).val());
      });
      if(button.val() == hidden.val()) {
        button.addClass('active');
      }
    });
  });
});

The Result

Twitter Bootstrap Radio Button Form Inputs Result

Notes & Considerations

  • This solution requires javascript in order to work properly so use judgement when implementing it.
  • You may also need to do some styling to get the buttons to look right in some contexts, but thankfully that’s been a relatively painless experience.
  • The type=”button” is required to prevent the form getting submitted when the toggle buttons are clicked.

Summary

Please contact me if you find any issues. I’ve tested this technique over the weekend and I’ve been very happy with it.

2 Trackbacks/Pingbacks

  1. Pingback: web frontend | Annotary
  2. Pingback: 在Django form中使用Bootstrap的Radio Button | Web Develo...

29 Comments

  1. fintara wrote... March 10, 2012

    Thanks a lot!

  2. erwin wrote... March 14, 2012

    Thanks a lot , you saved my day !!!

  3. Justin wrote... March 20, 2012

    Any idea how I could modify this to iterate over an array of form elements, i.e. I have hidden input fields setup like ? Thanks

  4. crancran wrote... April 4, 2012

    Nice trick ! very helpfull for me :)

  5. Gregor wrote... April 15, 2012

    I think you could do it without JavaScript at all. Put standard radio into the tags, make them overlay the entire button and add visibility:hidden.

    See: https://gist.github.com/ebc7ec3be4dc1ca79dce

    What do you think?

  6. Daniel Doezema wrote... April 15, 2012

    @gregor – I tired your idea on jsFiddle and it did not seem to set the value as expected.

    Try forking my jsFiddle and playing around with it.

    http://jsfiddle.net/veloper/XYEjs/

  7. Daniel Doezema wrote... April 15, 2012

    Played with it a bit and it was my bad selector that threw me off. http://jsfiddle.net/veloper/XYEjs/2/ seems to be working, i just fixed the opacity :)

  8. Aymerick wrote... April 29, 2012

    Be careful, on android the inputs are not resizable, so the css technique won’t work.

    Here is my technique: http://jsfiddle.net/c45NC/3/

    The #realform div contains hidden inputs, when you click on buttons it changes their values.
    It works with radio and checkbox.

    Edit: My technique with some optimisations : http://jsfiddle.net/c45NC/4/

  9. Salim Virani wrote... May 31, 2012

    Hi Daniel, great post, it really helped me learn. Searching around, I also found a one-line way to do this which might be useful in some cases:

    $(‘button[name="rating"].active’).val();

    An explanation is here: http://stackoverflow.com/a/10275763/240825

  10. Tony wrote... June 8, 2012

    Good stuff. Thanks.

  11. ghostdawg wrote... July 15, 2012

    Thanks for this, saved me some hours – using the default bootstrap example in the docs caused the form to post back every time a radio button was clicked – adding type=”button” solved this for me, thanks to you.

  12. John wrote... July 25, 2012

    Thanks!

  13. Adam wrote... August 16, 2012

    Thanks for this, that just saved me a load of time.

  14. Lucas Freitas wrote... September 17, 2012

    Thanks, won my day.

  15. melanke wrote... October 2, 2012

    I like “Jquery UI Bootstrap”

  16. Peter Drinnan wrote... October 12, 2012

    Wow! that is simple. I was thinking it would require a whole plugins.

  17. John wrote... October 15, 2012

    Thanks for this.

    A small change is required for Jquery 1.8.2 — change…

    $(‘div.btn-group[data-toggle-name=*]‘).each(function()

    to

    $(‘div.btn-group[data-toggle-name]‘).each(function()

  18. Chikkensoop wrote... October 18, 2012

    Daniel your updated example at http://jsfiddle.net/veloper/XYEjs/2/ doesn’t seem to be working, just gives undefined in the alerts?

  19. Igor wrote... November 9, 2012

    Thanks a alot, mate :)

  20. Marius wrote... November 25, 2012

    Hi, great tip, thanks for it, but to make it work I had to change…
    var hidden = $(‘input[name="' + name + '"]‘, form);
    to
    var hidden = $(‘input[name="' + name + '"]‘, group);

    Not sure why you need the reference of the parent form in the first place…

  21. maczor wrote... November 28, 2012

    thx man – it’s nice to find something done exactly like you wanted it

  22. josh wrote... December 4, 2012

    How did you do that tag input part? With the input box and the buttons with the x’s? Did that use the bootstrap typeahead?

  23. Daniel Doezema wrote... December 5, 2012

    @john – Heh, that little tidbit was annoying to get working. I ended up using a different jqueryui based plugin to do the typeahead. I then just mashed in bootstrap’s .btn CSS until it started to look respectable. It also required modification of the js plugin source to get some custom classes in.

    It’s a total hack job, but hey… it looks good right :)

  24. Sergey Makridenkov wrote... December 17, 2012

    Hi, I write small plugin for that, it easier from view – https://gist.github.com/4322304. Hidden input created automatically.

  25. Michael Calkins wrote... December 18, 2012

    I re did this a bit for just normal .btn
    http://jsfiddle.net/3dyw7/

  26. Lionel Abderemane wrote... January 25, 2013

    Thanks a lot !

  27. raveren wrote... February 14, 2013

    Rewritten for jquery 1.8+, buttons may be in different form (single input per page) and data attribute changed from data-toggle-name to data-input

    $('.btn-group[data-input]').each(function() {
    	var hidden = $('[name="' + $(this).data('input') + '"]');
    	$(this).on('click', '.btn', function() {
    		hidden.val($(this).val());
    	}).find('.btn').each(function() {
    		$(this).toggleClass('active', $(this).val() == hidden.val())
    	});
    });
    
  28. Michael Calkins wrote... April 25, 2013

    A better version of my own:

    $(".btn-input").live('click', function(){
        var btn         = $(this),
            container   = btn.parent(),
            name        = btn.data('toggle-name'),
            hidden      = container.find('input[name=' + name + ']'),
            value       = btn.attr('value');
        hidden.val(value);
        $(".btn-input[data-toggle-name=" + name + "]").removeClass('active btn-primary');
        btn.addClass('active btn-primary');
    });
    
  29. tennisplayerinlr wrote... May 15, 2013

    I would just like to give two thumbs up to raveren’s 02/14/2013 update. Also thanks for this post. the original solution worked fine, and then some discussion have really fine tuned it some more. thx everyone. :)

Comment On This Article...