- <%= render partial: 'shared/accessible_input',
- locals: {type: 'password', id: 'user_password', name: 'user[password]', label: _("Password"),
- classes: 'required'} %>
+
+
+ <%= render partial: 'shared/accessible_submit_button',
+ locals: {id: 'sign-in-button',
+ val: 'Sign In',
+ disabled_initially: true,
+ classes: 'small-input-button',
+ tooltip: _('Enter your email and password.')} %>
-
- <%= link_to _('Forgot password?'), new_password_path('user'), :class => "primary-color" %>
+
+ <%= link_to _('Forgot password?'), new_password_path('user'), :class => "primary-color" %>
+
diff --git a/app/views/shared/_register_form.html.erb b/app/views/shared/_register_form.html.erb
index d1f2c5a..2bd0d8e 100644
--- a/app/views/shared/_register_form.html.erb
+++ b/app/views/shared/_register_form.html.erb
@@ -1,36 +1,65 @@
-<%= form_for resource, as: 'user', url: registration_path("user"), html: {autocomplete: "off", class: "roadmap-form user-registration"} do |f| %>
- <%= devise_error_messages! %>
-
+<% javascript "shared/register_form.js" %>
+
+<%= form_for resource, as: 'user', url: registration_path("user"), html: {autocomplete: "off", class: "roadmap-form register-form"} do |f| %>
<% end %>
diff --git a/config/application.rb b/config/application.rb
index 786106b..cff295b 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -86,11 +86,12 @@
config.assets.precompile += %w(roadmap.js
answers/status.js
devise/passwords/new.js
+ devise/registrations/edit.js
plans/new_plan.js
contacts/new_contact.js
home/index.js
- shared/register_form.js
- shared/login_form.js)
+ shared/login_form.js
+ shared/register_form.js)
config.autoload_paths += %W(#{config.root}/lib)
config.action_controller.include_all_helpers = true
diff --git a/lib/assets/javascripts/devise/passwords/new.js b/lib/assets/javascripts/devise/passwords/new.js
index 7628f69..55987fb 100644
--- a/lib/assets/javascripts/devise/passwords/new.js
+++ b/lib/assets/javascripts/devise/passwords/new.js
@@ -1,5 +1,10 @@
$(document).ready(function(){
- $("#password-reset-form #user_email").change(function(){
- $("#password-reset-form #password-reset-button").attr('aria-disabled', validateEmail($(this).val()) != '');
+ $("#user_email").blur(function(){
+ $("#password-reset-button").attr('aria-disabled', validateEmail($(this).val()) != '');
});
+
+ // Run the input validations when the focus changes
+ $("#user_email").blur(function(){
+ toggleInputError(this, validateEmail($(this).val().trim()));
+ });
});
\ No newline at end of file
diff --git a/lib/assets/javascripts/devise/registrations/edit.js b/lib/assets/javascripts/devise/registrations/edit.js
new file mode 100644
index 0000000..85f93a7
--- /dev/null
+++ b/lib/assets/javascripts/devise/registrations/edit.js
@@ -0,0 +1,57 @@
+$(document).ready(function(){
+ // See if we should enable the submit button when a required input changes
+ $("input").change(function(){
+ toggleSubmit();
+ });
+
+ // Run the input validations when the focus changes
+ $("#user_email, #user_recovery_email").blur(function(){
+ let msg = validateEmail($(this).val().trim());
+ // If the standard email validation was successful validate that they do not match
+ toggleInputError(this, (msg != '' ? msg : validateEmailsDoNotMatch()));
+ });
+ $("#user_current_password").blur(function(){
+ toggleInputError(this, validatePassword($(this).val().trim()));
+ });
+ $("#user_new_password, #user_password_confirmation").blur(function(){
+ let msg = validatePassword($(this).val().trim());
+ // If the standard password validation was successful validate that they match
+ toggleInputError(this, (msg != '' ? msg : validatePasswordsMatch()));
+ });
+
+ // Toggle the password field so that its visible/masked
+ $("#passwords_show").click(function(){
+ let typ = $("#user_current_password").attr('type');
+ $("#user_current_password").attr('type', (typ === 'password' ? 'text' : 'password'));
+ $("#user_new_password").attr('type', (typ === 'password' ? 'text' : 'password'));
+ $("#user_password_confirmation").attr('type', (typ === 'password' ? 'text' : 'password'));
+ });
+
+ // Make sure the show password checkbox is unchecked on load
+ $("#passwords_show").attr("checked", false);
+
+ toggleSubmit();
+
+ function validateEmailsDoNotMatch(){
+ let email = $("form.register-form #user_email").val().trim();
+ let recovery = $("form.register-form #user_recovery_email").val().trim();
+ return (email === recovery ? (email != '' ? __('Emails must be different') : '') : '');
+ }
+
+ function validatePasswordsMatch(){
+ let pwd = $("#user_new_password").val().trim();
+ let conf = $("#user_password_confirmation").val().trim();
+ return (pwd != conf ? (pwd != '' ? __('Passwords must match') : '') : '');
+ }
+
+ // Display the submit button only if there is a valid email and password
+ function toggleSubmit(){
+ let disabled = ($("#user_firstname").val().trim().length <= 0 ||
+ $("#user_surname").val().trim().length <= 0 ||
+ validateEmail($("#user_email").val()) != '' ||
+ validateEmail($("#user_recovery_email").val()) != '' ||
+ $("#user_new_password").val() != $("#user_password_confirmation").val());
+ $("#update").attr('aria-disabled', disabled);
+ }
+});
+
diff --git a/lib/assets/javascripts/roadmap-form.js b/lib/assets/javascripts/roadmap-form.js
index 143a424..ce8bc00 100644
--- a/lib/assets/javascripts/roadmap-form.js
+++ b/lib/assets/javascripts/roadmap-form.js
@@ -1,6 +1,18 @@
-$(document).ready(function(){
-
-});
+// ---------------------------------------------------------------------------
+function toggleInputError(input, errorMessage){
+ let err = $(input).siblings("span.error-tooltip");
+ if(err.length <= 0){
+ err = $(input).siblings("span.error-tooltip-right");
+ }
+
+ if(err.length > 0 && (errorMessage === '' || $(input).val().trim().length <= 0)){
+ err.html('').attr('role', '');
+ $(input).removeClass('red-border');
+ }else{
+ err.html(__('Error: ') + errorMessage).attr('role', 'tooltip');
+ $(input).addClass('red-border');
+ }
+}
// ---------------------------------------------------------------------------
function validatePassword(sPassword) {
@@ -21,4 +33,13 @@
else {
return __('Invalid Email');
}
+}
+
+// ---------------------------------------------------------------------------
+function validateValuesDoNotMatch(inputA, inputB, message){
+ return ($(inputA).val().trim() === $(inputB).val().trim() ? message : '');
+}
+
+function processValidations(a, b){
+ return '';
}
\ No newline at end of file
diff --git a/lib/assets/javascripts/shared/login_form.js b/lib/assets/javascripts/shared/login_form.js
index f7af526..ca36b6d 100644
--- a/lib/assets/javascripts/shared/login_form.js
+++ b/lib/assets/javascripts/shared/login_form.js
@@ -4,10 +4,35 @@
$(this).siblings(".form-submit").attr('aria-disabled', $(this).val() != "true");
});
+ // See if we should enable the submit button when a required input changes
$("form.login-form input[class*='required']").change(function(){
toggleLogInSubmit();
});
+ // Run the input validations when the focus changes
+ $("form.login-form #user_email").blur(function(){
+ toggleInputError(this, validateEmail($(this).val().trim()));
+ });
+ $("form.login-form #user_password").blur(function(){
+ toggleInputError(this, validatePassword($(this).val().trim()));
+ });
+
+ // Toggle the password field so that its visible/masked
+ $("form.login-form #password_show").click(function(){
+ let typ = $("form.login-form #user_password").attr('type');
+ $("form.login-form #user_password").attr('type', (typ === 'password' ? 'text' : 'password'));
+ });
+
+ // Run the validations in case the page was refreshed
+ toggleInputError($("form.login-form #user_email"),
+ validateEmail($("form.login-form #user_email").val().trim()));
+ toggleInputError($("form.login-form #user_password"),
+ validatePassword($("form.login-form #user_password").val().trim()));
+
+ // Make sure the show password checkbox is unchecked on load
+ $("form.login-form #password_show").attr("checked", false);
+
+ // Display the submit button only if there is a valid email and password
function toggleLogInSubmit(){
let disabled = (validateEmail($("form.login-form #user_email").val()) != '' ||
validatePassword($("form.login-form #user_password").val()) != '');
diff --git a/lib/assets/javascripts/shared/register_form.js b/lib/assets/javascripts/shared/register_form.js
index 563fe81..aaaa84b 100644
--- a/lib/assets/javascripts/shared/register_form.js
+++ b/lib/assets/javascripts/shared/register_form.js
@@ -1,37 +1,54 @@
$(document).ready(function(){
// If the hidden valid-form field is set to true then enable the submit button
- $("form.user-registration #valid-form").change(function(){
+ $("form.register-form #valid-form").change(function(){
$(this).siblings(".form-submit").attr('aria-disabled', $(this).val() != "true");
});
- $("form.user-registration input[class*='required']").change(function(){
+ // See if we should enable the submit button when a required input changes
+ $("form.register-form input[class*='required']").change(function(){
toggleRegisterSubmit();
});
+
+ // Run the input validations when the focus changes
+ $("form.register-form #user_email, form.register-form #user_recovery_email").blur(function(){
+ let msg = validateEmail($(this).val().trim());
+ // If the standard email validation was successful validate that they do not match
+ toggleInputError(this, (msg != '' ? msg : validateEmailsDoNotMatch()));
+ });
+ $("form.register-form #user_password").blur(function(){
+ toggleInputError(this, validatePassword($(this).val().trim()));
+ });
+
+ // Toggle the password field so that its visible/masked
+ $("form.register-form #password_show").click(function(){
+ let typ = $("form.register-form #user_password").attr('type');
+ $("form.register-form #user_password").attr('type', (typ === 'password' ? 'text' : 'password'));
+ });
+
+ // Run the validations in case the page was refreshed
+ toggleInputError($("form.register-form #user_email"),
+ validateEmail($("form.register-form #user_email").val().trim()));
+ toggleInputError($("form.register-form #user_recovery_email"),
+ validateEmail($("form.register-form #user_recovery_email").val().trim()));
+ toggleInputError($("form.register-form #user_password"),
+ validatePassword($("form.register-form #user_password").val().trim()));
+
+ // Make sure the show password checkbox is unchecked on load
+ $("form.register-form #password_show").attr("checked", false);
- $("form.user-registration #user_email, form.user-registration #user_recovery_email").blur(function(){
- emailsMatch($(this).parent('form'));
- });
+ function validateEmailsDoNotMatch(){
+ let email = $("form.register-form #user_email").val().trim();
+ let recovery = $("form.register-form #user_recovery_email").val().trim();
+ return (email === recovery ? (email != '' ? __('Emails must be different') : '') : '');
+ }
function toggleRegisterSubmit(){
- let disabled = ($("#user_firstname").val().trim().length <= 0 ||
- $("#user_surname").val().trim().length <= 0 ||
- $("#user_email").val().trim().length <= 0 ||
- $("#user_recovery_email").val().trim().length <= 0 ||
- $("#user_password").val().trim().length <= 0 ||
- $("#user_email").val() === $("#user_recovery_email").val());
- $("form.user-registration #register-button").attr('aria-disabled', disabled);
+ let disabled = ($("form.register-form #user_firstname").val().trim().length <= 0 ||
+ $("form.register-form #user_surname").val().trim().length <= 0 ||
+ validateEmail($("form.register-form #user_email").val()) != '' ||
+ validateEmail($("form.register-form #user_recovery_email").val()) != '' ||
+ !$("form.register-form #user_accept_terms").prop('checked') ||
+ $("form.register-form #user_email").val() === $("form.register-form #user_recovery_email").val());
+ $("form.register-form #register-button").attr('aria-disabled', disabled);
}
-
- function emailsMatch(form){
- let email = $(this).find('#user_email');
- let recovery = $(this).find('#user_recovery_email');
-
- if($(email).val().trim() === $(recovery).val().trim()){
- $("span." + $(email).attr('roadmap-js-id') + "_error").html('').attr('role', '');
- $("input[roadmap-js-id='" + $(email).attr('roadmap-js-id') + "']").removeClass('red-border');
- }else{
- $("span." + $(email).attr('roadmap-js-id') + "_error").attr('role', 'tooltip');
- $("input[roadmap-js-id='" + $(email).attr('roadmap-js-id') + "']").addClass('red-border');
- }
- }
});
diff --git a/lib/assets/stylesheets/roadmap-form.scss b/lib/assets/stylesheets/roadmap-form.scss
index 9dc7e01..5b5423e 100644
--- a/lib/assets/stylesheets/roadmap-form.scss
+++ b/lib/assets/stylesheets/roadmap-form.scss
@@ -108,6 +108,9 @@
.left-indent {
margin-left: 15px;
}
+ .right-indent {
+ margin-right: 5px;
+ }
.input-extra-large {
width: 70%;
}
@@ -169,6 +172,7 @@
border-bottom: 6px solid transparent;
border-right: 6px solid $dark-grey;
}
+ /*
.submit-tooltip {
display: none;
margin-left: 5px;
@@ -183,7 +187,7 @@
padding: 5px 5px 8px 5px;
border-radius: 2px;
}
- }
+ }*/
input.small-input-button {
width: 250px;
}
@@ -198,23 +202,23 @@
box-shadow: 0 0 6px $error-background;
}
- .error-tooltip {
+ .error-tooltip, .error-tooltip-right, .submit-tooltip {
display: none;
- width: 270px;
- }
-
- .error-tooltip[role='tooltip'] {
+ width: 45%;
background: $error-background;
border-radius: 3px;
- top: 55px;
color: $error-color;
padding: 4px 6px;
- display: inline;
+ }
+
+ .error-tooltip[role='tooltip'], .submit-tooltip[role='tooltip'] {
+ top: 55px;
left: 0;
+ display: inline;
position: absolute;
z-index: 9;
}
- .error-tooltip[role='tooltip']:before {
+ .error-tooltip[role='tooltip']:before, .submit-tooltip[role='tooltip']:before {
display: inline;
position: absolute;
top: -5px;
@@ -224,6 +228,22 @@
border-right: 5px solid transparent;
border-bottom: 5px solid $error-background;
}
+
+ .error-tooltip-right[role="tooltip"] {
+ top: 0;
+ left: 500px;
+ display: inline;
+ }
+ .error-tooltip-right[role='tooltip']:before {
+ display: inline;
+ position: absolute;
+ left: -5px;
+ width: 0;
+ height: 0;
+ border-top: 5px solid transparent;
+ border-right: 5px solid transparent;
+ border-bottom: 5px solid $error-background;
+ }
}
/* Accessible JQuery combobox */
@@ -313,14 +333,18 @@
}
}
#new_user fieldset {
+ width: 90%;
+
input[type="password"],
#user_password,
input[type="email"] {
- width: 395px;
+ width: 90%;
}
-
+}
+
+#new_user fieldset {
.checkbox-right {
- width: 425px;
+ width: 98%;
position: relative;
#user_remember_me, input[type='checkbox'], .checkbox-label {
@@ -328,10 +352,25 @@
}
}
}
-#new_user.user-registration {
- #user_firstname,
- #user_surname {
- width: 182px;
+#edit_user fieldset {
+ .checkbox-right {
+ width: 55%;
+ position: relative;
+
+ #user_remember_me, input[type='checkbox'], .checkbox-label {
+ float: right;
+ }
+ }
+}
+
+#new_user.register-form {
+ .inline {
+ width: 46%;
+
+ #user_firstname,
+ #user_surname {
+ width: 92%;
+ }
}
}
div#forgot-password-link {
@@ -341,4 +380,7 @@
a:hover {
color: $primary-color !important; /* Remove the important once the bootstrap_and_overrides css is gone */
}
+}
+#new_user #password-reset-form {
+ width: 50%;
}
\ No newline at end of file
diff --git a/lib/assets/stylesheets/roadmap-hacks.scss b/lib/assets/stylesheets/roadmap-hacks.scss
index da98d5a..dac2b63 100644
--- a/lib/assets/stylesheets/roadmap-hacks.scss
+++ b/lib/assets/stylesheets/roadmap-hacks.scss
@@ -50,4 +50,7 @@
vertical-align: middle;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border linear .2s, box-shadow linear .2s;
+}
+select {
+ height: 30px;
}
\ No newline at end of file