From dd3e928d75ff1ffac402b1d3db0589be801599af Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Tue, 5 Mar 2024 17:52:52 -0600 Subject: [PATCH] Fill in empty dates with valid dates for date picker groups. This builds on #2348, and was requested by @Alex-Jordan in that pull request (see https://github.com/openwebwork/webwork2/pull/2348#pullrequestreview-1918156425). This makes it so that if a date is not filled in, then it will be filled by javascript with a date as needed to ensure it satisfies the usual date requirements on open, reduced scoring, close, and answer dates. The class value is taken into account for this when editing a set for users. This applies on both the problem set detail page and the user detail page. This javascript is also used on the sets manager page when editing set dates where this change does not apply, but it is designed to still work without conflict there. --- htdocs/js/DatePicker/datepicker.js | 40 +++++++++++-------- .../Instructor/ProblemSetDetail.pm | 3 +- .../UserDetail/set_date_table.html.ep | 3 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/htdocs/js/DatePicker/datepicker.js b/htdocs/js/DatePicker/datepicker.js index 767d5ce99b..2cfd887834 100644 --- a/htdocs/js/DatePicker/datepicker.js +++ b/htdocs/js/DatePicker/datepicker.js @@ -25,17 +25,34 @@ const groupRules = [ open_rule, - document.querySelector('input[id="' + name + '.due_date_id"]'), - document.querySelector('input[id="' + name + '.answer_date_id"]') + document.getElementById(`${name}.due_date_id`), + document.getElementById(`${name}.answer_date_id`) ]; - const reduced_rule = document.querySelector('input[id="' + name + '.reduced_scoring_date_id"]'); + const reduced_rule = document.getElementById(`${name}.reduced_scoring_date_id`); if (reduced_rule) groupRules.splice(1, 0, reduced_rule); + // Compute the time difference between the current browser timezone and the course timezone. + // flatpickr gives the time in the browser's timezone, and this is used to adjust to the course timezone. + // Note that this is in seconds. + const timezoneAdjustment = + new Date(new Date().toLocaleString('en-US')).getTime() - + new Date( + new Date().toLocaleString('en-US', { timeZone: open_rule.dataset.timezone ?? 'America/New_York' }) + ).getTime(); + + const classValues = groupRules.map( + (rule) => + parseInt(document.getElementsByName(`${rule.name}.class_value`)[0]?.dataset.classValue || '0') * 1000 - + timezoneAdjustment + ); + const update = () => { for (let i = 1; i < groupRules.length; ++i) { - const prevFieldDate = groupRules[i - 1].parentNode._flatpickr.selectedDates[0]; - const thisFieldDate = groupRules[i].parentNode._flatpickr.selectedDates[0]; + const prevFieldDate = + groupRules[i - 1]?.parentNode._flatpickr.selectedDates[0]?.getTime() || classValues[i - 1]; + const thisFieldDate = + groupRules[i]?.parentNode._flatpickr.selectedDates[0]?.getTime() || classValues[i]; if (prevFieldDate && thisFieldDate && prevFieldDate > thisFieldDate) { groupRules[i].parentNode._flatpickr.setDate(prevFieldDate, true); } @@ -47,15 +64,6 @@ luxon.Settings.defaultLocale = rule.dataset.locale ?? 'en'; - // Compute the time difference between the current browser timezone and the course timezone. - // flatpickr gives the time in the browser's timezone, and this is used to adjust to the course timezone. - // Note that this is in seconds. - const timezoneAdjustment = - new Date(new Date().toLocaleString('en-US')).getTime() - - new Date( - new Date().toLocaleString('en-US', { timeZone: rule.dataset.timezone ?? 'America/New_York' }) - ).getTime(); - const fp = flatpickr(rule.parentNode, { allowInput: true, enableTime: true, @@ -101,12 +109,12 @@ } }) ], - onChange(selectedDates) { + onChange() { if (this.input.value === orig_value) this.altInput.classList.remove('changed'); else this.altInput.classList.add('changed'); }, onClose: update, - onReady(selectedDates) { + onReady() { // Flatpickr hides the original input and adds the alternate input after it. That messes up the // bootstrap input group styling. So move the now hidden original input after the created alternate // input to fix that. diff --git a/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm index 0fbde8b7a1..96e3ab4f94 100644 --- a/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm +++ b/lib/WeBWorK/ContentGenerator/Instructor/ProblemSetDetail.pm @@ -1015,7 +1015,8 @@ sub fieldHTML ($c, $userID, $setID, $problemID, $globalRecord, $userRecord, $fie size => $properties{size} || 5, class => 'form-control-plaintext form-control-sm', 'aria-labelledby' => "$recordType.$recordID.$field.label", - $field =~ /date/ || $field eq 'restricted_release' || $field eq 'source_file' ? (dir => 'ltr') : () + $field =~ /date/ || $field eq 'restricted_release' || $field eq 'source_file' ? (dir => 'ltr') : (), + data => { class_value => $globalValue } ) : '' ) if $forUsers; diff --git a/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep b/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep index 01a2496e96..12fabb25df 100644 --- a/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep +++ b/templates/ContentGenerator/Instructor/UserDetail/set_date_table.html.ep @@ -46,7 +46,8 @@ id => "set.$setID.$field.class_value", readonly => undef, dir => 'ltr', class => 'form-control-plaintext form-control-sm w-auto', size => 16, - defined $userRecord ? ('aria-labelledby' => "set.$setID.${field}_id") : () =%> + defined $userRecord ? ('aria-labelledby' => "set.$setID.${field}_id") : (), + data => { class_value => $globalRecord->$field } =%> % } % if (defined $userRecord) {