From 32886da33dc6b082113b4b3abcc6163d9f7efe7c Mon Sep 17 00:00:00 2001 From: Ross Date: Wed, 17 Dec 2025 15:25:39 +0000 Subject: [PATCH] Add visual indicators for required fields and ARIA attributes in shift forms --- .../templates/rota/partials/shift_form.html | 31 ++++++++++++ .../rota/partials/shift_form_modal.html | 49 ++++++++++++++++--- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/djangorota/djangorota/templates/rota/partials/shift_form.html b/djangorota/djangorota/templates/rota/partials/shift_form.html index f79054f..6a18574 100644 --- a/djangorota/djangorota/templates/rota/partials/shift_form.html +++ b/djangorota/djangorota/templates/rota/partials/shift_form.html @@ -8,3 +8,34 @@ + + diff --git a/djangorota/djangorota/templates/rota/partials/shift_form_modal.html b/djangorota/djangorota/templates/rota/partials/shift_form_modal.html index 873120a..e152ce1 100644 --- a/djangorota/djangorota/templates/rota/partials/shift_form_modal.html +++ b/djangorota/djangorota/templates/rota/partials/shift_form_modal.html @@ -60,12 +60,12 @@ function _close_shift_modal_targets(){ {name: "exclude_days", label: "Exclude days (comma-separated)", type: "list"}, {name: "allow_self", label: "Allow self", type: "bool"} ]}, - "min_summed_grade_by_shifts_per_day": {label: "Min summed grade by shifts per day", fields: [ {name: "shifts", label: "Shifts (comma-separated)", type: "list"}, {name: "min_grade_sum", label: "Minimum grade sum", type: "int"}, {name: "days", label: "Days (comma-separated)", type: "list"} ]}, - "limit_grade_number": {label: "Limit grade number", fields: [ {name: "grade", label: "Grade", type: "int"}, {name: "max_number", label: "Max number", type: "int"} ]}, - "minimum_grade_number": {label: "Minimum grade number", fields: [ {name: "grade", label: "Grade", type: "int"}, {name: "min_number", label: "Min number", type: "int"} ]}, - "require_remote_site_presence": {label: "Require remote site presence", fields: [ {name: "site", label: "Site", type: "text"}, {name: "required_number", label: "Required number", type: "int"} ]}, - "max_shifts_per_week": {label: "Max shifts per week", fields: [ {name: "max_shifts", label: "Max shifts", type: "int"} ]}, - "max_shifts_per_week_block": {label: "Max shifts per week block", fields: [ {name: "week_block", label: "Week block", type: "int"}, {name: "max_shifts", label: "Max shifts", type: "int"} ]} + "min_summed_grade_by_shifts_per_day": {label: "Min summed grade by shifts per day", fields: [ {name: "shifts", label: "Shifts (comma-separated)", type: "list", required: true}, {name: "min_grade_sum", label: "Minimum grade sum", type: "int", required: true}, {name: "days", label: "Days (comma-separated)", type: "list", required: true} ]}, + "limit_grade_number": {label: "Limit grade number", fields: [ {name: "grade", label: "Grade", type: "int", required: true}, {name: "max_number", label: "Max number", type: "int", required: true} ]}, + "minimum_grade_number": {label: "Minimum grade number", fields: [ {name: "grade", label: "Grade", type: "int", required: true}, {name: "min_number", label: "Min number", type: "int", required: true} ]}, + "require_remote_site_presence": {label: "Require remote site presence", fields: [ {name: "site", label: "Site", type: "text", required: true}, {name: "required_number", label: "Required number", type: "int", required: true} ]}, + "max_shifts_per_week": {label: "Max shifts per week", fields: [ {name: "max_shifts", label: "Max shifts", type: "int", required: true} ]}, + "max_shifts_per_week_block": {label: "Max shifts per week block", fields: [ {name: "week_block", label: "Week block", type: "int", required: true}, {name: "max_shifts", label: "Max shifts", type: "int", required: true} ]} }; const textarea = document.getElementById('id_constraints'); @@ -148,6 +148,13 @@ function _close_shift_modal_targets(){ SCHEMAS[t].fields.forEach(f=>{ const fieldWrap = document.createElement('div'); fieldWrap.className='field'; const label = document.createElement('label'); label.className='label'; label.textContent = f.label; + // append required indicator if schema marks this field required + if(f.required){ + if(!label.querySelector('.required-indicator')){ + const span = document.createElement('span'); span.className='required-indicator has-text-danger'; span.textContent=' *'; + label.appendChild(span); + } + } fieldWrap.appendChild(label); const control = document.createElement('div'); control.className='control'; let input; @@ -168,6 +175,7 @@ function _close_shift_modal_targets(){ cb.checked = !!curb; cb.setAttribute('data-field-name', f.name); cb.onchange = syncToData; + if(f.required){ cb.required = true; cb.setAttribute('aria-required','true'); } control.appendChild(cb); fieldWrap.appendChild(control); fieldsContainer.appendChild(fieldWrap); @@ -181,6 +189,7 @@ function _close_shift_modal_targets(){ input = document.createElement('input'); input.className='input'; input.type='text'; input.oninput = syncToData; } input.setAttribute('data-field-name', f.name); + if(f.required){ input.required = true; input.setAttribute('aria-required','true'); } control.appendChild(input); fieldWrap.appendChild(control); fieldsContainer.appendChild(fieldWrap); @@ -248,6 +257,34 @@ function _close_shift_modal_targets(){ })(); +