From 159360692fc1f3f166e997c78a9877f5b4e0be8f Mon Sep 17 00:00:00 2001 From: dandds Date: Thu, 6 Jun 2019 13:40:50 -0400 Subject: [PATCH] Improve task order upload validation handling. - Display validation errors. - Rerender validated form data correctly. - Clear error state correctly. --- atst/forms/task_order.py | 2 +- atst/routes/task_orders/new.py | 8 ++++---- js/components/upload_input.js | 12 ++++++------ styles/elements/_uploader.scss | 23 +++++++++++++++++++++++ templates/components/upload_input.html | 16 +++++++++++++--- translations.yaml | 1 + 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/atst/forms/task_order.py b/atst/forms/task_order.py index f4e21baf..d5938bd1 100644 --- a/atst/forms/task_order.py +++ b/atst/forms/task_order.py @@ -18,7 +18,7 @@ class TaskOrderForm(BaseForm): None, validators=[ FileAllowed(["pdf"], translate("forms.task_order.file_format_not_allowed")), - FileLength(), + FileLength(message=translate("forms.validators.file_length")), ], render_kw={"accept": ".pdf,application/pdf"}, ) diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index 555b494f..9778320f 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -8,17 +8,17 @@ from atst.models.permissions import Permissions from atst.utils.flash import formatted_flash as flash -def render_task_orders_edit(portfolio_id, task_order_id=None): +def render_task_orders_edit(portfolio_id, task_order_id=None, form=None): render_args = {} if task_order_id: task_order = TaskOrders.get(task_order_id) - render_args["form"] = TaskOrderForm( + render_args["form"] = form or TaskOrderForm( number=task_order.number, pdf=task_order.pdf ) render_args["task_order_id"] = task_order_id else: - render_args["form"] = TaskOrderForm() + render_args["form"] = form or TaskOrderForm() render_args["cancel_url"] = ( http_request.referrer @@ -64,4 +64,4 @@ def update(portfolio_id, task_order_id=None): ) else: flash("form_errors") - return render_task_orders_edit(portfolio_id, task_order_id), 400 + return render_task_orders_edit(portfolio_id, task_order_id, form), 400 diff --git a/js/components/upload_input.js b/js/components/upload_input.js index 9fb71553..843bdf62 100644 --- a/js/components/upload_input.js +++ b/js/components/upload_input.js @@ -19,17 +19,15 @@ export default { initialData: { type: String, }, - uploadErrors: { - type: Array, - default: () => [], + initialErrors: { + type: Boolean, }, }, data: function() { - const pdf = this.initialData - return { - attachment: pdf || null, + attachment: this.initialData || null, + showErrors: this.initialErrors, } }, @@ -39,11 +37,13 @@ export default { }, addAttachment: function(e) { this.attachment = e.target.value + this.showErrors = false }, removeAttachment: function(e) { e.preventDefault() this.attachment = null this.$refs.attachmentInput.value = null + this.showErrors = false }, }, diff --git a/styles/elements/_uploader.scss b/styles/elements/_uploader.scss index bfca1e96..34f115fe 100644 --- a/styles/elements/_uploader.scss +++ b/styles/elements/_uploader.scss @@ -1,4 +1,6 @@ .upload-widget { + position: relative; + label.upload-label { text-align: right; border: 1px solid black; @@ -21,6 +23,8 @@ input { opacity: 0; + position: absolute; + top: 0; } } @@ -46,3 +50,22 @@ font-size: $small-font-size; } } + +.usa-input--error { + .upload-widget { + label.upload-label { + border: 1px solid $color-red; + box-shadow: inset 0 0 0 2px $color-red; + position: relative; + + .upload-button { + margin-left: -3px; + border-left: 3px solid $color-red; + } + + .icon { + top: 0; + } + } + } +} diff --git a/templates/components/upload_input.html b/templates/components/upload_input.html index d7d71cc3..f2835baf 100644 --- a/templates/components/upload_input.html +++ b/templates/components/upload_input.html @@ -1,14 +1,21 @@ {% from "components/icon.html" import Icon %} {% macro UploadInput(field, show_label=False) -%} - +
{{ Icon("check-circle-solid") }} Remove
-
+
{% if show_label %} {{ field.label }} {% endif %} @@ -18,6 +25,9 @@ Browse + {% if field.errors %} + {{ Icon('alert',classes="icon-validation") }} + {% endif %}
{% for error in field.errors %} - {{error}} + {{error}} {% endfor %}
diff --git a/translations.yaml b/translations.yaml index 1af070ff..27a7b7ac 100644 --- a/translations.yaml +++ b/translations.yaml @@ -336,6 +336,7 @@ forms: list_items_unique_message: Items must be unique name_message: 'This field accepts letters, numbers, commas, apostrophes, hyphens, and periods.' phone_number_message: Please enter a valid 5 or 10 digit phone number. + file_length: Your file may not exceed 50 MB. fragments: edit_application_form: explain: AT-AT allows you to create multiple applications within a portfolio. Each application can then be broken down into its own customizable environments.