views:

777

answers:

4

I have a form setup so that when you check a checkbox, the relevant UL will expand showing more options based on the choice. It works, but only when the user clicks the label of the checkbox. If the checkbox is clicked, the UL expands as expected, but the box doesn't get checked.

Javascript:

  jQuery(document).ready(function()
  {
     jQuery('.toggleUL').click(function()
     {
        var checkbox = jQuery(this).find('input');
        var ul       = jQuery(this).next('ul');

        if (ul.css('display') == 'block') { ul.find('input').attr('checked', false); }

        if (checkbox.attr('checked') == false)
        {
           checkbox.attr('checked', true);
        }
        else
        {
           checkbox.attr('checked', false);
        }


        ul.slideToggle('slow'); return false;
     });
  });

HTML:

       <label class="toggleUL"><input style="margin-right: 10px" type="checkbox" name="quoteWebsite" id="quoteWebsite" value="xxx" />xxx</label>
       <ul style="list-style-type: none; display: none">
          <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite1" value="xxx" />xxx</label></li>
          <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite2" value="xxx" />xxx</label></li>
          <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite3" value="xxx" />xxx</label></li>
       </ul>

The slideToggle() function wasn't working the way it should. When the box/label was clicked, the UL would expand then retract instantly. The only way I could get it to stop was to add 'return false;' which, of course, causes the checkbox not to check. Hence the checkbox.attr().

Hacked up code, I know. But how can I get the checkbox to work? >.<

A: 

add for="quoteWebsite" property to label

<label class="toggleUL" for="quoteWebsite"><input style="margin-right: 10px" type="checkbox" name="quoteWebsite" id="quoteWebsite" value="xxx" />xxx</label>
   <ul style="list-style-type: none; display: none">
      <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite1" value="xxx" />xxx</label></li>
      <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite2" value="xxx" />xxx</label></li>
      <li style="margin-left: 20px"><label><input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite3" value="xxx" />xxx</label></li>
   </ul>

so when user click on label, it will affect the checkbox and you only need to add click event handler on checkbox.

jQuery(document).ready(function()
{
  jQuery('#quoteWebsite').click(function()
  {
    var checkbox = jQuery(this);
    var ul       = jQuery(this).closest('label').next('ul');

    if (ul.css('display') == 'block') { ul.find('input').attr('checked', false); }

    if (checkbox.attr('checked') == false)
    {
       checkbox.attr('checked', true);
    }
    else
    {
       checkbox.attr('checked', false);
    }


    ul.slideToggle('slow'); return false;
  });
});
Anwar Chandra
That stopped the checkbox from checking at all. Not when clicked on itself or it's label.
spirax
+1  A: 

I would suggest you to attach the click event directly to the checkbox, and use the for attribute on the label element to associate it with the checkbox:

<input type="checkbox" name="quoteWebsite" id="quoteWebsite" value="xxx" />
<label for="quoteWebsite">xxx</label>

I simplified your code:

jQuery(function () {
     jQuery('#quoteWebsite').click(function() {
        var checkbox = jQuery(this),
            ul = jQuery(this).siblings('ul');

        if (ul.css('display') == 'block') {
          ul.find('input').attr('checked', false);
        }

        ul.slideToggle('slow');
     });
});

Now since the click event is attached to the checkbox, you don't need to handle manually the checked attribute toggling nor canceling the event.

Check the above example here.

CMS
That did it. Cheers =]
spirax
A: 

I'd suggest you to use the change event of the checkbox since the click event is not cross browser when dealing with checkboxes. Check the following discussion JQuery Click versus Change

One more thing that I've noticed on the CMS's solution is that it has a small problem. Consider the following scenario: What for example if you checks the checkbox, the options are expanded and for some reason the page gets refreshed. The main checkbox will remain checked but other options would collapse. Then you'll get into a real conflict. When you uncheck the checkbox the options would expand and vise versa.

Below you have the fix. It's much simpler and cleaner. Check it out action.

<label for="quoteWebsite">xxx</label>
<input style="margin-right: 10px" type="checkbox" name="quoteWebsite" id="quoteWebsite" value="xxx" />  

    <ul id="options" style="list-style-type: none; display: none">
        <li style="margin-left: 20px">
            <label>
                <input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite1"
                    value="xxx" />xxx</label></li>
        <li style="margin-left: 20px">
            <label>
                <input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite2"
                    value="xxx" />xxx</label></li>
        <li style="margin-left: 20px">
            <label>
                <input style="margin-right: 10px" type="checkbox" name="quoteWebsite1[]" id="quoteWebsite3"
                    value="xxx" />xxx</label></li>
    </ul>




    $(document).ready(function(){

        $('#quoteWebsite').change(function(){            
            $('#options').slideToggle('slow');
        });

        if ($('#quoteWebsite').is(':checked')) {
            $('#options').slideDown();
        } else {
            $('#options').slideUp();
        }  
    });
SpartanBeg
A: 

hi, i placed two checkbox? my Need is if the both checkbox is checked means how do i get in one variable? if only one checkbox checked means how do i get in one variable?

santhosh