Francois Gouget : testbot/cgi: Keep the master checkbox synchronized with the others.

Alexandre Julliard julliard at winehq.org
Tue Apr 19 16:14:43 CDT 2022


Module: tools
Branch: master
Commit: 9fac7e24655bb635ac04ba611ad76fc205c936c6
URL:    https://source.winehq.org/git/tools.git/?a=commit;h=9fac7e24655bb635ac04ba611ad76fc205c936c6

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Tue Apr 19 17:27:56 2022 +0200

testbot/cgi: Keep the master checkbox synchronized with the others.

The master checkbox is automatically checked / unchecked when the other
checkboxes are. This also removes the need to figure out what the
initial state of the master checkbox should be.
And it simplifies the master checkbox HTML code.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 testbot/lib/ObjectModel/CGI/Table.pm | 22 ++++++----------
 testbot/web/Submit.pl                |  6 ++---
 testbot/web/js/table.js              | 49 +++++++++++++++++++++++++++++++-----
 3 files changed, 52 insertions(+), 25 deletions(-)

diff --git a/testbot/lib/ObjectModel/CGI/Table.pm b/testbot/lib/ObjectModel/CGI/Table.pm
index b55fa41..1e33d78 100644
--- a/testbot/lib/ObjectModel/CGI/Table.pm
+++ b/testbot/lib/ObjectModel/CGI/Table.pm
@@ -52,33 +52,25 @@ Generates a master checkbox that changes all the checkboxes with the specified
 =over
 
 =item CbGroup
-A string identifying this group of checkboxes.
+A string identifying this group of checkboxes. The 'cbgroup' attribute of all
+checkboxes in this group must be set to this value:
 
-=item Checked
-True if the initial state should be checked.
+  <input type='checkbox' cbgroup='$CbGroup' name='...'>
 
 =item Attrs
 A string containing extra attributes to be inserted in this master checkbox
-tag. It should not contain the type, checked and onchange attributes.
+tag. It should not contain the type and hidden attributes.
 
 =back
 =back
 =cut
 
-sub GenerateMasterCheckbox($;$$)
+sub GenerateMasterCheckbox($;$)
 {
-  my ($CbGroup, $Checked, $Attrs) = @_;
+  my ($CbGroup, $Attrs) = @_;
 
   $Attrs ||= "";
-  $Checked = $Checked ? " checked" : "";
-  print <<EOF;
-<script type='text/javascript'>
-<!--
-// Only add the master checkbox if JavaScript is enabled
-document.write("<input$Attrs type='checkbox' onchange='SetCheckboxes(this, "$CbGroup");'$Checked>");
-//-->
-</script>
-EOF
+  print "<input$Attrs type='checkbox' hidden='true' mcbgroup='$CbGroup'>\n";
 }
 
 1;
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index cf00ed5..9292d38 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -780,7 +780,6 @@ sub GenerateFields($)
     print "<thead><tr><th class='Record'>";
 
     # Check which VMs are selected and set the master default
-    my $MasterChecked = 1;
     foreach my $VMRow (@{$self->{VMRows}})
     {
       next if ($VMRow->{Incompatible});
@@ -796,10 +795,9 @@ sub GenerateFields($)
       {
         $VMRow->{Checked} = 1;
       }
-      $MasterChecked = 0 if (!$VMRow->{Checked});
     }
 
-    GenerateMasterCheckbox("vmcb", $MasterChecked);
+    GenerateMasterCheckbox("vmcb");
     print "</th>\n";
     print "<th class='Record'>VM Name</th>\n";
     print "<th class='Record'>Options</th>\n";
@@ -815,7 +813,7 @@ sub GenerateFields($)
       my $VM = $VMRow->{VM};
 
       print "<tr class='", ($Even ? "even" : "odd"),
-            "'><td><input class='vmcb' name='$VMRow->{Field}' type='checkbox'";
+            "'><td><input cbgroup='vmcb' name='$VMRow->{Field}' type='checkbox'";
       $Even = !$Even;
       print " checked='checked'" if ($VMRow->{Checked});
       print "/></td>\n";
diff --git a/testbot/web/js/table.js b/testbot/web/js/table.js
index 350dd84..f617912 100644
--- a/testbot/web/js/table.js
+++ b/testbot/web/js/table.js
@@ -16,11 +16,48 @@
  */
 "use strict";
 
-function SetCheckboxes(master, group)
+var mcb_count;
+var mcb_checked;
+
+function SetCheckboxes(e)
+{
+    const master = e.target.closest("input");
+    const group = master.getAttribute("mcbgroup");
+    const selector = 'input[cbgroup="' + group + '"]';
+    document.querySelectorAll(selector).forEach(cb => {
+        cb.checked = master.checked;
+    });
+    mcb_checked[group] = master.checked ? mcb_count[group] : 0;
+}
+
+function UpdateMasterCb(e)
+{
+    const cb = e.target.closest("input");
+    const group = cb.getAttribute("cbgroup");
+    mcb_checked[group] += cb.checked ? 1 : -1;
+
+    const master = document.querySelector('input[mcbgroup="' + group + '"]');
+    master.checked = (mcb_count[group] == mcb_checked[group]);
+}
+
+
+function InitMasterCbs()
 {
-  var cbs = document.getElementsByClassName(group);
-  for (var i = 0; i < cbs.length; i++)
-  {
-    cbs[i].checked = master.checked;
-  }
+    mcb_count = {};
+    mcb_checked = {};
+    document.querySelectorAll("input[mcbgroup]").forEach(master => {
+        const group = master.getAttribute("mcbgroup");
+        mcb_count[group] = mcb_checked[group] = 0;
+        const selector = 'input[cbgroup="' + group + '"]';
+        document.querySelectorAll(selector).forEach(cb => {
+            mcb_count[group]++;
+            if (cb.checked) mcb_checked[group]++;
+            cb.addEventListener('click', UpdateMasterCb);
+        });
+        master.checked = (mcb_count[group] == mcb_checked[group]);
+        master.addEventListener('click', SetCheckboxes);
+        master.hidden = false;
+    });
 }
+
+window.addEventListener('load', InitMasterCbs);




More information about the wine-cvs mailing list