Skip to content
Snippets Groups Projects
Commit 7d18cbf3 authored by Ere Maijala's avatar Ere Maijala Committed by Demian Katz
Browse files

Client-side validation for bootstrap3.

parent 08a6fc77
No related merge requests found
...@@ -154,6 +154,9 @@ class MyResearchController extends AbstractBase ...@@ -154,6 +154,9 @@ class MyResearchController extends AbstractBase
// Make view // Make view
$view = $this->createViewModel(); $view = $this->createViewModel();
// Password policy
$view->passwordPolicy = $this->getAuthManager()
->getPasswordPolicy($method);
// Set up reCaptcha // Set up reCaptcha
$view->useRecaptcha = $this->recaptcha()->active('newAccount'); $view->useRecaptcha = $this->recaptcha()->active('newAccount');
// Pass request to view so we can repopulate user parameters in form: // Pass request to view so we can repopulate user parameters in form:
...@@ -1266,8 +1269,10 @@ class MyResearchController extends AbstractBase ...@@ -1266,8 +1269,10 @@ class MyResearchController extends AbstractBase
$userFromHash = isset($post->hash) $userFromHash = isset($post->hash)
? $this->getTable('User')->getByVerifyHash($post->hash) ? $this->getTable('User')->getByVerifyHash($post->hash)
: false; : false;
// View and reCaptcha // View, password policy and reCaptcha
$view = $this->createViewModel($post); $view = $this->createViewModel($post);
$view->passwordPolicy = $this->getAuthManager()
->getPasswordPolicy();
$view->useRecaptcha = $this->recaptcha()->active('changePassword'); $view->useRecaptcha = $this->recaptcha()->active('changePassword');
// Check reCaptcha // Check reCaptcha
if (!$this->formWasSubmitted('submit', $view->useRecaptcha)) { if (!$this->formWasSubmitted('submit', $view->useRecaptcha)) {
...@@ -1346,6 +1351,9 @@ class MyResearchController extends AbstractBase ...@@ -1346,6 +1351,9 @@ class MyResearchController extends AbstractBase
// Display username // Display username
$user = $this->getUser(); $user = $this->getUser();
$view->username = $user->username; $view->username = $user->username;
// Password policy
$view->passwordPolicy = $this->getAuthManager()
->getPasswordPolicy();
// Identification // Identification
$user->updateHash(); $user->updateHash();
$view->hash = $user->verify_hash; $view->hash = $user->verify_hash;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -330,6 +330,7 @@ var Lightbox = { ...@@ -330,6 +330,7 @@ var Lightbox = {
*/ */
registerForms: function() { registerForms: function() {
var form = $("#modal").find('form'); var form = $("#modal").find('form');
form.validator();
var name = $(form).attr('name'); var name = $(form).attr('name');
// Assign form handler based on name // Assign form handler based on name
if(typeof name !== "undefined" && typeof Lightbox.formHandlers[name] !== "undefined") { if(typeof name !== "undefined" && typeof Lightbox.formHandlers[name] !== "undefined") {
......
/*!
* Validator v0.5.0 for Bootstrap 3, by @1000hz
* Copyright 2014 Spiceworks, Inc.
* Licensed under http://opensource.org/licenses/MIT
*
* https://github.com/1000hz/bootstrap-validator
*/
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),f=d.data("bs.validator");f||d.data("bs.validator",f=new c(this,e)),"string"==typeof b&&f[b]()})}var c=function(b,c){this.$element=a(b),this.options=c,this.$element.attr("novalidate",!0),this.toggleSubmit(),this.$element.on("input.bs.validator change.bs.validator focusout.bs.validator",a.proxy(this.validateInput,this)),this.$element.on("submit.bs.validator",a.proxy(this.onSubmit,this)),this.$element.find("[data-match]").each(function(){var b=a(this),c=b.data("match");a(c).on("input.bs.validator",function(){b.val()&&b.trigger("input")})})};c.DEFAULTS={delay:500,html:!1,errors:{match:"Does not match",minlength:"Not long enough"}},c.VALIDATORS={"native":function(a){var b=a[0];return b.checkValidity?b.checkValidity():!0},match:function(b){var c=b.data("match");return!b.val()||b.val()===a(c).val()},minlength:function(a){var b=a.data("minlength");return!a.val()||a.val().length>=b}},c.prototype.validateInput=function(b){var c=a(b.target),d=c.data("bs.validator.errors");if(c.is('[type="radio"]')&&(c=this.$element.find('input[name="'+c.attr("name")+'"]')),this.$element.trigger(b=a.Event("validate.bs.validator",{relatedTarget:c[0]})),!b.isDefaultPrevented()){var e=this;this.runValidators(c).done(function(f){c.data("bs.validator.errors",f),f.length?e.showErrors(c):e.clearErrors(c),d&&f.toString()===d.toString()||(b=f.length?a.Event("invalid.bs.validator",{relatedTarget:c[0],detail:f}):a.Event("valid.bs.validator",{relatedTarget:c[0],detail:d}),e.$element.trigger(b)),e.toggleSubmit(),e.$element.trigger(a.Event("validated.bs.validator",{relatedTarget:c[0]}))})}},c.prototype.runValidators=function(b){function d(a){return b.data(a+"-error")||b.data("error")||"native"==a&&b[0].validationMessage||g.errors[a]}var e=[],f=([c.VALIDATORS.native],a.Deferred()),g=this.options;return b.data("bs.validator.deferred")&&b.data("bs.validator.deferred").reject(),b.data("bs.validator.deferred",f),a.each(c.VALIDATORS,a.proxy(function(a,c){if((b.data(a)||"native"==a)&&!c.call(this,b)){var f=d(a);!~e.indexOf(f)&&e.push(f)}},this)),!e.length&&b.val()&&b.data("remote")?this.defer(b,function(){a.get(b.data("remote"),[b.attr("name"),b.val()].join("=")).fail(function(a,b,c){e.push(d("remote")||c)}).always(function(){f.resolve(e)})}):f.resolve(e),f.promise()},c.prototype.validate=function(){var a=this.options.delay;return this.options.delay=0,this.$element.find(":input").trigger("input"),this.options.delay=a,this},c.prototype.showErrors=function(b){var c=this.options.html?"html":"text";this.defer(b,function(){var d=b.closest(".form-group"),e=d.find(".help-block.with-errors"),f=b.data("bs.validator.errors");f.length&&(f=a("<ul/>").addClass("list-unstyled").append(a.map(f,function(b){return a("<li/>")[c](b)})),void 0===e.data("bs.validator.originalContent")&&e.data("bs.validator.originalContent",e.html()),e.empty().append(f),d.addClass("has-error"))})},c.prototype.clearErrors=function(a){var b=a.closest(".form-group"),c=b.find(".help-block.with-errors");c.html(c.data("bs.validator.originalContent")),b.removeClass("has-error")},c.prototype.hasErrors=function(){function b(){return!!(a(this).data("bs.validator.errors")||[]).length}return!!this.$element.find(":input:enabled").filter(b).length},c.prototype.isIncomplete=function(){function b(){return"checkbox"===this.type?!this.checked:"radio"===this.type?!a('[name="'+this.name+'"]:checked').length:""===a.trim(this.value)}return!!this.$element.find(":input[required]:enabled").filter(b).length},c.prototype.onSubmit=function(a){this.validate(),(this.isIncomplete()||this.hasErrors())&&a.preventDefault()},c.prototype.toggleSubmit=function(){var a=this.$element.find('input[type="submit"], button[type="submit"]');a.toggleClass("disabled",this.isIncomplete()||this.hasErrors()).css({"pointer-events":"all",cursor:"pointer"})},c.prototype.defer=function(a,b){window.clearTimeout(a.data("bs.validator.timeout")),a.data("bs.validator.timeout",window.setTimeout(b,this.options.delay))};var d=a.fn.validator;a.fn.validator=b,a.fn.validator.Constructor=c,a.fn.validator.noConflict=function(){return a.fn.validator=d,this},a(window).on("load",function(){a('form[data-toggle="validator"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery);
\ No newline at end of file
...@@ -9,6 +9,16 @@ ...@@ -9,6 +9,16 @@
} }
} }
.group [class^=col-] {padding-left:0} .group [class^=col-] {padding-left:0}
.has-error {margin-bottom:0;}
.help-block.with-errors {
padding:@padding-base-vertical 0;
&:empty {
padding:0;
}
&,.list-unstyled {
margin:0;
}
}
.highlight{&:extend(mark);} .highlight{&:extend(mark);}
.icon-bar {background-color:#888} .icon-bar {background-color:#888}
img {max-width:100%} img {max-width:100%}
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
<label class="col-sm-3 control-label" for="account_email"><?=$this->transEsc('Email Address')?>:</label> <label class="col-sm-3 control-label" for="account_email"><?=$this->transEsc('Email Address')?>:</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="account_email" type="email" name="email" value="<?=$this->escapeHtmlAttr($this->request->get('email'))?>" class="form-control"/> <input id="account_email" type="email" name="email" value="<?=$this->escapeHtmlAttr($this->request->get('email'))?>" class="form-control"/>
<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
...@@ -25,12 +26,14 @@ ...@@ -25,12 +26,14 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label" for="account_password"><?=$this->transEsc('Password')?>:</label> <label class="col-sm-3 control-label" for="account_password"><?=$this->transEsc('Password')?>:</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="account_password" type="password" name="password" class="form-control"/> <input id="account_password" type="password" name="password" class="form-control" required aria-required="true"<?=isset($this->passwordPolicy['minLength']) ? ' data-minlength="' . $this->passwordPolicy['minLength'] . '" data-minlength-error="' . $this->escapeHtmlAttr($this->translate('password_minimum_length', array('%%minlength%%' => $this->passwordPolicy['minLength']))) . '"' : ''?><?=isset($this->passwordPolicy['maxLength']) ? ' maxlength="' . $this->passwordPolicy['maxLength'] . '"' : ''?>/>
<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label" for="account_password2"><?=$this->transEsc('Password Again')?>:</label> <label class="col-sm-3 control-label" for="account_password2"><?=$this->transEsc('Password Again')?>:</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input id="account_password2" type="password" name="password2" class="form-control"/> <input id="account_password2" type="password" name="password2" class="form-control" required aria-required="true" data-match="#account_password" data-match-error="<?=$this->escapeHtmlAttr($this->translate('Passwords do not match'))?>"/>
<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -17,12 +17,14 @@ ...@@ -17,12 +17,14 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label"><?=$this->transEsc('new_password') ?>:</label> <label class="col-sm-3 control-label"><?=$this->transEsc('new_password') ?>:</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="password" name="password" class="form-control"/> <input type="password" id="password" name="password" class="form-control" required aria-required="true"<?=isset($this->passwordPolicy['minLength']) ? ' data-minlength="' . $this->passwordPolicy['minLength'] . '" data-minlength-error="' . $this->escapeHtmlAttr($this->translate('password_minimum_length', array('%%minlength%%' => $this->passwordPolicy['minLength']))) . '"' : ''?><?=isset($this->passwordPolicy['maxLength']) ? ' maxlength="' . $this->passwordPolicy['maxLength'] . '"' : ''?>/>
<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label"><?=$this->transEsc('confirm_new_password') ?>:</label> <label class="col-sm-3 control-label"><?=$this->transEsc('confirm_new_password') ?>:</label>
<div class="col-sm-9"> <div class="col-sm-9">
<input type="password" name="password2" class="form-control"/> <input type="password" name="password2" class="form-control" required aria-required="true" data-match="#password" data-match-error="<?=$this->escapeHtmlAttr($this->translate('Passwords do not match'))?>"/>
<div class="help-block with-errors"></div>
</div> </div>
</div> </div>
\ No newline at end of file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<h2><?=$this->transEsc('User Account')?></h2> <h2><?=$this->transEsc('User Account')?></h2>
<?=$this->flashmessages()?> <?=$this->flashmessages()?>
<form method="post" action="" name="accountForm" id="accountForm" class="form-horizontal"> <form method="post" action="" name="accountForm" id="accountForm" class="form-horizontal" data-toggle="validator" role="form">
<?=$this->auth()->getCreateFields()?> <?=$this->auth()->getCreateFields()?>
<?=$this->recaptcha()->html($this->useRecaptcha) ?> <?=$this->recaptcha()->html($this->useRecaptcha) ?>
<div class="form-group"> <div class="form-group">
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<? elseif (!isset($this->hash)): ?> <? elseif (!isset($this->hash)): ?>
<div class="error"><?=$this->transEsc('recovery_user_not_found') ?></div> <div class="error"><?=$this->transEsc('recovery_user_not_found') ?></div>
<? else: ?> <? else: ?>
<form class="form-horizontal" action="<?=$this->url('myresearch-newpassword') ?>" method="post"> <form id="newpassword" class="form-horizontal" action="<?=$this->url('myresearch-newpassword') ?>" method="post" data-toggle="validator" role="form">
<input type="hidden" value="<?=$this->escapeHtmlAttr($this->hash) ?>" name="hash"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->hash) ?>" name="hash"/>
<input type="hidden" value="<?=$this->escapeHtmlAttr($this->username) ?>" name="username"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->username) ?>" name="username"/>
<input type="hidden" value="<?=$this->escapeHtmlAttr($this->auth_method) ?>" name="auth_method"/> <input type="hidden" value="<?=$this->escapeHtmlAttr($this->auth_method) ?>" name="auth_method"/>
......
...@@ -16,6 +16,7 @@ return array( ...@@ -16,6 +16,7 @@ return array(
'vendor/bootstrap-accessibility.min.js', 'vendor/bootstrap-accessibility.min.js',
//'vendor/bootlint.min.js', //'vendor/bootlint.min.js',
'vendor/typeahead.js', 'vendor/typeahead.js',
'vendor/validator.min.js',
'vendor/rc4.js', 'vendor/rc4.js',
'common.js', 'common.js',
'lightbox.js', 'lightbox.js',
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment