diff --git a/app/views/contact_us/contacts/_new_left.html.erb b/app/views/contact_us/contacts/_new_left.html.erb new file mode 100644 index 0000000..1d8f999 --- /dev/null +++ b/app/views/contact_us/contacts/_new_left.html.erb @@ -0,0 +1,42 @@ +<%= form_for @contact, url: contacts_path do |f| %> +<% if ContactUs.require_name %> +
+ <%= f.label(:name, _('Name'), class: 'control-label') %> + <%= f.text_field(:name, + class: "form-control", + value: current_user.nil? ? '' : current_user.name(false), + readonly: current_user.present?, + "aria-required": true) %> +
+<% end %> +
+ <%= f.label(:email, _('Email'), class: 'control-label') %> + <%= f.email_field(:email, + class: "form-control", + value: current_user.nil? ? '' : current_user.email, + readonly: current_user.present?, + "aria-required": true) %> +
+<% if ContactUs.require_subject %> +
+ <%= f.label(:subject, _('Subject')) %> + <%= f.text_field(:subject, + class: "form-control", + "aria-required": true) %> +
+<% end %> +
+ <%= f.label(:message, _('Message')) %> + <%= f.text_area(:message, + class: "form-control", + rows: 10, + "aria-required": true) %> +
+<% if !user_signed_in? then %> +
+ <%= label_tag(nil, _('Security check')) %> + <%= recaptcha_tags %> +
+<% end %> + <%= f.button(_('Submit'), class: "btn btn-default", type: "submit") %> +<% end %> \ No newline at end of file diff --git a/app/views/contact_us/contacts/_new_right.html.erb b/app/views/contact_us/contacts/_new_right.html.erb new file mode 100644 index 0000000..8d87283 --- /dev/null +++ b/app/views/contact_us/contacts/_new_right.html.erb @@ -0,0 +1,39 @@ + +
+ <%= Rails.configuration.branding[:organisation][:name] %>
+ <% [Rails.configuration.branding[:organisation][:address_line1], + Rails.configuration.branding[:organisation][:address_line2], + Rails.configuration.branding[:organisation][:address_line3], + Rails.configuration.branding[:organisation][:address_line4], + Rails.configuration.branding[:organisation][:address_country]].each do |addr_line| %> +<% if addr_line.present? %> + <%= addr_line %>
+<% end %> +<% end %> +
+<% +telephone=Rails.configuration.branding[:organisation][:telephone] +if telephone.present? %> + <%= "#{_('Helpline')} #{telephone}" %> +<% end %> +<% +email=Rails.configuration.branding[:organisation][:email] +if email.present? %> +
+ <%= _('Email') %> + "><%= email %> +
+<% end %> +<% +link=Rails.configuration.branding[:organisation][:google_maps_link] +if link.present? %> + +<% end %> \ No newline at end of file diff --git a/app/views/contact_us/contacts/new.html.erb b/app/views/contact_us/contacts/new.html.erb index c8883dd..f98ec59 100644 --- a/app/views/contact_us/contacts/new.html.erb +++ b/app/views/contact_us/contacts/new.html.erb @@ -1,86 +1,20 @@ -<% javascript "views/contacts/new_contact.js" %> -

<%= _("Contact Us") %>

-

-<%= raw _('%{application_name} is provided by the %{organisation_name}.
You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below.') % {organisation_name: Rails.configuration.branding[:organisation][:name], - organisation_url: Rails.configuration.branding[:organisation][:url], - application_name: Rails.configuration.branding[:application][:name]} %> -

-
- -
- - <%= form_for @contact, url: contacts_path, html: {class: "roadmap-form"} do |f| %> -
- <% if ContactUs.require_name %> -
- <%= f.label(:name, _('Name'), class: 'required') %> - <%= f.text_field(:name, class: "left-indent required input-large", value: current_user.nil? ? '' : current_user.name(false), readonly: !current_user.nil?) %> -
- <% end %> - -
- <%= f.label(:email, _('Email'), class: 'required') %> - <%= f.text_field(:email, class: "left-indent required input-large", value: current_user.nil? ? '' : current_user.email, readonly: !current_user.nil?) %> - -
- - <% if ContactUs.require_subject %> -
- <%= f.label(:subject, _('Subject'), class: 'required') %> - <%= f.text_field(:subject, class: "left-indent required input-large") %> -
- <% end %> - -
- <%= f.label(:message, _('Message'), class: "align-top required") %> - <%= f.text_area(:message, class: "required input-large", rows: 10, style: "height: 160px;") %> -
- <% if !user_signed_in? then %> -
- <%= label_tag(nil, _('Security check'), class: "align-top required") %> -
- <%= recaptcha_tags %> -
-
- <% end %> - -
-
 
- <%= render partial: 'shared/accessible_submit_button', - locals: {id: 'create_contact_submit', - val: 'Submit', - disabled_initially: true, - tooltip: _('Fill in the required fields')} %> -
-
- <% end %> - +
+

<%= _("Contact Us") %>

+

+ <%= raw _('%{application_name} is provided by the %{organisation_name}.
You can find out more about us on our website. If you would like to contact us about %{application_name}, please fill out the form below.') % {organisation_name: Rails.configuration.branding[:organisation][:name], + organisation_url: Rails.configuration.branding[:organisation][:url], + application_name: Rails.configuration.branding[:application][:name]} %> +

- - -
-
    - <% [Rails.configuration.branding[:organisation][:name], - Rails.configuration.branding[:organisation][:address_line1], - Rails.configuration.branding[:organisation][:address_line2], - Rails.configuration.branding[:organisation][:address_line3], - Rails.configuration.branding[:organisation][:address_line4], - Rails.configuration.branding[:organisation][:address_country]].each do |addr_line| %> - - <% if addr_line %> -
  • <%= addr_line %>
  • - <% end %> - <% end %> -
- -

<%= "#{_('Helpline')} #{Rails.configuration.branding[:organisation][:telephone]}" %>

-

<%= _('Email') %> <%= Rails.configuration.branding[:organisation][:email] %>

- - -
- - +
+
+
+ <%= render :partial => "contact_us/contacts/new_left" %> +
+
+
+ <%= render :partial => "contact_us/contacts/new_right" %>
-
+
\ No newline at end of file diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js index bc7d828..8ba5321 100644 --- a/lib/assets/javascripts/application.js +++ b/lib/assets/javascripts/application.js @@ -36,12 +36,15 @@ //= require define.js //= require utils/debounce.js //= require utils/tinymce.js +//= require utils/validate.js +//= require utils/ariatiseForm.js // views JS files //= require views/notes/add.js //= require views/notes/show.js //= require views/notes/edit.js //= require views/notes/archive.js +//= require views/contacts/new.js // Rest of JS files //= require dmproadmap/accordions.js diff --git a/lib/assets/javascripts/utils/ariatiseForm.js b/lib/assets/javascripts/utils/ariatiseForm.js new file mode 100644 index 0000000..6762df8 --- /dev/null +++ b/lib/assets/javascripts/utils/ariatiseForm.js @@ -0,0 +1,122 @@ +/* + dmproadmap.utils.ariatiseForm augmentates a HTML form by: + - Associating help text with form controls + - Adding validation state to each form group + - Adding specific attributes for user with assistive technologies. + + For example the following form : +
+
+ + +
+
+ + +
+
+ + +
+ +
+ will be augmentated as follows: +
+
+ + + +
+
+ + + +
+
+ + +
+ +
+ and any time the buttton is clicked the validation according to each type (e.g. text, email) will be triggered. An invalid result for a form-control will: + 1. Add has-error class to its form-group parent and aria-invalid="true" to the form-control + 2. Show its help-block following sibling + 3. Prevent form to be submitted +*/ +(function(ctx){ + var requiredFields=(function(selector){ + return $(selector).find('.form-control').filter('[aria-required="true"]'); + }); + var blockHelp=(function (id,type){ + var msg='Please fill out this field with a valid '+type+'.'; //TODO internationalisation + return ''; + }); + var ariaDescribedBy=(function(value){ + return { 'aria-describedby': value }; + }); + var ariaInvalid=(function(value){ + return { 'aria-invalid': value }; + }); + var validationStates={ + hasWarning: 'has-warning', + hasError: 'has-error', + hasSuccess: 'has-success' + }; + var getTypeForSubmittableElement=(function(el){ + // Reference from https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content + if($(el).is('input')){ + return $(el).attr('type'); // available types at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form__types + } + else if($(el).is('select')){ + return 'select'; + } + else if($(el).is('textarea')){ + return 'textarea'; + } + else + return 'unknown'; + }); + var isValid=(function(type, value){ + // 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 + switch(type){ + case 'text': + case 'textarea': + return dmproadmap.utils.validate.text(value); + case 'email': + return dmproadmap.utils.validate.email(value); + default: + return false; + } + }); + var valid=(function(el){ + $(el).parent().removeClass(validationStates.hasError); + $(el).attr(ariaInvalid(false)); + $(el).next().hide(); + }); + var invalid=(function(el){ + $(el).parent().addClass(validationStates.hasError); + $(el).attr(ariaInvalid(true)); + $(el).next().show(); + }); + ctx.init=ctx.init || (function(options){ + if($ && options && options.selector){ + requiredFields(options.selector).each(function(i,el){ + $(el).attr(ariaDescribedBy('help'+i)); + $(el).after(blockHelp('help'+i, getTypeForSubmittableElement(el))); + }); + $(options.selector+' [type="submit"]').click(function(e){ + requiredFields(options.selector).each(function(i,el){ + if(isValid(getTypeForSubmittableElement(el),$(el).val())){ + valid(el); + } + else{ + e.preventDefault(); + invalid(el); + } + }); + }); + } + }); +})(define('dmproadmap.utils.ariatiseForm')); \ No newline at end of file diff --git a/lib/assets/javascripts/utils/validate.js b/lib/assets/javascripts/utils/validate.js new file mode 100644 index 0000000..5ff7c09 --- /dev/null +++ b/lib/assets/javascripts/utils/validate.js @@ -0,0 +1,24 @@ +(function(ctx){ + /* + Validates whether or not the value length is greather than zero after + removing whitespace from both ends of the string. + @param value String to verify its length + @return true if it has a length greater than zero; otherwise, false. + */ + ctx.text = ctx.text || (function(value){ + if(Object.prototype.toString.call(value) === '[object String]') + return value.trim().length > 0; + return false; + }); + /* + Validates whether or not the value matches the regular expression + for an email + @param value String the to search for a match + @return true if there is match between the email regex and the specific string; otherwise, false. + */ + ctx.email = ctx.email || (function(value){ + if(Object.prototype.toString.call(value) === '[object String]') + return /[^@\s]+@(?:[-a-z0-9]+\.)+[a-z]{2,}$/.test(value); + return false; + }); +})(define('dmproadmap.utils.validate')); \ No newline at end of file diff --git a/lib/assets/javascripts/views/contacts/new.js b/lib/assets/javascripts/views/contacts/new.js new file mode 100644 index 0000000..771a2c5 --- /dev/null +++ b/lib/assets/javascripts/views/contacts/new.js @@ -0,0 +1,3 @@ +$(document).ready(function(){ + dmproadmap.utils.ariatiseForm.init({ selector: '#new_contact_us_contact' }); +}); \ No newline at end of file diff --git a/lib/assets/javascripts/views/contacts/new_contact.js b/lib/assets/javascripts/views/contacts/new_contact.js deleted file mode 100644 index 9f2ea63..0000000 --- a/lib/assets/javascripts/views/contacts/new_contact.js +++ /dev/null @@ -1,25 +0,0 @@ -var RecaptchaOptions = { - theme : "clean" -}; - -$(document).ready(function(){ - // Run the input validations when the focus changes - $("#contact_us_contact_email").blur(function(){ - toggleFormElementError(this, validateEmail($(this).val().trim())); - }); - - $("input[type='text'], input[type='email'], textarea").change(function(e){ - var enable = ($("#contact_us_contact_name").val().trim().length > 0 && - validateEmail($("#contact_us_contact_email").val().trim()) === '' && - $("#contact_us_contact_subject").val().trim().length > 0 && - $("#contact_us_contact_message").val().trim().length > 0); - - // Disabled recaptcha since always sets enable, TODO change when we tackle https://github.com/DMPRoadmap/roadmap/issues/501 - // if($("#recaptcha-anchor")){ - // if($("#recaptcha-anchor").prop('aria-checked') != 'true'){ - // enable = false; - // } - // } - $("#create_contact_submit").attr('aria-disabled', !enable); - }); -});