diff --git a/app/controllers/orgs_controller.rb b/app/controllers/orgs_controller.rb index 0278d84..135fc5c 100644 --- a/app/controllers/orgs_controller.rb +++ b/app/controllers/orgs_controller.rb @@ -29,11 +29,11 @@ # Only allow super admins to change the org types and shib info if current_user.can_super_admin? # Handle Shibboleth identifiers if that is enabled - if Rails.application.config.shibboleth_use_filtered_discovery_service + if Rails.application.config.shibboleth_use_filtered_discovery_service && params[:shib_id].present? shib = IdentifierScheme.find_by(name: 'shibboleth') shib_settings = @org.org_identifiers.select{ |ids| ids.identifier_scheme == shib}.first - if params[:shib_id].present? || params[:shib_domain].present? + if !params[:shib_id].blank? shib_settings = OrgIdentifier.new(org: @org, identifier_scheme: shib) unless shib_settings.present? shib_settings.identifier = params[:shib_id] shib_settings.attrs = {domain: params[:shib_domain]} diff --git a/app/helpers/orgs_helper.rb b/app/helpers/orgs_helper.rb index 4afe809..f106fa1 100644 --- a/app/helpers/orgs_helper.rb +++ b/app/helpers/orgs_helper.rb @@ -9,7 +9,7 @@ # @return [String] The tooltip message def tooltip_for_org_feedback_form(org) email = org.contact_email.presence || DEFAULT_EMAIL - _("A data librarian from %{org_name} will respond to your request within 48 + _("SAMPLE MESSAGE: A data librarian from %{org_name} will respond to your request within 48 hours. If you have questions pertaining to this action please contact us at %{organisation_email}.") % { organisation_email: email, diff --git a/app/models/template.rb b/app/models/template.rb index a22b855..50e2616 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -53,7 +53,6 @@ has_many :questions, through: :sections has_many :annotations, through: :questions - # ========== # = Scopes = # ========== diff --git a/app/views/guidance_groups/_index_by_theme.html.erb b/app/views/guidance_groups/_index_by_theme.html.erb index 3c39eff..8ba4226 100644 --- a/app/views/guidance_groups/_index_by_theme.html.erb +++ b/app/views/guidance_groups/_index_by_theme.html.erb @@ -11,22 +11,36 @@ <% guidance_groups_by_theme.each_pair do |guidance_group, theme_hash| %> <% theme_hash.each_pair do |theme, guidances| %>
+<<<<<<< HEAD
>>>>>> parent of ac3dbec2... Revert "lookup hash guidance groups by org. DMPRoadmap/roadmap#1409" data-toggle="collapse" href="<%= "##{guidances.object_id}" %>" aria-expanded="false" aria-controls="<%= "##{guidances.object_id}" %>">
" +======= + id="<%= "#{guidances.object_id}" %>" +>>>>>>> parent of ac3dbec2... Revert "lookup hash guidance groups by org. DMPRoadmap/roadmap#1409" class="panel-collapse collapse" role="tabpanel" aria-labelledby="<%= "panel-heading-#{guidances.object_id}" %>"> @@ -39,4 +53,8 @@
<% end %> <% end %> +<<<<<<< HEAD
+======= + +>>>>>>> parent of ac3dbec2... Revert "lookup hash guidance groups by org. DMPRoadmap/roadmap#1409" diff --git a/app/views/guidances/new_edit.html.erb b/app/views/guidances/new_edit.html.erb index 66e3e2c..28e3cf8 100644 --- a/app/views/guidances/new_edit.html.erb +++ b/app/views/guidances/new_edit.html.erb @@ -14,8 +14,8 @@ <%= text_area_tag("guidance-text", guidance.text, class: "form-control", 'aria-required': true, rows: 10) %> <%= render partial: 'org_admin/shared/theme_selector', - locals: { f: f, all_themes: themes, as_radio: true, required: true, - popover_message: _('Select one theme that is relevant to this guidance. This will display your generic organisation-level guidance, or any Schools/Departments for which you create guidance groups, across all templates that have questions with the corresponding theme tags.') } %> + locals: { f: f, all_themes: themes, as_radio: false, required: true, + popover_message: _('Select one or more themes that are relevant to this guidance. This will display your generic organisation-level guidance, or any Schools/Departments for which you create guidance groups, across all templates that have questions with the corresponding theme tags.') } %>
<%= f.label _('Guidance group'), for: :guidance_group_id, class: 'control-label' %> <%= f.collection_select(:guidance_group_id, guidance_groups, diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 2e50441..9f43109 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -88,6 +88,7 @@ VALIDATION_MESSAGE_PASSWORDS_MATCH: _('The passwords must match.'), VALIDATION_MESSAGE_RADIO: _('Please choose one of the options.'), VALIDATION_MESSAGE_CHECKBOX: _('Please check the box to continue.'), + VALIDATION_MESSAGE_MULTI_CHECKBOX: _('Please select at least one of the options to continue.'), VALIDATION_MESSAGE_SELECT: _('Please select a value from the list.'), VALIDATION_MESSAGE_TEXT: _('This field is required.'), diff --git a/app/views/org_admin/shared/_theme_selector.html.erb b/app/views/org_admin/shared/_theme_selector.html.erb index 11fe8e7..13dd640 100644 --- a/app/views/org_admin/shared/_theme_selector.html.erb +++ b/app/views/org_admin/shared/_theme_selector.html.erb @@ -3,43 +3,41 @@ <% required ||= false %>
- <% if required %> - * - <% end %> - <%= f.label _('Themes'), for: :theme_ids, class: 'control-label' %> - <%= render partial: 'shared/popover', - locals: { message: popover_message, placement: 'right' }%> -
- <% if all_themes.length > 0 %> <% cntr = 0 nbr_of_cols = (all_themes.length.to_f / MAX_NUMBER_THEMES_PER_COLUMN.to_f).ceil col_size = (12 / (nbr_of_cols > 4 ? 3 : nbr_of_cols)).round %> -
- <% all_themes.each do |theme| %> - <% if cntr >= MAX_NUMBER_THEMES_PER_COLUMN %> +
+ + <%= _('Themes') %> + <%= render partial: 'shared/popover', + locals: { message: popover_message, placement: 'right' }%> + + +
+ <% all_themes.each do |theme| %> + <% if cntr >= MAX_NUMBER_THEMES_PER_COLUMN %> +
+
+ <% cntr = 0 %> + <% end %> +
+ <% namespace = f.object.class.name.downcase %> + <% id = f.object.id.present? ? f.object.id : 'new' %> + + value="<%= theme.id %>"<%= f.object.themes.include?(theme) ? ' checked="checked"' : '' %>> + <%= theme.title %>
-
- <% cntr = 0 %> + <% cntr += 1 %> <% end %> -
-
- <% namespace = f.object.class.name.downcase %> - <% id = f.object.id.present? ? f.object.id : 'new' %> - - value="<%= theme.id %>"<%= f.object.themes.include?(theme) ? ' checked="checked"' : '' %>> - <%= theme.title %> -
-
- <% cntr += 1 %> - <% end %> -
+
+
<% else %>

<%= _('No themes have been defined. Please contact your administrator for assistance.') %>

<% end %> diff --git a/app/views/shared/_create_account_form.html.erb b/app/views/shared/_create_account_form.html.erb index 03ca99d..6bdf261 100644 --- a/app/views/shared/_create_account_form.html.erb +++ b/app/views/shared/_create_account_form.html.erb @@ -23,15 +23,18 @@ <%= f.label(:password, _('Password'), class: "control-label") %> <%= f.password_field(:password, class: "form-control", "aria-required": true) %>
-
- +
+
+ +
-
- <%= f.label(:accept_terms, - raw("#{ f.check_box(:accept_terms, "aria-required": true, "data-validation-error": _('You must agree to the term and conditions.')) } #{_('I accept the')} #{_('terms and conditions')}")) %> +
+
+ <%= f.label(:accept_terms, + raw("#{ f.check_box(:accept_terms, "aria-required": true, "data-validation-error": _('You must agree to the term and conditions.')) } #{_('I accept the')} #{_('terms and conditions')}")) %> +
- <%= f.button(_('Create account'), class: "btn btn-default", type: "submit") %> <% end %> diff --git a/lib/assets/javascripts/utils/ariatiseForm.js b/lib/assets/javascripts/utils/ariatiseForm.js index 3048118..b1f4b5a 100644 --- a/lib/assets/javascripts/utils/ariatiseForm.js +++ b/lib/assets/javascripts/utils/ariatiseForm.js @@ -50,7 +50,11 @@ // Otherwise if the element is required validate based on its type } else if ($(el).attr('aria-required') === 'true') { if ($(el).is('input')) { - return $(el).attr('type'); // available types at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form__types + const type = $(el).attr('type'); // available types at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form__types + if (type === 'checkbox' && $(el).closest('fieldset').length > 0) { + return 'multi-checkbox'; + } + return type; } else if ($(el).is('select')) { return 'select'; } else if ($(el).is('.tinymce')) { @@ -75,23 +79,17 @@ }; const addAsterisk = (el) => { const asterisk = '* '; + const type = getValidationTypeForElement(el); if (isObject(el)) { - switch (getValidationTypeForElement(el)) { - case 'checkbox': { - el.after(asterisk); - break; - } - case 'radio': { - const legend = el.closest('fieldset').find('legend'); - legend.html(`${asterisk}${legend.text()}`); - break; - } - default: { - const label = el.closest('.form-group').find('label'); - if (isObject(label)) { - $(label[0]).before(asterisk); - } - break; + if (el.closest('fieldset').length > 0 && el.closest('fieldset').find('legend').length > 0) { + const legend = el.closest('fieldset').find('legend'); + legend.html(`${asterisk} ${legend.html()}`); + } else if (type === 'checkbox' || type === 'radio') { + el.after(asterisk); + } else { + const label = el.closest('.form-group').find('label'); + if (isObject(label)) { + $(label[0]).before(asterisk); } } } @@ -110,24 +108,28 @@ case 'tinymce': return Tinymce.findEditorById($(el).attr('id')).getContent(); case 'checkbox': + case 'multi-checkbox': return ($(el).is(':checked') ? 'checked' : ''); default: return $(el).val(); } }; -const isValid = (type, value) => { +const isValid = (el) => { // TODO add more validation for each new type coming along by: // 1. defining a function at dmproadmap.utils.validate // 2. adding the case in the switch below + const type = getValidationTypeForElement(el); + const value = getValue(type, el); // See if a specific data-validation was specified switch (type) { case 'text': - return validator.isValidText(value); case 'textarea': - return validator.isValidText(value); case 'tinymce': + case 'select': + case 'radio': + case 'js-combobox': return validator.isValidText(value); case 'number': return validator.isValidNumber(value); @@ -135,13 +137,10 @@ return validator.isValidEmail(value); case 'password': return validator.isValidPassword(value); - case 'radio': - return validator.isValidText(value); - case 'select': case 'checkbox': - return validator.isValidText(value); - case 'js-combobox': - return validator.isValidText(value); + return validator.isValidCheckbox(el); + case 'multi-checkbox': + return validator.isValidMultiCheckbox(el); default: return false; } @@ -150,7 +149,6 @@ const getDefaultValidationMessage = (type) => { switch (type) { case 'text': - return getConstant('VALIDATION_MESSAGE_TEXT'); case 'textarea': return getConstant('VALIDATION_MESSAGE_TEXT'); case 'number': @@ -163,6 +161,8 @@ return getConstant('VALIDATION_MESSAGE_RADIO'); case 'checkbox': return getConstant('VALIDATION_MESSAGE_CHECKBOX'); + case 'multi-checkbox': + return getConstant('VALIDATION_MESSAGE_MULTI_CHECKBOX'); case 'js-combobox': return getConstant('VALIDATION_MESSAGE_SELECT'); default: @@ -202,14 +202,13 @@ const target = $(el); const id = target.attr('id'); const typ = getValidationTypeForElement(target); - target.attr('validation-help-block', `help-${id}`); const help = blockHelp(`help-${id}`, getValidationMessage(el)); - // If its a radio then the 'required' status should apply to the group - if (typ === 'radio') { - target.closest('.form-group').before(help); - // If its a checkbox, add the help block below the checkbox container - } else if (typ === 'checkbox') { - target.closest('.checkbox').after(help); + + target.attr('validation-help-block', `help-${id}`); + if (target.closest('fieldset').length > 0 && target.closest('fieldset').find('legend').length > 0) { + target.closest('fieldset').find('legend').after(help); + } else if (typ === 'radio' || typ === 'checkbox') { + target.closest('.form-group').after(help); } else { target.after(help); } @@ -223,12 +222,10 @@ let anyInvalid = false; let firstInvalid; validatable.each((i, el) => { - const type = getValidationTypeForElement(el); const required = ($(el).attr('aria-required') && $(el).attr('aria-required') === 'true'); - // If the field is required OR its not empty if (required || $(el).val().trim() !== '') { - if (isValid(type, getValue(type, el))) { + if (isValid($(el))) { valid(el); } else { anyInvalid = true; diff --git a/lib/assets/javascripts/utils/isValidInputType.js b/lib/assets/javascripts/utils/isValidInputType.js index 0a54d99..d116019 100644 --- a/lib/assets/javascripts/utils/isValidInputType.js +++ b/lib/assets/javascripts/utils/isValidInputType.js @@ -1,4 +1,4 @@ -import { isString, isNumber } from './isType'; +import { isObject, isString, isNumber } from './isType'; import getConstant from '../constants'; /* Validates whether or not the value passed matches to a valid email @@ -63,3 +63,17 @@ } return false; }; + +export const isValidCheckbox = (el) => { + if (isObject(el)) { + return el.is(':checked'); + } + return false; +}; + +export const isValidMultiCheckbox = (el) => { + if (isObject(el) && isObject(el.closest('fieldset'))) { + return el.closest('fieldset').find('input:checked').length > 0; + } + return false; +};