Advertisement
Guest User

Multi-selection in JavaScript (2022-10-02)

a guest
Oct 2nd, 2022
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 10.77 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <title>Multi-selection in JavaScript</title>
  5.     <meta name="author" content="Elominius from Wikiversity">
  6.  
  7.     <!-- the viewport meta tag magnifies the page on mobile browsers to make it useable there -->
  8.     <meta name="viewport" content="initial-scale=1.0, user-scalable=yes">
  9.  
  10. <style type="text/css">
  11. body {
  12. /* dark theme */ background-color:#343; color:#ddd;
  13. /* modern font pack */ font-family: ubuntu,'noto sans','open sans', calibri, 'segoe ui', 'trebuchet ms', arial, helvetica, verdana, tahoma, 'Bitstream Vera Sans', 'sans-serif';
  14. }
  15. a { color: lightblue; }
  16.  
  17. /* prevent buttons from sticking to each other */
  18. button { margin-top: 1em; }
  19.  
  20. /* Initially grey out containers that are only meant to be shown with JavaScript activated, in order to provide a preview. */
  21. JS_show { opacity:0.2; pointer-events:none; }
  22.     /* for completely hiding it if preferred, use: JS_show { display: none; } */
  23.  
  24. </style>
  25.  
  26. </head>
  27.  
  28. <body>
  29. <JS_show>
  30. <h2>Container 1</h2>
  31. <button class="range_selector" onclick="MultiSelect.select_all(0);">Select all</button>
  32. <button class="range_selector" onclick="MultiSelect.select_none(0);">Select none</button>
  33. <button class="range_selector" onclick="MultiSelect.invert_selection(0);">Invert selection</button>
  34.     <!-- This checks all unchecked boxes and unchecks all checked boxes.  -->
  35. &nbsp;&nbsp;
  36. <button class="range_selector" onclick="MultiSelect.select_range(0);">Select range</button>
  37. <button class="range_selector" onclick="MultiSelect.zebra_select(0);">Zebra select</button>
  38. <!--
  39. "Select range" does select all items between the first and last selected one. First known to be used in the early 2010s by ES File Explorer, a file manager for the Android mobile operating system.
  40.  
  41. "Zebra select" alternately selects ranges of checked boxes. This allows selecting multiple ranges of items.
  42. -->
  43. <br />
  44.  
  45. <item_counter style="display:block;">0 items selected</item_counter>
  46. <form style="column-width:160px;">
  47.   <!-- Note: the "id", "name", and "value" parameters have no effect on the behaviour of the buttons. -->
  48.   <input type="checkbox" id="item1" name="item1" value="1">
  49.   <label for="item1">Item 1</label><br />
  50. </form>
  51. </JS_show>
  52.  
  53. <JS_show>
  54. <h2>Container 2</h2>
  55. <button class="range_selector" onclick="MultiSelect.select_all(1);">Select all</button>
  56. <button class="range_selector" onclick="MultiSelect.select_none(1);">Select none</button>
  57. <button class="range_selector" onclick="MultiSelect.invert_selection(1);">Invert selection</button>
  58. <button class="range_selector" onclick="MultiSelect.select_range(1);">Select range</button>
  59. <button class="range_selector" onclick="MultiSelect.zebra_select(1);">Zebra select</button>
  60. <br />
  61. <item_counter style="display:block;">0 items selected</item_counter>
  62. <form style="column-width:160px;">
  63.   <input type="checkbox" id="item1" name="item1" value="1">
  64.   <label for="item1">Item 1</label><br />
  65. </form>
  66. </JS_show>
  67.  
  68. <noscript>
  69.     <!-- This guidance is shown if JavaScript is not available in the user's browser. -->
  70.     <h2>JavaScript is unavailable</h2>
  71.     <p>To mass-select check boxes, please activate JavaScript or use a web browser that supports it.</p>
  72.     <p>If you are seeing this error in the Android HTML viewer, enter the path to this HTML file into the address bar of the web browser.</p>
  73. </noscript>
  74.  
  75. <hr />
  76. <div id="credit" style="font-size:small;">Originally created by <a href="https://en.wikiversity.org/wiki/User:Elominius">Elominius from Wikiversity</a>. Licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-by-SA 3.0</a>.</div>
  77.  
  78. <script type="text/javascript">
  79.     // reveals "JS_show" containers
  80. if ( document.getElementsByTagName("JS_show")[0] ) /* check if JS_show containers exist */ {
  81.     for (
  82.         count=0; // initiate counter
  83.         count < document.getElementsByTagName("JS_show").length; // count JS_show containers
  84.         count++ // count up. Same as count+=1 and count=count+1.
  85.     ) {
  86.         // restore opacity and/or unhide by overriding CSS at the top using inline CSS:
  87.         document.getElementsByTagName("JS_show")[count].setAttribute("style","display:block; opacity:1; pointer-events:all;");
  88.     }
  89. }
  90.  
  91. // == generate check boxes before running code ==
  92. var main_form=document.getElementsByTagName("form")[0]; // shortcut variable
  93. var checkbox_count=0; // defeating JS Hint error; no functional difference
  94. for (
  95.     checkbox_count=2; // start at the second check box; the first already is already in the HTML for preview to non-JavaScript users
  96.     checkbox_count <= 24; // add check boxes until there are 24.
  97.     checkbox_count++ // count up
  98. ) {
  99. // create element (does not matter which)
  100. main_form.appendChild(document.createElement("span"));
  101.  
  102. // add next box through HTML string
  103. main_form.lastChild.outerHTML='\n  <input type="checkbox" id="item'+checkbox_count+'" name="item'+checkbox_count+'" value="'+checkbox_count+'">\n  <label for="item'+checkbox_count+'">Item '+checkbox_count+'</label><br />';
  104. }
  105.  
  106. // == main code ==
  107.  
  108. var count=0; // Declaring variable for "for" loops to defeat JS Hint error; no functional difference.
  109.  
  110. var MultiSelect = {}; // main object
  111. MultiSelect.item_count=0;
  112.  
  113. // === Select the form with the provided number ===
  114. MultiSelect.select_form = function(form_number) {
  115.     if (!form_number) form_number=0; // set to 0 if undefined.
  116.     MultiSelect.current_form=document.getElementsByTagName("form")[form_number];
  117.  
  118.     // create variables associated with elements inside the form
  119.     MultiSelect.current_boxes=MultiSelect.current_form.getElementsByTagName("input");
  120.     MultiSelect.number_of_boxes=MultiSelect.current_form.getElementsByTagName("input").length-1; // correcting off-by-one error since length is shifted up by one.
  121.     MultiSelect.item_counter /* item counter container */ = document.getElementsByTagName("item_counter")[0];
  122. };
  123.  
  124.     // run this code before every selection
  125. MultiSelect.initialize = function(form_number) {
  126.     MultiSelect.select_form(form_number); // select form out of multiple
  127.     MultiSelect.count_selected = 0; // reset counters to zero
  128.     MultiSelect.count_total = 0;
  129. };
  130.  
  131. // === selection algorithms ===
  132. MultiSelect.select_range = function(form_number) {
  133.     MultiSelect.initialize(form_number); // at the beginning of every selection algorithm
  134.  
  135. // find first checked box; prevent overrunning the last box and causing exception if none selected.
  136. MultiSelect.first_checked_box=0;
  137. while (! MultiSelect.current_boxes[MultiSelect.first_checked_box].checked && MultiSelect.first_checked_box < MultiSelect.number_of_boxes) {
  138.     MultiSelect.first_checked_box++;
  139. }
  140.  
  141. // find last checked box by counting down from end
  142. MultiSelect.last_checked_box=MultiSelect.number_of_boxes;
  143. while (! MultiSelect.current_boxes[MultiSelect.last_checked_box].checked && MultiSelect.last_checked_box > 0 ) {
  144.     MultiSelect.last_checked_box--;
  145. }
  146.  
  147. MultiSelect.current_box=MultiSelect.current_boxes[MultiSelect.first_checked_box+1];
  148. for (
  149.     count=MultiSelect.first_checked_box;
  150.     MultiSelect.current_box != MultiSelect.current_boxes[MultiSelect.last_checked_box];
  151.     count++
  152. ) {
  153.     MultiSelect.current_box = MultiSelect.current_boxes[count];
  154.     MultiSelect.current_box.checked = true; // check boxes
  155.     MultiSelect.count_selected++; // count up for each selection
  156. }
  157.         // update the counter of selected and total check boxes
  158.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  159.         MultiSelect.count_selected, // all boxes, taken from "for" loop
  160.         MultiSelect.number_of_boxes+1 // compensate off-by-one error
  161.     );
  162.  
  163. };
  164.  
  165.  
  166. // select every box
  167. MultiSelect.select_all = function(form_number) {
  168.     MultiSelect.initialize(form_number);
  169.     for (
  170.         count=0;
  171.         count < MultiSelect.number_of_boxes+1;
  172.         count++
  173.     ) { MultiSelect.current_boxes[count].checked=true; }
  174.  
  175.         // update the counter of selected and total check boxes
  176.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  177.         count, // all boxes, taken from "for" loop
  178.         count
  179.     );
  180. };
  181.  
  182. // deselect every box
  183. MultiSelect.select_none = function(form_number) {
  184.     MultiSelect.initialize(form_number);
  185.     for (
  186.         count=0;
  187.         count < MultiSelect.number_of_boxes+1;
  188.         count++
  189.     ) { MultiSelect.current_boxes[count].checked=false; }
  190.  
  191.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  192.         0, // no boxes selected after running
  193.         count // taken from "for" loop
  194.     );
  195. };
  196.  
  197. // deselect selected boxes, select unselected boxes
  198. MultiSelect.invert_selection = function(form_number) {
  199.     MultiSelect.initialize(form_number);
  200.     for (
  201.         count=0;
  202.         count < MultiSelect.number_of_boxes+1;
  203.         count++
  204.     ) {
  205.         if (MultiSelect.current_boxes[count].checked) {
  206.         MultiSelect.current_boxes[count].checked=false;
  207.         } else {
  208.         MultiSelect.current_boxes[count].checked=true;
  209.         MultiSelect.count_selected++;
  210.         }
  211.     }
  212.  
  213.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  214.         MultiSelect.count_selected,
  215.         count // taken from for loop
  216.     );
  217. };
  218.  
  219. // alternately select ranges between selected boxes
  220. MultiSelect.zebra_select = function(form_number) {
  221.     MultiSelect.initialize();
  222. var zebra_select_next=false; // reset to "false"
  223.     for (
  224.         count=0;
  225.         count < MultiSelect.number_of_boxes+1;
  226.         count++
  227.     ) {
  228.         /* switch selection mode */
  229.         // check if box after current one exists to prevent exception from occuring
  230.         while (MultiSelect.current_boxes[count+1] && MultiSelect.current_boxes[count].checked && count < MultiSelect.number_of_boxes) {
  231.             zebra_select_next ? zebra_select_next=false : zebra_select_next=true;
  232.             count++; // skip over already selected boxes
  233.             MultiSelect.count_selected++;
  234.         }
  235.         MultiSelect.current_boxes[count].checked=zebra_select_next;
  236.         if (zebra_select_next) MultiSelect.count_selected++;
  237.     }
  238.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  239.         MultiSelect.count_selected,
  240.         MultiSelect.number_of_boxes+1
  241.     );
  242. };
  243.  
  244.  
  245. MultiSelect.generate_itemcount_string = function(selected,total) {
  246.     if (total == 1) {
  247.     return selected+" out of 1 item selected";
  248.     } else {
  249.     return selected+" out of "+total+" items selected";
  250.     }
  251. };
  252.  
  253. MultiSelect.update_itemcount = function(form_number) {
  254.     MultiSelect.initialize(form_number);
  255.  
  256.     for (
  257.         count=0;
  258.         count < MultiSelect.number_of_boxes;
  259.         count++
  260.     ) {
  261.         // add one for each selected box
  262.         if (MultiSelect.current_boxes[count].checked) MultiSelect.count_selected++;
  263. }
  264.  
  265.     MultiSelect.item_counter.innerHTML=MultiSelect.generate_itemcount_string(
  266.         MultiSelect.count_selected,
  267.         MultiSelect.number_of_boxes + 1 // off-by-one error
  268.     );
  269. };
  270.  
  271. for (
  272.     count;
  273.     count < document.getElementsByTagName("form").length;
  274.     count++
  275. ) { MultiSelect.initialize(count); }
  276.  
  277.     // update item count at each selection
  278. MultiSelect.current_form.onclick=function(){MultiSelect.update_itemcount(0)};
  279.  
  280.     // generate itemcount once to generate the total number of check boxes
  281. MultiSelect.update_itemcount(0);
  282. </script>
  283.  
  284. </body>
  285.  
  286. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement