简体   繁体   中英

Jquery Button Plugin with All Button to toggle checkboxes

I am using jquery button and need to toggle associated checkeboxes but my code hangs the browser. I need 1) On click of all select all 2) on click of select all (all selected) uncheck all checkboxes 3) if all selected clicking on any sub checkboxes should unselect (ALL checkbox) and the one that was clicked as checkbox should remain.

Here is the fiddle .

The issue I am facing is, when i do this process, the checkboxes hangs up making the browser to hang even. for eg: In the fiddle click all, den click any checkbox in between. so after this when again I click on check all, it hangs up

Any help is really appreciated.

    <script>
jQuery(document).ready(function(){
// If checkd all and we click on any sub options make ALL option UNCHECKED

jQuery( ".format" ).buttonset();
    //check ALl checkbox onClick
    $("body").on("click", ".chktaxoall,.chkcmfall", function (e, source) {
        var all = $(this).is(":checked");
        var set = $(this).data("set");

        if (source != "code") {
            $("input[type=checkbox][data-set='" + set + "']:not(this)").each(function () {
                if ($(this).is(":checked") != all) 
                    $(this).trigger("click", "code");
            });
        }
    });

    $("body").on("click", ".wrap_acf input:checkbox", function (e, source) {
        var set = $(this).data("set");
        var allChecked = $(".chkcmfall[data-set='" + set + "']").is(":checked");

        if (source != "code" && allChecked) {
            $(".wrap_acf input[type=checkbox][data-set='" + set + "']:not(this)").trigger("click", "code");
            $(".chkcmfall[data-set='" + set + "']").trigger("click", "code");
        }
        else if (source != "code")
        {
            if ($(".wrap_acf input[type=checkbox][data-set='" + set + "']:checked").length == $(".wrap_acf input[type=checkbox][data-set='" + set + "']").length)
                $(".chkcmfall[data-set='" + set + "']").trigger("click", "code");
        }
    })
    })

</script>

I think this is more or less what you wanted based on your responses to the others. http://jsfiddle.net/drmyersii/27xkkxbw/2/

The major change is here:

$("body").on("click", ".css-checkbox:not(.chkcmfall)", function (e, source) {
    var set = $(this).data("set");
    var all = $(".chkcmfall[data-set='" + set + "']").is(":checked");
    var currentChecked = $(this).is(":checked");

    if(!currentChecked && all)
    {
        $('.css-checkbox[data-set="' + set + '"]').prop('checked', false);
        $(this).prop('checked', true);
        jQuery( ".format" ).buttonset();
    }
});

If this is what you wanted, I can clean up the fiddle for you too.

I played around with your fiddle and figured out your problem: You trigger a click event and pass along "code" as a parameter; you then check on the parameter "code" and click your elements if they aren't sending the parameter "code" -so you're trying to prevent repeated clicks. However, if you add some console.log statements you'll quickly find that the parameter "source" is never defined - it's consistently undefined - so your checkboxes are clicked over and over again.

If you switch to using 2 Events as suggested by Bardo you can really differentiate where your clicks are coming from and you won't experience the lag.

I've forked your fiddle and made the some changes. I think this does what you want it to do and it performs well: http://jsfiddle.net/bmartinelle/brzexyf9/

 $("input[type=checkbox][data-set='" + set + "']").each(function () {
      $(this).trigger("cclick", "code");//trigger a custom click event! you can't pass a parameter to the default click event
 });


 $("body").on("cclick", ".wrap_acf input:checkbox", function (e, source) {
       var set = $(this).data("set");
       var allChecked = $(".chkcmfall[data-set='" + set + "']").is(":checked");

       if(allChecked &! $(this).is(":checked"))
       {
             $(this).click();
       }else if( (!allChecked) && $(this).is(":checked"))
       {
           $(this).click();
        }

  });

EDIT: also support unchecking of the "all" button if an element is unchecked:

$("body").on("click", ".css-checkbox:not(.chkcmfall)", function (e, source) {
         var set = $(this).data("set");
         var all = $(".chkcmfall[data-set='" + set + "']").is(":checked");
         var currentChecked = $(this).is(":checked");

           if(!currentChecked && all)
           {
               //we need to uncheck all:

                $(".chkcmfall[data-set='" + set + "']").prop("checked", false);
                $( ".format" ).buttonset();
           }
 });

There's nothing particularly wrong with your logic. Your slowness is coming from the method you are using setting the checkboxes. You call click() on each of them, which of course, fires off the event again every single time and recalculates everything multiple times. Instead I recommend this:

$("body").on("click",".chkcmfall", function() {
    var set = $(this).data("set");
    var allButtonIsChecked = $(".chkcmfall[data-set='" + set + "']").prop('checked');
    var checkBoxSet = $(".wrap_acf input[type=checkbox][data-set='" + set + "']");
    checkBoxSet.prop('checked',allButtonIsChecked);
    checkBoxSet.each(function () {
        var myLabel = $("label[for='" + $(this).prop('id') + "']");
        myLabel.removeClass('ui-state-active');
        myLabel.removeAttr('aria-pressed');
        if ($(this).prop('checked')){
            myLabel.addClass('ui-state-active');
            myLabel.attr('aria-pressed',"true");
        }
    });
});

$("body").on("click",".wrap_acf input[type=checkbox][data-set]", function () {
    var set = $(this).data("set");
    var allButton = $(".chkcmfall[data-set='" + set + "']");
    if (allButton.prop('checked')){
        allButton.trigger("click");
        $(this).prop('checked',"true");
        var myLabel = $("label[for='" + $(this).prop('id') + "']");
        myLabel.addClass('ui-state-active');
        myLabel.attr('aria-pressed',"true");            
    }

});

Ok, let's see if I'm understanding what you need.

You want a button that, on click checks/unchecks all checkboxes on your page, and you want that, when clicking on a checkbox, if it's checked, it remains checked while all others get's unchecked. It's right?

Ok, in this case you need two events. One for button clicking and another one for checkbox elements clicking.

The first one should be as simple as:

$("#myButton").on("click", function() {
    //If just one or none checkboxes are enabled then button click should enable all
    //otherwise button click should disable all
    var enableAll = $('input[type="checkbox"]:checked').length <= 1;
    $('input[type="checkbox"]').attr("checked", enableAll);
});

Then, for the click on a single checkbox you can just do this: 1) Uncheck all checkboxes 2) Check this checkbox

$('input[type="checkbox"]').on("click", function() {
    $('input[type="checkbox"]').attr("checked", false);
    $(this).attr("checked", true);
});

Probably you'll need to workaround a bit the code, as I'm writting it on the run. The basic idea is that, if I'm understanding correctly your needings, probably your code should be a lot simpler than what you have now... try with this ideas.

I hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM