Topic
  • 7 replies
  • Latest Post - ‏2013-09-18T15:47:53Z by Codeoline
Codeoline
Codeoline
141 Posts

Pinned topic Multiple delete with single check

‏2013-09-12T18:25:22Z |

I have a view page that has an added column of check boxes that delete selected rows. 

Is there a way to add a single check box in the  column row header next to the delete button that would add a check to all rows on the page.

Say i had 100 rows on the page and i wanted to delete 90 of them. Rather than placing a check in 90 different rows I would like to check a single box and doing so would then place a check mark in all 100 rows.  I could then un-check the 10 i do not wish to delete.

Please see the attached model.

Thank You

  • Codeoline
    Codeoline
    141 Posts
    ACCEPTED ANSWER

    Re: Multiple delete with single check

    ‏2013-09-18T15:47:53Z  
    • mburati
    • ‏2013-09-17T18:22:48Z

    I guess that depends on if you're just selecting/deselecting the visible checkboxes on the page (in which case you could just look at the current checkboxes value) or if you're storing state of the checkboxes on the server in variable state across paging actions and then executing a delete later based on that server state, in which case you'd want to check and toggle that actual server state which would be more work.

     

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

     

    I got this figured out and i think it is working correctly.

    Thanks for pointing me in the right direction

     

    var boxeschecked = 0;
    var boxesunchecked = 0;
    var checkall = true;
    var uncheckall = false;


    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){
          if(elem.checked==true) boxeschecked = boxeschecked + 1;
          else boxesunchecked = boxesunchecked + 1;
    });

    // alert("checked " + boxeschecked.toString() + " unchecked " + boxesunchecked.toString());

    if (boxeschecked>0) checkall = true;
    if (boxeschecked>0) uncheckall = true;
    if (boxesunchecked==0) checkall = false;

    if (uncheckall){
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=false;elem.onclick.apply(elem);});
    }
    else if (checkall){
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true;elem.onclick.apply(elem);});
    }
    else {
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=false;elem.onclick.apply(elem);});
    }
     

  • mburati
    mburati
    2560 Posts

    Re: Multiple delete with single check

    ‏2013-09-13T13:14:29Z  

    Hmm,  that seems like a fairly simple question, but I'm afraid I don't have a super simple answer, just multiple answers that should hopefully help a bit.

     - The first part is typically straightforward Javascript and a web search of "Check all checkboxes in a form via Javascript" (or JS) should get you a number of answers showing you how to do that in Javascript.   If you're not a JS developer, the JS involved may take a bit of time to follow and tweak.

     - Knowing that WEF is using Dojo already and that Dojo provides convenience methods for querying all elements of specified types or class in a form you could do a web search for "dojo query all checkboxes in a form" and find a number of one liners that do both a query and iterate over the results.

     - The dojo query JS to find all inputs of type checkbox in the current form (where JS is running) is something like this:

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true});

     

    There are a couple of caveats that WEF and specifically WEF checkboxes and paging introduce into the equation though:

     - A caveat is that WEF checkboxes, in order to work around the ugly way that HTML checkboxes work (where they don't submit anything if unchecked) pairs up a second input type="hidden" element with each checkbox, and that's the one that the server side logic depends on, where the checkbox input is really there to just run an onclick handler that sets the associated hidden cb input to true/false/whatever based on whether the user clicked on the checkbox to enable or disable it.    So, if all you do is set the checkboxes checked value via the above JS then the onclick never gets called and the original hidden input gets sent to the server.

     - One might think that you could then just call elem.click()  after setting its clicked value, to trigger the JS, and that would be partly true

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true; elem.click()});

    BUT, the problem with that is that the onclick handler references "this"  and by calling the click from this other JS, you're implicitly changing what "this" points to  (JS "this" references are a little tricky to get used to if you're not a JS developer), so it ends up setting the value on the wrong "this".

    SO,  how do you trigger the onclick handler that WEF had added to the checkbox AND have it execute correctly?   A quick web search for how to apply an onclick vis JS and get the this reference correct suggests to refer to the onclick function of the element directly and then call that event handler's "apply" method, "passing" the element itself, so that the this instance reference associated with the event handler is correct, in other words, like this:

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true;elem.onclick.apply(elem);});

     

    Now you have the JS that should do what you want, you need to get it on the page.   For your particular sample,  I added a "Button" builder:

     - Set the page to deleteMultipleList

     - Set the location technique to "Relative to named tag" and Placement to "After"

     - Set the Tag to put the button on to deleteMultipleDelCheckedButton

     - Set "New Tag Name" to "selectAll"

     - Set "Label" to "Select All"

     - Set Action Type to "Run a Script"

     - Set the script to the above final version of the dojo query that sets each cb element checked and then applies its onclick handler, passing the element ref to the onclick handler so the "this" reference in the inline onclick handler JS will be correct.

     - Ran it with the Chrome debugger open to watch the JS go by AND what inputs are submitted when you click the delete button after clicking select all.   If you leave off the JS that applies the onclick handler OR you just call elem.click() you would see that the form submit submits checked checkboxes but false for the hidden inputs.  With the JS that applies the onclick handler correct though, youll see the hidden cb inputs set to true when the cb elements' clicked values are programmatically set to true before applying the onclick handler.

    Another Caveat:

     - You have paging enabled in your sample model so you really only have 3 checkboxes per form, not 90 or 100, so a select all is only going to select the checkboxes in the actual form in the browser, which is 3 rows worth.   To do 100, you would have to have the 100 in the form, since each time to go to the next page of rows, you're really displaying a new form with new inputs.

     - One option is to just show more rows, so you can delete more at a time.

     - Another option is to figure out how to create a separate button that calls a server acction that sets a to-be-deleted input for every row on the server side and then a button that applies that when you're ready rather than the one generated here which just deletes the ones specified in the current form.    That would take quite a bit more time to write up than I have at the moment while answering what I thought was going to be a quick question before I remembered the caveats.

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.
    Updated on 2013-09-13T13:20:18Z at 2013-09-13T13:20:18Z by mburati
  • Codeoline
    Codeoline
    141 Posts

    Re: Multiple delete with single check

    ‏2013-09-16T19:41:02Z  
    • mburati
    • ‏2013-09-13T13:14:29Z

    Hmm,  that seems like a fairly simple question, but I'm afraid I don't have a super simple answer, just multiple answers that should hopefully help a bit.

     - The first part is typically straightforward Javascript and a web search of "Check all checkboxes in a form via Javascript" (or JS) should get you a number of answers showing you how to do that in Javascript.   If you're not a JS developer, the JS involved may take a bit of time to follow and tweak.

     - Knowing that WEF is using Dojo already and that Dojo provides convenience methods for querying all elements of specified types or class in a form you could do a web search for "dojo query all checkboxes in a form" and find a number of one liners that do both a query and iterate over the results.

     - The dojo query JS to find all inputs of type checkbox in the current form (where JS is running) is something like this:

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true});

     

    There are a couple of caveats that WEF and specifically WEF checkboxes and paging introduce into the equation though:

     - A caveat is that WEF checkboxes, in order to work around the ugly way that HTML checkboxes work (where they don't submit anything if unchecked) pairs up a second input type="hidden" element with each checkbox, and that's the one that the server side logic depends on, where the checkbox input is really there to just run an onclick handler that sets the associated hidden cb input to true/false/whatever based on whether the user clicked on the checkbox to enable or disable it.    So, if all you do is set the checkboxes checked value via the above JS then the onclick never gets called and the original hidden input gets sent to the server.

     - One might think that you could then just call elem.click()  after setting its clicked value, to trigger the JS, and that would be partly true

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true; elem.click()});

    BUT, the problem with that is that the onclick handler references "this"  and by calling the click from this other JS, you're implicitly changing what "this" points to  (JS "this" references are a little tricky to get used to if you're not a JS developer), so it ends up setting the value on the wrong "this".

    SO,  how do you trigger the onclick handler that WEF had added to the checkbox AND have it execute correctly?   A quick web search for how to apply an onclick vis JS and get the this reference correct suggests to refer to the onclick function of the element directly and then call that event handler's "apply" method, "passing" the element itself, so that the this instance reference associated with the event handler is correct, in other words, like this:

    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true;elem.onclick.apply(elem);});

     

    Now you have the JS that should do what you want, you need to get it on the page.   For your particular sample,  I added a "Button" builder:

     - Set the page to deleteMultipleList

     - Set the location technique to "Relative to named tag" and Placement to "After"

     - Set the Tag to put the button on to deleteMultipleDelCheckedButton

     - Set "New Tag Name" to "selectAll"

     - Set "Label" to "Select All"

     - Set Action Type to "Run a Script"

     - Set the script to the above final version of the dojo query that sets each cb element checked and then applies its onclick handler, passing the element ref to the onclick handler so the "this" reference in the inline onclick handler JS will be correct.

     - Ran it with the Chrome debugger open to watch the JS go by AND what inputs are submitted when you click the delete button after clicking select all.   If you leave off the JS that applies the onclick handler OR you just call elem.click() you would see that the form submit submits checked checkboxes but false for the hidden inputs.  With the JS that applies the onclick handler correct though, youll see the hidden cb inputs set to true when the cb elements' clicked values are programmatically set to true before applying the onclick handler.

    Another Caveat:

     - You have paging enabled in your sample model so you really only have 3 checkboxes per form, not 90 or 100, so a select all is only going to select the checkboxes in the actual form in the browser, which is 3 rows worth.   To do 100, you would have to have the 100 in the form, since each time to go to the next page of rows, you're really displaying a new form with new inputs.

     - One option is to just show more rows, so you can delete more at a time.

     - Another option is to figure out how to create a separate button that calls a server acction that sets a to-be-deleted input for every row on the server side and then a button that applies that when you're ready rather than the one generated here which just deletes the ones specified in the current form.    That would take quite a bit more time to write up than I have at the moment while answering what I thought was going to be a quick question before I remembered the caveats.

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

    Thank You so far.  This is working perfectly. 

    I am just wondering if it is possible to toggle the check boxes checked and unchecked each time the "Select All" button is clicked?  Say i clicked the "Select All" button and it checked all on the form, I then i decided i only wanted to check a select few.  I would like to click the "Select All" button again which would un-check them all rather than add another button to un-check them all. 

    Also

    Is it possible to edit the size of the "Delete" button that comes with the check boxes so it looks more like the "Select All" button that i created?

    Attachments

  • mburati
    mburati
    2560 Posts

    Re: Multiple delete with single check

    ‏2013-09-17T11:47:55Z  
    • Codeoline
    • ‏2013-09-16T19:41:02Z

    Thank You so far.  This is working perfectly. 

    I am just wondering if it is possible to toggle the check boxes checked and unchecked each time the "Select All" button is clicked?  Say i clicked the "Select All" button and it checked all on the form, I then i decided i only wanted to check a select few.  I would like to click the "Select All" button again which would un-check them all rather than add another button to un-check them all. 

    Also

    Is it possible to edit the size of the "Delete" button that comes with the check boxes so it looks more like the "Select All" button that i created?

    Yes, if you look at the script for the select all button you can see the javascript it's using and then change it to look at the current value and set it to the opposite rather than always setting it to true.

     

    As for sizes of anything on the page, it's just HTML and CSS so yes you should be able to change it.  Use a browser inspector/debugger (Firebug, Chrome's right-click and inspect element or IE's F12 Developer TOols) to see what CSS is being applied to the current page so you'll have an idea how you want to change it (eg, apply an overriding style directly or your own CSS stylesheet for all the styles, possibly set via theme builder)..

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.
  • Codeoline
    Codeoline
    141 Posts

    Re: Multiple delete with single check

    ‏2013-09-17T13:05:52Z  
    • mburati
    • ‏2013-09-17T11:47:55Z

    Yes, if you look at the script for the select all button you can see the javascript it's using and then change it to look at the current value and set it to the opposite rather than always setting it to true.

     

    As for sizes of anything on the page, it's just HTML and CSS so yes you should be able to change it.  Use a browser inspector/debugger (Firebug, Chrome's right-click and inspect element or IE's F12 Developer TOols) to see what CSS is being applied to the current page so you'll have an idea how you want to change it (eg, apply an overriding style directly or your own CSS stylesheet for all the styles, possibly set via theme builder)..

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

    The current value for each checkbox or do I create a variable and set it to toggle back and forth from true to false?

  • mburati
    mburati
    2560 Posts

    Re: Multiple delete with single check

    ‏2013-09-17T18:22:48Z  
    • Codeoline
    • ‏2013-09-17T13:05:52Z

    The current value for each checkbox or do I create a variable and set it to toggle back and forth from true to false?

    I guess that depends on if you're just selecting/deselecting the visible checkboxes on the page (in which case you could just look at the current checkboxes value) or if you're storing state of the checkboxes on the server in variable state across paging actions and then executing a delete later based on that server state, in which case you'd want to check and toggle that actual server state which would be more work.

     

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

     

  • Codeoline
    Codeoline
    141 Posts

    Re: Multiple delete with single check

    ‏2013-09-17T19:35:45Z  
    • mburati
    • ‏2013-09-17T18:22:48Z

    I guess that depends on if you're just selecting/deselecting the visible checkboxes on the page (in which case you could just look at the current checkboxes value) or if you're storing state of the checkboxes on the server in variable state across paging actions and then executing a delete later based on that server state, in which case you'd want to check and toggle that actual server state which would be more work.

     

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

     

    I know very little about JS and i appreciate all of the help.               

    What about this scenario? I have clicked the "Select All" button and now all of the checkboxes are checked.  I then decided to physically uncheck 2 of the checkboxes.   Now i have decided that i want to uncheck all of them by clicking the "Select All" button.  I dont want the 2 that i physically unchecked to now be set to checked.  Can you give me any pointers on how to accomplish this? I added this code to the "Select All " button but it does not work. 

    var currentValue = true;
     {
     if (currentValue == true){
     dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true;elem.onclick.apply(elem);});
     currentValue = false;
      }
     else {
      dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=false;elem.onclick.apply(elem);});
     currentvalue = true;
     }}

  • Codeoline
    Codeoline
    141 Posts

    Re: Multiple delete with single check

    ‏2013-09-18T15:47:53Z  
    • mburati
    • ‏2013-09-17T18:22:48Z

    I guess that depends on if you're just selecting/deselecting the visible checkboxes on the page (in which case you could just look at the current checkboxes value) or if you're storing state of the checkboxes on the server in variable state across paging actions and then executing a delete later based on that server state, in which case you'd want to check and toggle that actual server state which would be more work.

     

     

    I hope that info helps,
    ..Mike Burati 
    The postings on this site are my own and do not necessarily represent the positions, strategies, or opinions of IBM.

     

    I got this figured out and i think it is working correctly.

    Thanks for pointing me in the right direction

     

    var boxeschecked = 0;
    var boxesunchecked = 0;
    var checkall = true;
    var uncheckall = false;


    dojo.query("input[type=checkbox]", this.form).forEach(function(elem){
          if(elem.checked==true) boxeschecked = boxeschecked + 1;
          else boxesunchecked = boxesunchecked + 1;
    });

    // alert("checked " + boxeschecked.toString() + " unchecked " + boxesunchecked.toString());

    if (boxeschecked>0) checkall = true;
    if (boxeschecked>0) uncheckall = true;
    if (boxesunchecked==0) checkall = false;

    if (uncheckall){
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=false;elem.onclick.apply(elem);});
    }
    else if (checkall){
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=true;elem.onclick.apply(elem);});
    }
    else {
          dojo.query("input[type=checkbox]", this.form).forEach(function(elem){elem.checked=false;elem.onclick.apply(elem);});
    }