Ronaldinho Learn Coding
Ronaldinho Learn Coding

Reputation: 13824

Radio Button with Jquery and Bootstrap

I have the code here (basically modified from Jquery Checkbox Button by changed $widget.find('input:radio') in JS and type = "radio" in html.

(What it basically does is that, it makes the radio look better and more user friendly than a plain radio box, I want a big button so maybe touchscreen users can have better experience)

enter image description here

HTML

<span class="button-checkbox">
        <button type="button" class="btn btn-lg" data-color="primary">Option 1</button>
        <input type="radio" class="hidden" name="group1" id="op1" checked />
</span>

<span class="button-checkbox">
        <button type="button" class="btn btn-lg" data-color="primary">Option 2</button>
        <input type="radio" class="hidden" name="group1" id="op2"  />
</span>

JS

$(function () {
    $('.button-checkbox').each(function () {

        // Settings
        var $widget = $(this),
            $button = $widget.find('button'),
            $checkbox = $widget.find('input:radio'),
            color = $button.data('color'),
            settings = {
                on: {
                    icon: 'glyphicon glyphicon-check'
                },
                off: {
                    icon: 'glyphicon glyphicon-unchecked'
                }
            };

        // Event Handlers
        $button.on('click', function () {
            $checkbox.prop('checked', !$checkbox.is(':checked'));
            $checkbox.triggerHandler('change');
            updateDisplay();
        });
        $checkbox.on('change', function () {
            updateDisplay();
        });

        // Actions
        function updateDisplay() {
            var isChecked = $checkbox.is(':checked');

            // Set the button's state
            $button.data('state', (isChecked) ? "on" : "off");

            // Set the button's icon
            $button.find('.state-icon')
                .removeClass()
                .addClass('state-icon ' + settings[$button.data('state')].icon);

            // Update the button's color
            if (isChecked) {
                $button
                    .removeClass('btn-default')
                    .addClass('btn-' + color + ' active');
            }
            else {
                $button
                    .removeClass('btn-' + color + ' active')
                    .addClass('btn-default');
            }
        }

        // Initialization
        function init() {

            updateDisplay();

            // Inject the icon if applicable
            if ($button.find('.state-icon').length == 0) {
                $button.prepend('<i class="state-icon ' + settings[$button.data('state')].icon + '"></i> ');
            }
        }
        init();
    });
});

Here is demo: http://jsfiddle.net/9o41oykp/2/

Problem: The checked/unchecked style seems to be working but because this is radio so I need it to be mutual exclusive meaning that only 1 box can be checked (when you check a radio box, the rest (in same group) should become unchecked automatically), but right now as you see you can check more than one box (the style showing it), I need help with jQuery function to make it work.

Upvotes: 1

Views: 1608

Answers (1)

j08691
j08691

Reputation: 207861

I updated the code to work with radio buttons. The problem was, when using this with checkboxes it will work because you can modify a single checkbox without having to worry about the siblings, but with radio buttons you have to run through all the siblings, checking/unchecking each one, which requires looping over the set every time you make a change.

jsFiddle example

(note that in the fiddle I exposed the radio buttons so you could see whether each was checked or not.)

$(function () {
    $('.button-checkbox').each(function () {
        // Settings
        var $widget = $(this),
            $button = $widget.find('button'),
            $checkbox = $widget.find('input:radio'),
            color = $button.data('color'),
            settings = {
                on: {
                    icon: 'glyphicon glyphicon-check'
                },
                off: {
                    icon: 'glyphicon glyphicon-unchecked'
                }
            };

        // Event Handlers
        $button.on('click', function () {
            $checkbox.triggerHandler('change');
            if ($(this).hasClass('btn-default')) {
                $checkbox.prop('checked', !$checkbox.is(':checked'));
                updateDisplay();
            }
        });

        // Actions
        function updateDisplay() {
            $('.button-checkbox').each(function () {
                var isChecked = $(this).find('input:radio').is(':checked');
                // Set the button's state
                $(this).find('button').data('state', (isChecked) ? "on" : "off");
                // Set the button's icon
                $(this).find('button').find('.state-icon')
                    .removeClass()
                    .addClass('state-icon ' + settings[$(this).find('button').data('state')].icon);
                // Update the button's color
                if (isChecked) {
                    $(this).find('button')
                        .removeClass('btn-default')
                        .addClass('btn-' + color + ' active');
                } else {
                    $(this).find('button')
                        .removeClass('btn-' + color + ' active')
                        .addClass('btn-default');
                }
            })
        }
        // Initialization
        function init() {
            updateDisplay();
            // Inject the icon if applicable
            if ($button.find('.state-icon').length == 0) {
                $button.prepend('<i class="state-icon ' + settings[$button.data('state')].icon + '"></i> ');
            }
        }
        init();
    });
});

Upvotes: 1

Related Questions