Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW Show icons on tabs with invalid form field values #1111

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/dist/styles/bundle.css

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/lang/src/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"Admin.CONFIRMUNSAVED": "Are you sure you want to navigate away from this page?\n\nWARNING: Your changes have not been saved.\n\nPress OK to continue, or Cancel to stay on the current page.",
"Admin.CONFIRMUNSAVEDSHORT": "WARNING: Your changes have not been saved.",
"Admin.VALIDATIONERROR": "Validation Error",
"Admin.VALIDATION_ERRORS_IN_TAB": "This tab contains validation errors.",
"Admin.VALIDATION_ERRORS_ON_PAGE": "There are validation errors on this page, please fix them before saving or publishing.",
"Admin.NONE": "None",
"Admin.EDIT": "Edit",
"Admin.ANY": "Any",
Expand Down
107 changes: 87 additions & 20 deletions client/src/legacy/LeftAndMain.EditForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,95 @@ $.entwine('ss', function($){
},
'from .cms-tabset': {
onafterredrawtabs: function () {
// Show validation errors if necessary
if(this.hasClass('validationerror')) {
// Ensure the first validation error is visible
var tabError = this.find('.message.validation, .message.required').first().closest('.tab');
$('.cms-container').clearCurrentTabState(); // clear state to avoid override later on

// Attempt #1: Look for nearest .ss-tabset (usually nested deeper underneath a .cms-tabset).
var $tabSet = tabError.closest('.ss-tabset');

// Attempt #2: Next level in tab-ception, try to select the tab within this higher level .cms-tabset if possible
if (!$tabSet.length) {
$tabSet = tabError.closest('.cms-tabset');
}

if ($tabSet.length) {
$tabSet.tabs('option', 'active', tabError.index('.tab'));
} else if (!this.getValidationErrorShown()) {
// Ensure that this error message popup won't be added more than once
this.setValidationErrorShown(true);
errorMessage(ss.i18n._t('Admin.VALIDATIONERROR', 'Validation Error'));
}
// This function will:
// - Add an invalid icon on each tab that contains form fields than failed validation
// - Set an alert message in the edit form error banner
const iconClass = 'font-icon-attention-1 tab-attention';
const iconTitle = ss.i18n._t(
'VALIDATION_ERRORS_IN_TAB',
'This tab contains validation errors.'
);
const iconScreenReaderText = ss.i18n._t(
'VALIDATION_ERRORS_IN_TAB_SCREEN_READER',
'(Has validation errors)'
);
const alertMessageText = ss.i18n._t(
'Admin.VALIDATION_ERRORS_ON_PAGE',
'There are validation errors on this page, please fix them before saving or publishing.'
);
const toastNotificationMessage = ss.i18n._t(
'Admin.VALIDATIONERROR',
'Validation Error'
);
const $editFormErrorBanner = $("#Form_EditForm_error");

// Remove any existing invalid tab icons and screen-reader text
this.find('.tab-attention, .tab-validation-error-sr').remove();

// Check if there are any form validation errors
let validationErrorExists = false;

// Validation errors from DataObject::getCMSValidator()
if (this.hasClass('validationerror')) {
validationErrorExists = true;
}

// Validation errors from DataObject::validate() .. ValidationResult::addError();
if ($editFormErrorBanner.html() !== '') {
validationErrorExists = true;
}

// Validation errors from DataObject::validate() .. ValidationResult::addFieldError()
if (this.find('.alert.error').length > 0) {
validationErrorExists = true;
}

// If there are no validation errors then hide any old messages and exit
if (!validationErrorExists) {
$editFormErrorBanner.hide();
return;
}

// Show a toast notification for DataObject::getCMSValidator() validation errors
if (!this.getValidationErrorShown() && this.hasClass('validationerror')) {
errorMessage(toastNotificationMessage);
// Ensure that this error message popup won't be added more than once
this.setValidationErrorShown(true);
}

// Find tab-pane's with decedent validation .alert's
const $invalidTabPanes = this.find('.tab-pane .alert').closest('.tab-pane');
if (!$invalidTabPanes.length) {
// If we are at this point it's probably a failed DataObject::validate()
// where there was a general (non-field) error added via ValidationResult::addError()
return;
}

// Get the surrounding ss-tabset
const $ssTabSet = $invalidTabPanes.closest('.tab-content').closest('.ss-tabset');
if ($ssTabSet.length) {

// Add invalid icons to tabs
$invalidTabPanes.each((i) => {
const invalidTabPaneId = $invalidTabPanes.eq(i).attr('id');
const $tabLi = $ssTabSet.find(`#tab-${invalidTabPaneId}`).closest('li');
const $icon = $(`<i class="${iconClass}" title="${iconTitle}" aria-hidden="true"></i>`);
emteknetnz marked this conversation as resolved.
Show resolved Hide resolved
const $screenReaderSpan = $(`<span class="tab-validation-error-sr sr-only">${iconScreenReaderText}</span>`);
$tabLi.append($icon);
$tabLi.append($screenReaderSpan);
});

// Set an alert message in the edit form error banner
$editFormErrorBanner.attr('class', 'alert alert-danger');
$editFormErrorBanner.html(alertMessageText);
$editFormErrorBanner.show();
}

// Ensure the class "validationerror" is set for the scenario where
// the error came from validate() .. ValidationResult::addFieldError()
// so that css styles are applied to tab icons
this.addClass('validationerror');
}
},
onremove: function() {
Expand Down
11 changes: 11 additions & 0 deletions client/src/styles/legacy/_style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,17 @@ html, body {
}
}

.validationerror .panel--padded .ui-tabs-nav {
Cheddam marked this conversation as resolved.
Show resolved Hide resolved
margin-top: -$panel-padding-y;

.tab-attention {
color: $state-draft;
position: absolute;
margin-top: 12px;
margin-left: -4px;
}
}

// -------------------------------------------------------
// Loading Interface
// ------------------------------------------------------- */
Expand Down