Module: tools Branch: master Commit: 9fac7e24655bb635ac04ba611ad76fc205c936c6 URL: https://source.winehq.org/git/tools.git/?a=commit;h=9fac7e24655bb635ac04ba61...
Author: Francois Gouget fgouget@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);