From a4e50f2b873458e3036db1a6b3e6afb58d4b10b3 Mon Sep 17 00:00:00 2001
From: Louis Kirkham <65811538+TheDancingClown@users.noreply.github.com>
Date: Thu, 28 Sep 2023 14:27:52 +0100
Subject: [PATCH] Revert "Re-work appraisal form submissions"
---
.../javascripts/admin/form_answers.js.coffee | 34 +++-
app/assets/stylesheets/admin/base.scss | 5 -
.../controllers/appraisal_form_controller.js | 189 ------------------
app/models/assessor_assignment.rb | 27 +--
...section_appraisal_form_moderated.html.slim | 4 +-
.../_section_appraisal_form_primary.html.slim | 4 +-
...section_appraisal_form_secondary.html.slim | 4 +-
.../_section_case_summary.html.slim | 13 +-
.../_application_background_section.html.slim | 2 +-
.../_case_summary_submit_block.html.slim | 15 +-
.../_non_rag_section.html.slim | 4 +-
.../_rag_section.html.slim | 4 +-
.../_submit_appraisal_form.html.slim | 15 +-
.../_verdict_section.html.slim | 4 +-
14 files changed, 57 insertions(+), 267 deletions(-)
delete mode 100644 app/javascript/controllers/appraisal_form_controller.js
diff --git a/app/assets/javascripts/admin/form_answers.js.coffee b/app/assets/javascripts/admin/form_answers.js.coffee
index 4f0550d00d..d36bc6d886 100644
--- a/app/assets/javascripts/admin/form_answers.js.coffee
+++ b/app/assets/javascripts/admin/form_answers.js.coffee
@@ -336,7 +336,29 @@ ready = ->
if (element)
element.classList.add('form-edit')
- $(document).on "click", ".form-save-link:not(.js-form-save-link)", (e) ->
+ $('.submit-assessment').on 'ajax:error', (e, data, status, xhr) ->
+ panel = this.closest('.panel-body')
+ errors = data.responseJSON
+
+ removeExistingErrorMessages(panel)
+
+ Object.entries(errors).forEach ([key, values]) ->
+ field = panel.querySelector("[name*='[#{key}]']")
+ if field and shouldValidateField(field)
+ showErrorForInvalidField(field, values)
+
+ $(".submit-assessment").on "ajax:success", (e, data, status, xhr) ->
+ panel = this.closest('.panel-body')
+ message = "Assessment submitted"
+ if panel.closest(".panel-collapse").classList.contains('section-case-summary')
+ message = "Case summary submitted"
+
+ removeExistingErrorMessages(panel)
+ panel.insertAdjacentHTML('afterbegin', buildBannerHtml(message, 'success'))
+
+ $(this).find('input:submit').remove()
+
+ $(document).on "click", ".form-save-link", (e) ->
link = $(this)
e.preventDefault()
formGroup = link.closest(".form-group")
@@ -371,11 +393,11 @@ ready = ->
input.val(updatedSection)
form.submit()
else
- if area.first().val().length
- formGroup.find(".form-value p:first").html(area.first().val().replace(/\n/g, '
'))
- if area.last().val().length
- formGroup.find(".form-value p:last").html(area.last().val().replace(/\n/g, '
'))
- form.submit()
+ if area.first().val().length
+ formGroup.find(".form-value p:first").html(area.first().val().replace(/\n/g, '
'))
+ if area.last().val().length
+ formGroup.find(".form-value p:last").html(area.last().val().replace(/\n/g, '
'))
+ form.submit()
$("#new_review_audit_certificate input[type='radio']").on "change", ->
area = $(".audit-cert-description")
diff --git a/app/assets/stylesheets/admin/base.scss b/app/assets/stylesheets/admin/base.scss
index adb156c9e1..1bbe32c8b5 100644
--- a/app/assets/stylesheets/admin/base.scss
+++ b/app/assets/stylesheets/admin/base.scss
@@ -1619,11 +1619,6 @@ label.govuk-label.govuk-checkboxes__label.boolean.optional.govuk-label {
}
}
- .rag-error {
- background-color: #f2dede;
- color: #a94442 !important;
- }
-
.rag-blank {
&,
a,
diff --git a/app/javascript/controllers/appraisal_form_controller.js b/app/javascript/controllers/appraisal_form_controller.js
deleted file mode 100644
index 50835dc495..0000000000
--- a/app/javascript/controllers/appraisal_form_controller.js
+++ /dev/null
@@ -1,189 +0,0 @@
-export default class extends ApplicationController {
- static values = {
- success: String,
- };
-
- connect() {}
-
- success(event) {
- return this.handleSuccess(event);
- }
-
- error(event) {
- return this.handleError(event);
- }
-
- handleSuccess = ({ target }) => {
- const panel = target.closest('.panel-body');
-
- this.resetErrors(panel);
-
- const message = this.hasSuccessValue ? this.successValue : 'Success!';
- const [alert, identifier] = this.createAlert('success', message);
-
- panel.insertAdjacentHTML('afterbegin', alert);
-
- const template = this.element.querySelector('[data-role=template]');
-
- if ('content' in template) {
- const replacement = template.content.cloneNode(true);
- target.replaceWith(replacement.firstChild);
- } else {
- target.remove();
- }
- };
-
- handleError = (event) => {
- const {
- target,
- detail: { responseJSON: errors },
- } = event;
- const panel = target.closest('.panel-body');
-
- this.resetErrors(panel);
-
- Object.entries(errors).forEach(([key, values]) => {
- const field = panel.querySelector(`[name*='[${key}]']`);
- const container = field.closest('.form-container');
-
- if (field && this.shouldValidateField(field)) {
- this.showFieldErrors(field, values);
- }
-
- if (key && key.endsWith('_rate')) {
- const button = container.querySelector('label button');
- if (button) button.classList.add('rag-error');
- } else {
- if (!this.visible(field)) {
- const target = container.querySelector('.form-edit-link');
- if (target) $(target).trigger('click');
- }
- }
- });
- };
-
- stash = (event) => {
- event.preventDefault();
- event.stopPropagation();
-
- const { target: button } = event;
- const wrapper = button.closest('.form-group');
- const form = wrapper.closest('form');
- const textarea = Array.from(wrapper.querySelectorAll('textarea')).filter(this.visible);
-
- if (textarea.length > 1) {
- for (let idx = 0; idx < textarea.length; idx++) {
- LS.removeItem(textarea[idx].dataset.autosaveKey);
- }
- } else {
- LS.removeItem(textarea[0].dataset.autosaveKey);
- }
-
- wrapper.classList.remove('form-edit');
-
- if (Array.from(wrapper.querySelectorAll('.form-value p[data-for]')).length > 0) {
- Array.from(wrapper.querySelectorAll('.form-value p[data-for]')).forEach((el) => {
- let identifier = el.dataset.for;
- let element = document.querySelector(`#${identifier}`);
-
- if (element) el.innerHTML = element.value;
- });
-
- return form.submit();
- } else if (textarea.length === 1) {
- let _textarea = textarea[0];
-
- if (_textarea.value.length) {
- const panel = event.target.closest('.panel-body');
- const value = _textarea.value.replace(/\n/g, '
');
- const updatedValue = button.dataset.updatedSection;
-
- wrapper.querySelector('.form-value p').innerHTML = value;
-
- panel.querySelector('.field-with-errors')?.classList?.remove('field-with-errors');
- panel.querySelector('.feedback-holder')?.classList?.remove('error');
- panel.querySelector('.btn-rag > button')?.classList?.remove('rag-error');
-
- Array.from(wrapper.querySelectorAll('textarea')).forEach((el) => {
- if (el.value && el.value.length) {
- return el.closest('.input')?.classList?.remove('field-with-errors');
- }
- });
-
- if (updatedValue) {
- const input = form.querySelector("input[name='updated_section']");
-
- if (input) {
- input.value = updatedValue;
- }
- }
-
- return form.submit();
- }
- } else {
- if (textarea[0] && textarea[0].value.length) {
- const value = textarea[0].value.replace(/\n/g, '
');
- Array.from(wrapper.querySelectorAll('.form-value p'))[0].innerHTML = value;
- }
-
- if (textarea[-1] && textarea[-1].value.length) {
- const value = textarea[-1].value.replace(/\n/g, '
');
- Array.from(wrapper.querySelectorAll('.form-value p'))[-1].innerHTML = value;
- }
-
- return form.submit();
- }
- };
-
- resetErrors(element) {
- element.querySelectorAll('.field-with-errors').forEach((el) => el.classList.remove('field-with-errors'));
- element.querySelectorAll('.rag-error').forEach((el) => el.classList.remove('rag-error'));
- element.querySelectorAll('[aria-errormessage]').forEach((el) => el.removeAttribute('aria-errormessage'));
- element.querySelectorAll('.alert').forEach((el) => el.remove());
- }
-
- shouldValidateField(field) {
- return !field.disabled && field.type !== void 0 && !['file', 'reset', 'submit', 'button'].includes(field.type);
- }
-
- showFieldErrors(field, errors, selector) {
- if (selector == null) {
- selector = '.form-container';
- }
-
- const container = field.closest(selector);
- const group = field.closest('.govuk-form-group');
-
- if (group) {
- group.classList.add('field-with-errors');
- }
-
- if (container) {
- return errors.forEach((message) => {
- const [alert, identifier] = this.createAlert('danger', message);
- field.setAttribute('aria-errormessage', identifier);
- return container.insertAdjacentHTML('afterbegin', alert);
- });
- }
- }
-
- createAlert = (type, message) => {
- const id = 'alert__' + String(Math.random()).slice(2, -1);
- const element = `
-
- ${message}
-
-
- `;
-
- return [element, id];
- };
-
- visible(field) {
- return (
- !field.hidden && (!field.type || field.type != 'hidden') && (field.offsetWidth > 0 || field.offsetHeight > 0)
- );
- }
-}
diff --git a/app/models/assessor_assignment.rb b/app/models/assessor_assignment.rb
index afe8d26884..5952da3a9d 100644
--- a/app/models/assessor_assignment.rb
+++ b/app/models/assessor_assignment.rb
@@ -152,13 +152,7 @@ def not_submitted_or_not_locked?
def award_specific_attributes
struct.diff(form_answer, moderated?).each do |att|
if public_send(att).present?
- message = if att.ends_with?("_rate")
- "RAG rating for '#{section_name(att)}' cannot be present for this Award Type"
- else
- "An appraisal comment for '#{section_name(att)}' cannot be present for this Award Type"
- end
-
- errors.add(att, message: message)
+ errors.add(att, "cannot be present for this Award Type")
end
end
end
@@ -168,13 +162,7 @@ def mandatory_fields_for_submitted
struct.meths_for_award_type(form_answer, moderated?).each do |meth|
if public_send(meth).blank?
- message = if meth.ends_with?("_rate")
- "RAG rating is required for '#{section_name(meth)}'. Select an option from the dropdown list."
- else
- "An appraisal comment is required for '#{section_name(meth)}' and must be filled in."
- end
-
- errors.add(meth, message: message)
+ errors.add(meth, "cannot be blank for submitted assessment")
end
end
end
@@ -186,8 +174,7 @@ def validate_rate(rate_type)
c = "#{rate_type.upcase}_ALLOWED_VALUES"
if val && !struct.const_get(c).include?(val)
sect_name = struct.rate(section)
- message = "#{rate_type} field for '#{section_name(section)}' has not permitted value."
- errors.add(sect_name, message: message)
+ errors.add(sect_name, "#{rate_type} field has not permitted value")
end
end
end
@@ -196,14 +183,6 @@ def section_rate(section)
public_send(struct.rate(section))
end
- def section_name(key)
- @_sections ||= struct.struct(form_answer).to_h
- section_key = key.to_s.gsub(/_desc$/, "").gsub(/_rate$/, "")
- if section = @_sections.dig(section_key.to_sym)
- section[:label].gsub(/:$/, "")
- end
- end
-
def struct
AppraisalForm
end
diff --git a/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim b/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim
index de355293c6..4e34590b76 100644
--- a/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim
+++ b/app/views/admin/form_answers/_section_appraisal_form_moderated.html.slim
@@ -7,12 +7,12 @@
small
= moderated_assessment.last_editor_info
- #section-appraisal-form-moderated.section-appraisal-form.section-appraisal-form-moderated.panel-collapse.collapse[aria-labelledby="appraisal-form-moderated-heading" data-controller="appraisal-form" data-appraisal-form-success-value="Appraisal form (moderated) has been submitted"]
+ #section-appraisal-form-moderated.section-appraisal-form.section-appraisal-form-moderated.panel-collapse.collapse[aria-labelledby="appraisal-form-moderated-heading"]
.panel-body[data-controller="inline-flash"]
= simple_form_for([namespace_name, moderated_assessment],
remote: true,
authenticity_token: true,
- html: { data: { type: "json", inline_flash_target: "form" } }) do |f|
+ html: { data: { type: "json", inline_flash_target: "form", controller: "html5-form-validation", html5_form_validation_selectors_value: ["textarea"] } }) do |f|
= render_section(resource, f)
= hidden_field_tag :updated_section
diff --git a/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim b/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim
index 8a5bdf7d40..12430e2f25 100644
--- a/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim
+++ b/app/views/admin/form_answers/_section_appraisal_form_primary.html.slim
@@ -6,12 +6,12 @@
- if primary_assessment.last_editor_info.present?
small
= primary_assessment.last_editor_info
- #section-appraisal-form-primary.section-appraisal-form.section-appraisal-form-primary.panel-collapse.collapse[aria-labelledby="appraisal-form-primary-heading" data-controller="appraisal-form" data-appraisal-form-success-value="Appraisal form (primary) has been submitted"]
+ #section-appraisal-form-primary.section-appraisal-form.section-appraisal-form-primary.panel-collapse.collapse aria-labelledby="appraisal-form-primary-heading"
.panel-body[data-controller="inline-flash"]
= simple_form_for([namespace_name, primary_assessment],
remote: true,
authenticity_token: true,
- html: { data: { type: "json", inline_flash_target: "form" }, id: "primary_appraisal_form" }) do |f|
+ html: { data: { type: "json", inline_flash_target: "form", html5_form_validation_selectors_value: ["textarea"], controller: "html5-form-validation" }, id: "primary_appraisal_form" }) do |f|
= hidden_field_tag :updated_section, nil, id: "primary_updated_section_hidden_field"
= render_section(resource, f)
diff --git a/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim b/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim
index 7295176f9d..27e6acd617 100644
--- a/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim
+++ b/app/views/admin/form_answers/_section_appraisal_form_secondary.html.slim
@@ -6,12 +6,12 @@
- if secondary_assessment.last_editor_info.present?
small
= secondary_assessment.last_editor_info
- #section-appraisal-form-secondary.section-appraisal-form.section-appraisal-form-secondary.panel-collapse.collapse[aria-labelledby="appraisal-form-secondary-heading" data-controller="appraisal-form" data-appraisal-form-success-value="Appraisal form (secondary) has been submitted"]
+ #section-appraisal-form-secondary.section-appraisal-form.section-appraisal-form-secondary.panel-collapse.collapse aria-labelledby="appraisal-form-secondary-heading"
.panel-body[data-controller="inline-flash"]
= simple_form_for([namespace_name, secondary_assessment],
remote: true,
authenticity_token: true,
- html: { data: { type: "json", inline_flash_target: "form" }, id: "secondary_appraisal_form"}) do |f|
+ html: { data: { type: "json", inline_flash_target: "form", controller: "html5-form-validation", html5_form_validation_selectors_value: ["textarea"] }, id: "secondary_appraisal_form"}) do |f|
= hidden_field_tag :updated_section, nil, id: "secondary_updated_section_hidden_field"
= render_section(resource, f)
diff --git a/app/views/admin/form_answers/_section_case_summary.html.slim b/app/views/admin/form_answers/_section_case_summary.html.slim
index 309962a33e..7bc5b85389 100644
--- a/app/views/admin/form_answers/_section_case_summary.html.slim
+++ b/app/views/admin/form_answers/_section_case_summary.html.slim
@@ -11,10 +11,19 @@
- if assessment.editable.present?
small
= "Updated by #{message_author_name(assessment.editable)} - #{format_date(assessment.updated_at)}"
- .panel-collapse.collapse[aria-labelledby="case-summary-heading-#{assessment.position}" id="section-case-summary-#{assessment.position}" class="section-case-summary-#{assessment.position}" data-controller="appraisal-form" data-appraisal-form-success-value="Case summary has been submitted"]
+ .panel-collapse.collapse aria-labelledby="case-summary-heading-#{assessment.position}" id="section-case-summary-#{assessment.position}" class="section-case-summary-#{assessment.position}"
.panel-body[data-controller="inline-flash"]
- = simple_form_for([namespace_name, assessment], remote: true, authenticity_token: true, html: { data: { inline_flash_target: "form" } }) do |f|
+ /.alert.alert-glyphicon.alert-info
+ span.glyphicon.glyphicon-info-sign
+ p.todo-placeholder
+ ' Some instructions on how to use this or what this section is about. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Duis mollis, est non commodo luctus.
+
+ / Only show if Moderated Appraisal is submitted
+ / For Primary Assessor
+ / It becomes read-only for primary assessor after submission
+
+ = simple_form_for([namespace_name, assessment], remote: true, authenticity_token: true, html: { data: { inline_flash_target: "form", controller: "html5-form-validation", html5_form_validation_selectors_value: ["textarea"] } }) do |f|
= render partial: "admin/form_answers/appraisal_form_components/application_background_section",
locals: { f: f}
= render_section(resource, f)
diff --git a/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim
index 70ef64e0dc..1b49d9e47d 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_application_background_section.html.slim
@@ -23,5 +23,5 @@
= link_to "#", class: "form-edit-link pull-right", data: { element_focus_target: "reveal" }
span.glyphicon.glyphicon-pencil
' Edit
- = link_to "Save", "#", class: "btn btn-primary form-save-link js-form-save-link pull-right if-no-js-hide", data: { action: "click->appraisal-form#stash" }
+ = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", data: { action: "click->html5-form-validation#validate" }
.clear
diff --git a/app/views/admin/form_answers/appraisal_form_components/_case_summary_submit_block.html.slim b/app/views/admin/form_answers/appraisal_form_components/_case_summary_submit_block.html.slim
index f1b3a16e5d..377907f0cc 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_case_summary_submit_block.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_case_summary_submit_block.html.slim
@@ -1,6 +1,6 @@
- if policy(assessment).can_be_submitted? || policy(assessment).can_be_re_submitted?
- = form_tag(url_for([namespace_name, :assessment_submissions]), remote: true, authenticity_token: true, class: "submit-assessment", data: { action: "ajax:x:success->appraisal-form#success ajax:x:error->appraisal-form#error", type: "json" })
+ = form_tag(url_for([namespace_name, :assessment_submissions]), remote: true, authenticity_token: true, class: "submit-assessment", "data-type" => "json")
= hidden_field_tag :assessment_id, assessment.id
.feedback-holder
@@ -9,19 +9,6 @@
= submit_tag submit_case_summary_title(assessment), class: "btn btn-primary btn-confirm-submit"
.clear
- template[data-role='template']
- - if policy(assessment).admin_or_lead?
- - unlock_url = namespace_name == :admin ? unlock_admin_assessment_submission_url(assessment) : unlock_assessor_assessment_submission_url(assessment)
-
- = form_tag unlock_url, method: :patch do
- = hidden_field_tag :assessment_id, assessment.id
- .feedback-holder.alert.alert-success
- ' Case Summary Submitted
-
- .pull-right
- = submit_tag "Unlock", class: "btn btn-primary"
- .clear
-
- elsif assessment.submitted?
- if policy(assessment).can_unlock?
diff --git a/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim
index b41eb85b86..3a16109334 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_non_rag_section.html.slim
@@ -26,6 +26,6 @@
span.glyphicon.glyphicon-pencil
' Edit
.form-actions.text-right
- = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" }
- = link_to "Save", "#", class: "btn btn-primary form-save-link js-form-save-link pull-right if-no-js-hide", data: { updated_section: section.desc, action: "click->appraisal-form#stash" }
+ = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss", action: "click->html5-form-validation#discard" }
+ = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", data: { action: "click->html5-form-validation#validate", updated_section: section.desc }
.clear
diff --git a/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim
index 0af8748211..6747cf3735 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_rag_section.html.slim
@@ -46,6 +46,6 @@
span.glyphicon.glyphicon-pencil
' Edit
.form-actions.text-right
- = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" }
- = link_to "Save", "#", class: "btn btn-primary form-save-link js-form-save-link pull-right if-no-js-hide", data: { updated_section: section.desc, action: "click->appraisal-form#stash" }
+ = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss", action: "click->html5-form-validation#discard" }
+ = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", data: { action: "click->html5-form-validation#validate", updated_section: section.desc }
.clear
diff --git a/app/views/admin/form_answers/appraisal_form_components/_submit_appraisal_form.html.slim b/app/views/admin/form_answers/appraisal_form_components/_submit_appraisal_form.html.slim
index afd2f9ee3f..ecf4400712 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_submit_appraisal_form.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_submit_appraisal_form.html.slim
@@ -3,7 +3,7 @@
authenticity_token: true,
remote: true,
class: "submit-assessment",
- data: { action: "ajax:x:success->appraisal-form#success ajax:x:error->appraisal-form#error", type: "json" })
+ data: { type: "json" })
= hidden_field_tag :assessment_id, assessment.id, id: "#{assessment.position}_assessment_id_submit_appraisal_form_hidden_field"
@@ -13,19 +13,6 @@
= submit_tag (assessment.submitted? ? "Re-submit appraisal" : "Submit appraisal"), class: "btn btn-primary btn-confirm-submit"
.clear
- template[data-role='template']
- - if policy(assessment).admin_or_lead?
- - unlock_url = namespace_name == :admin ? unlock_admin_assessment_submission_url(assessment) : unlock_assessor_assessment_submission_url(assessment)
-
- = form_tag unlock_url, method: :patch do
- = hidden_field_tag :assessment_id, assessment.id, id: "#{assessment.position}_assessment_id_unlock_appraisal_form_hidden_field"
- .feedback-holder.alert.alert-success
- ' Assessment submitted
-
- .pull-right
- = submit_tag "Unsubmit", class: "btn btn-primary"
- .clear
-
- elsif assessment.submitted?
- if policy(assessment).can_unlock?
diff --git a/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim b/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim
index 4eacdcbd27..c0102babf6 100644
--- a/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim
+++ b/app/views/admin/form_answers/appraisal_form_components/_verdict_section.html.slim
@@ -44,6 +44,6 @@
span.glyphicon.glyphicon-pencil
' Edit
.form-actions.text-right
- = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss" }
- = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide"
+ = link_to "Cancel", "#", class: "btn btn-default form-cancel-link if-no-js-hide", data: { element_focus_target: "dismiss", action: "click->html5-form-validation#discard" }
+ = link_to "Save", "#", class: "btn btn-primary form-save-link pull-right if-no-js-hide", data: { action: "click->html5-form-validation#validate" }
.clear