1

I'd like to make a beautiful multiple choice HTML page. I want to have 3 or 4 <div>s including images and/or text, and users should be able to toggle each <div> "on" or "off" by simply clicking anywhere on the <div> (there should be a highlighting effect, if possible with an animation). When the form gets submitted, the server should be sent the state of each <div>, as if it were a checkbox.

I have searched all over the place but could not find something like that. It seems so basic that I probably overlooked something trivial. Any ideas? I already use jQuery and bootstrap, so if there's a simple solution based only on these frameworks, I'd be very happy.

Thanks.

Edit: I don't want the <div>s to move or disappear. I just want a "highlighting" effect, such as changing the background color to blue when the <div> is selected, and back to white when it is unselected.

Jeromy French
  • 11,812
  • 19
  • 76
  • 129
MiniQuark
  • 46,633
  • 36
  • 147
  • 183
  • Will this work? http://api.jquery.com/toggle/ – Scott Dec 07 '12 at 22:04
  • Something like the bootstrap collapsible? http://twitter.github.com/bootstrap/javascript.html#collapse you of course would need custom code to send the state of the divs with a form submit. – Kevin B Dec 07 '12 at 22:06
  • @Scott: Well, toggle seems to show/hide instead of highlighting/"un-highlighting", so not really what I need, although there are some things in common. – MiniQuark Dec 07 '12 at 22:08
  • @KevinB: mmmh, not exactly, I probably need to clarify my question, I'm sorry. I'll edit it. – MiniQuark Dec 07 '12 at 22:10
  • Ah, you don't want to collapse them, you simply want it either highlighted or not highlighted. That should be as simple as a click event that adds/removes (.toggleClass) a class to/from the clicked div while also updating a hidden input with div status. You don't need a plugin for that. – Kevin B Dec 07 '12 at 22:12
  • @KevinB: I guess that's why I'm confused. It seems so simple that I expected it to be a basic widget, but I cannot find it anywhere. Would you mind spelling out your suggestion in an answer? I'd be happy to vote for it if there's no better solution. Thanks! – MiniQuark Dec 07 '12 at 22:18

2 Answers2

5

I would recommend starting with a good HTML base. I would probably use a hidden radio button inside each div and check or uncheck it when the div was clicked. The radio button would be a valid item on the form which would submit the selected value.

HTML:

<div class="choice">
    <input id="choice_1" type="radio" name="choice" value="choice_1" />
    <label for="choice_1">Chicago</label>
</div>

<div class="choice">
    <input id="choice_2" type="radio" name="choice" value="choice_2" />
    <label for="choice_2">Los Angeles</label>
</div>


<div class="choice">    
    <input id="choice_3" type="radio" name="choice" value="choice_3" />
    <label for="choice_3">San Francisco</label>
</div>

​JavaScript:

$(document).ready(function() {
    var choices = $('.choice');

    choices.on('click', function(event) {
        var choice = $(event.target);
        choice
            .find('[name="choice"]')
            .prop('checked', true)
            .trigger('change');
    });

    var inputs = $('.choice input');
    inputs.on('change', function(event) {
        var input = $(event.target);
        var choice = $(this).closest('.choice');

        $('.choice.active').removeClass('active');
        choice.addClass('active');
    });
});​

Demo: jsfiddle

Alternative: if you want multiple selected at once

So with radio buttons only one within the radio button group is active at a time. If that is not the behavior you want, you could use a hidden checkbox and toggle it on and off.

HTML:

<div class="choice">
    <input id="choice_1" type="checkbox" name="choice_1" value="choice_1" />
    <label for="choice_1">Chicago</label>
</div>

<div class="choice">
    <input id="choice_2" type="checkbox" name="choice_2" value="choice_2" />
    <label for="choice_2">Los Angeles</label>
</div>


<div class="choice">    
    <input id="choice_3" type="checkbox" name="choice_3" value="choice_3" />
    <label for="choice_3">San Francisco</label>
</div>

​JavaScript:

$(document).ready(function() {
    var choices = $('.choice');

    choices.on('click', function(event) {
        var choice = $(event.target);
        var input = choice.find('[type="checkbox"]');
        input
            .prop('checked', !input.is(':checked'))
            .trigger('change');
    });

    var inputs = $('.choice input');
    inputs.on('change', function(event) {
        var input = $(event.target);
        var choice = $(this).closest('.choice');

        if (input.is(':checked')) {
            choice.addClass('active');
        }
        else {
            choice.removeClass('active');
        }
    });
});​

Demo: jsfiddle

Cymen
  • 14,079
  • 4
  • 52
  • 72
  • +1, though he didn't say anything about only one div being active at a time. I removed my answer because this one is much better other than that. – Kevin B Dec 07 '12 at 22:50
  • @KevinB Good point -- I'm assuming... I'll update the answer though for the other case. – Cymen Dec 07 '12 at 22:51
  • 1
    Thanks a lot people, you were a great help. Just one thing: I have images in my divs, and with this current code, clicking on the images does not select the div. Replacing "var choice = $(event.target);" by "var choice = $(this).closest('.choice');" fixes the problem. – MiniQuark Dec 08 '12 at 13:20
1

You could do this a couple of ways using a jQuery click function:

// Toggle a class for the div
// - For this you would setup your styles in the CSS for your site 
$('div').click(function(){
    $(this).toggleClass('highlight');
});

// Animate the background-color for the div
// - For this you would need to include the jquery.color plugin
// - https://github.com/jquery/jquery-color
$('div').toggle(function(){
    $(this).animate({backgroundColor: "#aa0000"}, 500);
}, function(){
    $(this).animate({backgroundColor: "#ffffff"}, 500);
});

here's an example jsFiddle: http://jsfiddle.net/PC5ry/

Steve O
  • 5,224
  • 1
  • 24
  • 26