diff --git a/app/views/plans/_share_form.html.erb b/app/views/plans/_share_form.html.erb index 46002cf..ec785a6 100644 --- a/app/views/plans/_share_form.html.erb +++ b/app/views/plans/_share_form.html.erb @@ -80,7 +80,7 @@
-

<%= _('Permissions') %>

+
<%= f.label :access_level, raw("#{f.radio_button :access_level, 3, "aria-required": true} #{_('Co-owner: can edit project details, change visibility, and add collaborators')}") %>
diff --git a/app/views/plans/new.html.erb b/app/views/plans/new.html.erb index 4a9f9c9..a6c92fd 100644 --- a/app/views/plans/new.html.erb +++ b/app/views/plans/new.html.erb @@ -12,8 +12,10 @@
<%= form_for Plan.new, url: plans_path do |f| %> -

<%= _('What research project are you planning?') %>

+
<%= f.text_field(:title, class: 'form-control', 'aria-describedby': 'project-title', 'aria-required': 'true', 'data-toggle': 'tooltip', @@ -26,8 +28,10 @@
-

<%= _('Select the primary research organisation') %>

+
<%= render partial: "shared/accessible_combobox", locals: {name: 'plan[org_name]', @@ -48,8 +52,10 @@
-

<%= _('Select the primary funding organisation') %>

+
<%= render partial: "shared/accessible_combobox", locals: {name: 'plan[funder_name]', diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js index 8f6ef35..e1f41ec 100644 --- a/lib/assets/javascripts/application.js +++ b/lib/assets/javascripts/application.js @@ -36,9 +36,8 @@ import './views/sections/edit'; import './views/sections/index'; import './views/sections/new'; -import './views/questions/edit'; +import './views/questions/new_edit'; import './views/questions/index'; -import './views/questions/new'; import './views/questions/show'; import './views/question_options/index'; import './views/shared/create_account_form'; diff --git a/lib/assets/javascripts/utils/ariatiseForm.js b/lib/assets/javascripts/utils/ariatiseForm.js index 0264863..ecb3980 100644 --- a/lib/assets/javascripts/utils/ariatiseForm.js +++ b/lib/assets/javascripts/utils/ariatiseForm.js @@ -41,30 +41,6 @@ } return []; }; -const blockHelp = (id, msg) => { - if (isString(id) && isString(msg)) { - return ``; - } - return ''; -}; -const ariaDescribedBy = (value) => { - if (value) { - return { 'aria-describedby': value }; - } - return null; -}; -const ariaInvalid = (value) => { - if (isBoolean(value)) { - return { 'aria-invalid': value }; - } - return { 'aria-invalid': false }; -}; - -const validationStates = { - hasWarning: 'has-warning', - hasError: 'has-error', - hasSuccess: 'has-success' }; - const getValidationTypeForElement = (el) => { const validation = $(el).attr('data-validation'); // if the specified validation type is defined @@ -85,7 +61,47 @@ } return false; }; - +const blockHelp = (id, msg) => { + if (isString(id) && isString(msg)) { + return ``; + } + return ''; +}; +const ariaDescribedBy = (value) => { + if (value) { + return { 'aria-describedby': value }; + } + return null; +}; +const ariaInvalid = (value) => { + if (isBoolean(value)) { + return { 'aria-invalid': value }; + } + return { 'aria-invalid': false }; +}; +const addAsterisk = (el) => { + const asterisk = '* '; + if (isObject(el)) { + switch (getValidationTypeForElement(el)) { + case 'checkbox': { + el.after(asterisk); + break; + } + default: { + const label = el.closest('.form-group').find('label'); + if (isObject(label)) { + $(label[0]).before(asterisk); + } + break; + } + } + } +}; +const validationStates = { + hasWarning: 'has-warning', + hasError: 'has-error', + hasSuccess: 'has-success', +}; const getValue = (type, el) => { switch (type) { case 'radio': @@ -180,12 +196,16 @@ // Add validation error message sections for each validatable input element validatable.each((i, el) => { - $(el).attr(ariaDescribedBy(`help${i}`)); - $(el).after(blockHelp(`help${i}`, getValidationMessage(el))); + const target = $(el); + target.attr(ariaDescribedBy(`help${i}`)); + target.after(blockHelp(`help${i}`, getValidationMessage(el))); + if (target.attr('aria-required') === 'true') { + addAsterisk(target); + } }); // Bind validations to the form's submit button - $(`${options.selector} [type="submit"]`).click((e) => { + $(`${options.selector}`).submit((e) => { let anyInvalid = false; validatable.each((i, el) => { const type = getValidationTypeForElement(el); diff --git a/lib/assets/javascripts/utils/validation.js b/lib/assets/javascripts/utils/validation.js index 09ff999..84c381a 100644 --- a/lib/assets/javascripts/utils/validation.js +++ b/lib/assets/javascripts/utils/validation.js @@ -10,24 +10,6 @@ } return []; }; -const blockHelp = (id, msg) => { - if (isString(id) && isString(msg)) { - return ``; - } - return ''; -}; -const ariaInvalid = (value) => { - if (isBoolean(value)) { - return { 'aria-invalid': value }; - } - return { 'aria-invalid': false }; -}; - -const validationStates = { - hasWarning: 'has-warning', - hasError: 'has-error', - hasSuccess: 'has-success' }; - const getValidationTypeForElement = (el) => { const validation = $(el).attr('data-validation'); // if the specified validation type is defined @@ -49,6 +31,43 @@ return false; }; +const blockHelp = (id, msg) => { + if (isString(id) && isString(msg)) { + return ``; + } + return ''; +}; +const addAsterisk = (el) => { + const asterisk = '* '; + if (isObject(el)) { + switch (getValidationTypeForElement(el)) { + case 'checkbox': { + el.after(asterisk); + break; + } + default: { + const label = el.closest('.form-group').find('label'); + if (isObject(label)) { + $(label[0]).before(asterisk); + } + break; + } + } + } +}; +const ariaInvalid = (value) => { + if (isBoolean(value)) { + return { 'aria-invalid': value }; + } + return { 'aria-invalid': false }; +}; + +const validationStates = { + hasWarning: 'has-warning', + hasError: 'has-error', + hasSuccess: 'has-success', +}; + const getValue = (type, el) => { switch (type) { case 'radio': @@ -148,6 +167,9 @@ target.attr('data-validatable', 'true'); } } + if (target.attr('aria-required') === 'true') { + addAsterisk(target); + } }; const removeValidationMessage = (el) => { const target = $(el); diff --git a/lib/assets/javascripts/views/questions/edit.js b/lib/assets/javascripts/views/questions/edit.js deleted file mode 100644 index 2a12c4b..0000000 --- a/lib/assets/javascripts/views/questions/edit.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Tinymce } from '../../utils/tinymce'; -import ariatiseForm from '../../utils/ariatiseForm'; -import onChangeQuestionFormat from './sharedEventHandlers'; - -$(() => { - Tinymce.init({ selector: '.question' }); - ariatiseForm({ selector: '.question_form' }); - $('.edit_question_cancel').on('click', (e) => { - e.preventDefault(); - const questionEdit = $(e.target).closest('.question_edit'); - questionEdit.hide(); - questionEdit.parent().find('.question_show').show(); - }); - $('[name="question[question_format_id]"]').on('change', onChangeQuestionFormat); -}); diff --git a/lib/assets/javascripts/views/questions/new.js b/lib/assets/javascripts/views/questions/new.js deleted file mode 100644 index b26541e..0000000 --- a/lib/assets/javascripts/views/questions/new.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Tinymce } from '../../utils/tinymce'; -import ariatiseForm from '../../utils/ariatiseForm'; -import onChangeQuestionFormat from './sharedEventHandlers'; - -$(() => { - Tinymce.init({ selector: '.question' }); - ariatiseForm({ selector: '.question_form' }); - $('.new_question_cancel').on('click', (e) => { - const questionNew = $(e.target).closest('.question_new'); - questionNew.hide(); - questionNew.closest('.row').find('.question_new_link').show(); - }); - $('[name="question[question_format_id]"]').on('change', onChangeQuestionFormat); -}); diff --git a/lib/assets/javascripts/views/questions/new_edit.js b/lib/assets/javascripts/views/questions/new_edit.js new file mode 100644 index 0000000..ecaf228 --- /dev/null +++ b/lib/assets/javascripts/views/questions/new_edit.js @@ -0,0 +1,20 @@ +import { Tinymce } from '../../utils/tinymce'; +import ariatiseForm from '../../utils/ariatiseForm'; +import onChangeQuestionFormat from './sharedEventHandlers'; + +$(() => { + Tinymce.init({ selector: '.question' }); + ariatiseForm({ selector: '.question_form' }); + $('.edit_question_cancel').on('click', (e) => { + e.preventDefault(); + const questionEdit = $(e.target).closest('.question_edit'); + questionEdit.hide(); + questionEdit.parent().find('.question_show').show(); + }); + $('.new_question_cancel').on('click', (e) => { + const questionNew = $(e.target).closest('.question_new'); + questionNew.hide(); + questionNew.closest('.row').find('.question_new_link').show(); + }); + $('[name="question[question_format_id]"]').on('change', onChangeQuestionFormat); +}); diff --git a/lib/assets/stylesheets/overrides.scss b/lib/assets/stylesheets/overrides.scss index a833b18..d0801b7 100644 --- a/lib/assets/stylesheets/overrides.scss +++ b/lib/assets/stylesheets/overrides.scss @@ -9,6 +9,11 @@ $highlight-color: $black; $highlight-background-color: #F36F24; +/**** assign the red color to text ****/ +.red { + color: $red; +} + /**** font configuration ****/ @font-face { font-family: 'GillSansLight'; @@ -477,15 +482,24 @@ } /* Plan creation */ -.create-plan-or { - padding: 5px 0 0 15px; -} -.create-plan-checkbox { - margin-left: -40px; - margin-top: -5px; -} -.create-plan-mock { - margin-left: -40px; +#new_plan { + .create-plan-or { + padding: 5px 0 0 15px; + } + .create-plan-checkbox { + margin-left: -40px; + margin-top: -5px; + } + .create-plan-mock { + margin-left: -40px; + } + .h2-label { + font-size: 30px; + font-weight: normal; + } + .red { + margin-left: 15px; + } } /* Sharp edges */