diff --git a/app/assets/javascripts/fileUpload.js b/app/assets/javascripts/fileUpload.js index ea6c7ac62..19c53b971 100644 --- a/app/assets/javascripts/fileUpload.js +++ b/app/assets/javascripts/fileUpload.js @@ -1,34 +1,69 @@ +function announceUploadStatusFromElement() { + const srRegion = document.getElementById('upload-status-live'); + const success = document.getElementById('upload-success'); + const error = document.getElementById('upload-error'); + + if (!srRegion) return; + + const message = error?.textContent || success?.textContent; + + if (message) { + srRegion.textContent = ''; + setTimeout(() => { + srRegion.textContent = message + '\u00A0'; // add a non-breaking space + srRegion.focus(); // Optional + }, 300); + } +} + + +// Exported for use in tests +function initUploadStatusAnnouncer() { + document.addEventListener('DOMContentLoaded', () => { + announceUploadStatusFromElement(); + }); +} + (function(Modules) { "use strict"; Modules.FileUpload = function() { - this.submit = () => this.$form.trigger('submit'); - this.showCancelButton = () => $('.file-upload-button', this.$form).replaceWith(` - Cancel upload - `); - - this.start = function(component) { - - this.$form = $(component); - - // The label gets styled like a button and is used to hide the native file upload control. This is so that - // users see a button that looks like the others on the site. - - this.$form.find('label.file-upload-button').addClass('usa-button margin-bottom-1').attr( {role: 'button', tabindex: '0'} ); - - // Clear the form if the user navigates back to the page - $(window).on("pageshow", () => this.$form[0].reset()); - - // Need to put the event on the container, not the input for it to work properly - this.$form.on( - 'change', '.file-upload-field', - () => this.submit() && this.showCancelButton() - ); - + this.showCancelButton = () => { + $('.file-upload-button', this.$form).replaceWith(` + + `); }; - }; + this.start = function(component) { + this.$form = $(component); + this.$form.on('click', '[data-module="upload-trigger"]', function () { + const inputId = $(this).data('file-input-id'); + const fileInput = document.getElementById(inputId); + if (fileInput) fileInput.click(); + }); + + $(window).on("pageshow", () => this.$form[0].reset()); + + this.$form.on('change', '.file-upload-field', () => { + this.submit(); + this.showCancelButton(); + }); + }; + }; })(window.GOVUK.Modules); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = { + announceUploadStatusFromElement, + initUploadStatusAnnouncer + }; +} + +if (typeof window !== 'undefined') { + initUploadStatusAnnouncer(); +} diff --git a/app/assets/javascripts/fullscreenTable.js b/app/assets/javascripts/fullscreenTable.js index cef792052..d4062e71c 100644 --- a/app/assets/javascripts/fullscreenTable.js +++ b/app/assets/javascripts/fullscreenTable.js @@ -22,7 +22,6 @@ this.$scrollableTable .on('scroll', this.toggleShadows) .on('scroll', this.maintainHeight) - .on('focus blur', () => this.$component.toggleClass('js-focus-style')); if ( window.GOVUK.stickAtBottomWhenScrolling && @@ -37,11 +36,11 @@ this.insertShims = () => { - const attributesForFocus = 'role aria-labelledby tabindex'; + const attributesForFocus = 'role aria-labelledby'; let captionId = this.$table.find('caption').text().toLowerCase().replace(/[^A-Za-z]+/g, ''); this.$table.find('caption').attr('id', captionId); - this.$table.wrap(`
`); + this.$table.wrap(`
`); this.$component .append( diff --git a/app/assets/sass/uswds/_legacy-styles.scss b/app/assets/sass/uswds/_main.scss similarity index 96% rename from app/assets/sass/uswds/_legacy-styles.scss rename to app/assets/sass/uswds/_main.scss index 71fc58e4f..983a72c8c 100644 --- a/app/assets/sass/uswds/_legacy-styles.scss +++ b/app/assets/sass/uswds/_main.scss @@ -344,3 +344,17 @@ h2.recipient-list { } } } + +// Button ellipses loading + +.dot-anim::after { + content: '.'; + animation: dotPulse 1.5s steps(3, end) infinite; +} + +@keyframes dotPulse { + 0% { content: ''; } + 33% { content: '.'; } + 66% { content: '..'; } + 100% { content: '...'; } +} diff --git a/app/assets/sass/uswds/styles.scss b/app/assets/sass/uswds/styles.scss index 304e2f346..ce6adcbbb 100644 --- a/app/assets/sass/uswds/styles.scss +++ b/app/assets/sass/uswds/styles.scss @@ -1,5 +1,5 @@ @forward "uswds-theme"; @forward "uswds"; @forward "uswds-theme-custom-styles"; -@forward "legacy-styles"; +@forward "main"; @forward "data-visualization"; diff --git a/app/templates/base.html b/app/templates/base.html index 80a0afc7f..c75fae406 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -11,6 +11,12 @@ {% include "components/head.html" %} +
+
{% block bodyStart %} {% block extra_javascripts_before_body %} diff --git a/app/templates/components/banner.html b/app/templates/components/banner.html index 5ea9383d9..ccbc24225 100644 --- a/app/templates/components/banner.html +++ b/app/templates/components/banner.html @@ -4,10 +4,6 @@ {% macro banner(body, type=None, with_tick=False, delete_button=None, subhead=None, context=None, action=None, id=None, thing=None) %}
{{ field(**{ 'class': 'file-upload-field', + 'id': field.name, 'accept': allowed_file_extensions|format_list_items('.{item}')|join(',')|e }) }} - + {% if alternate_link and alternate_link_text %} or {{ alternate_link_text }} {% endif %} - + {{ usaButton({ "text": "Submit", "classes": "file-upload-submit" }) }} diff --git a/app/templates/views/check/column-errors.html b/app/templates/views/check/column-errors.html index bcb518892..0fa479c3f 100644 --- a/app/templates/views/check/column-errors.html +++ b/app/templates/views/check/column-errors.html @@ -20,7 +20,11 @@ Error {% block maincolumn_content %} + +
+ {# Alert for users of AT #} + File upload failed {% call banner_wrapper(type='dangerous') %} {% if recipients.too_many_rows %} @@ -150,7 +154,7 @@ Error ) }} {% endif %}
- Back to top + Back to top
{% endif %} diff --git a/app/templates/views/check/ok.html b/app/templates/views/check/ok.html index 71324b724..58e31a06a 100644 --- a/app/templates/views/check/ok.html +++ b/app/templates/views/check/ok.html @@ -21,6 +21,8 @@ {{ template|string }}
+ {# Alert for users of AT #} + File uploaded successfully