added validation and enter key bindings

This commit is contained in:
David Baldwynn 2016-04-28 21:57:04 -07:00
parent ada7880bac
commit ed9eb42468
14 changed files with 84 additions and 77 deletions

View file

@ -33,19 +33,19 @@ angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope'
// add previous state property // add previous state property
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) { $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
$state.previous = fromState; $state.previous = fromState;
console.log('toState: '+toState.name); //console.log('toState: '+toState.name);
//Redirect to listForms if user is authenticated //Redirect to listForms if user is authenticated
if(toState.name === 'home' || toState.name === 'signin' || toState.name === 'resendVerifyEmail' || toState.name === 'verify' || toState.name === 'signup' || toState.name === 'signup-success'){ if(toState.name === 'home' || toState.name === 'signin' || toState.name === 'resendVerifyEmail' || toState.name === 'verify' || toState.name === 'signup' || toState.name === 'signup-success'){
if(Auth.isAuthenticated()){ if(Auth.isAuthenticated()){
event.preventDefault(); // stop current execution event.preventDefault(); // stop current execution
console.log('go to forms'); //console.log('go to forms');
$state.go('listForms'); // go to listForms page $state.go('listForms'); // go to listForms page
} }
} }
//Redirect to 'signup' route if user is not authenticated //Redirect to 'signup' route if user is not authenticated
else if(toState.name !== 'access_denied' && !Auth.isAuthenticated() && toState.name !== 'submitForm'){ else if(toState.name !== 'access_denied' && !Auth.isAuthenticated() && toState.name !== 'submitForm'){
console.log('go to signup'); //console.log('go to signup');
event.preventDefault(); // stop current execution event.preventDefault(); // stop current execution
$state.go('listForms'); // go to listForms page $state.go('listForms'); // go to listForms page
} }
@ -72,7 +72,7 @@ angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope'
if( (permissions != null) ){ if( (permissions != null) ){
if( !authenticator.canAccess(permissions) ){ if( !authenticator.canAccess(permissions) ){
event.preventDefault(); event.preventDefault();
console.log('access denied'); //console.log('access denied');
$state.go('access_denied'); $state.go('access_denied');
} }
} }

View file

@ -47,7 +47,21 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
forms: '=' forms: '='
}, },
link: function(scope, element) { link: function(scope, element) {
console.log(scope.forms.myForm);
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
}else if(type === 'rating'){
scope.field.fieldValue = 0;
}else if(scope.field.fieldType === 'radio'){
console.log(scope.field);
scope.field.fieldValue = scope.field.fieldOptions[0].option_value;
console.log(scope.field.fieldValue);
}else if(type === 'legal'){
scope.field.fieldValue = 'true';
$rootScope.nextField();
}
};
scope.setActiveField = $rootScope.setActiveField; scope.setActiveField = $rootScope.setActiveField;
@ -74,7 +88,8 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
scope.field.placeholder = 'joesmith@example.com'; scope.field.placeholder = 'joesmith@example.com';
break; break;
case 'number': case 'number':
scope.field.input_type = 'number'; scope.field.input_type = 'text';
scope.field.validateRegex = /^\d+$/;
break; break;
default: default:
scope.field.input_type = 'url'; scope.field.input_type = 'url';

View file

@ -2,19 +2,18 @@
angular.module('forms').directive('onEnterKey', ['$rootScope', function($rootScope){ angular.module('forms').directive('onEnterKey', ['$rootScope', function($rootScope){
return { return {
restrict: 'A', restrict: 'A',
link: function($scope, $element, $attrs) { link: function($scope, $element, $attrs) {
$element.bind('keydown keypress', function(event) { $element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode; var keyCode = event.which || event.keyCode;
console.log($attrs.onEnterKey);
if(keyCode === 13) { if(keyCode === 13) {
$rootScope.$apply(function() { $rootScope.$apply(function() {
$rootScope.$eval($attrs.onEnterKey); $rootScope.$eval($attrs.onEnterKey);
}); });
event.preventDefault(); event.preventDefault();
} }
}); });
} }
}; };
}]); }]);

View file

@ -36,7 +36,7 @@ angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter'
}; };
$scope.setActiveField($scope.myform.visible_form_fields[0]._id, 0, false); $scope.setActiveField($scope.myform.visible_form_fields[0]._id, 0, false);
console.log($scope.selected); //console.log($scope.selected);
//Reset Timer //Reset Timer
TimeCounter.restartClock(); TimeCounter.restartClock();
}; };
@ -83,13 +83,13 @@ angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter'
*/ */
$scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) { $scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) {
if($scope.selected === null || $scope.selected._id === field_id){ if($scope.selected === null || $scope.selected._id === field_id){
console.log('not scrolling'); //console.log('not scrolling');
console.log($scope.selected); //console.log($scope.selected);
return; return;
} }
console.log('field_id: '+field_id); //console.log('field_id: '+field_id);
console.log('field_index: '+field_index); //console.log('field_index: '+field_index);
console.log($scope.selected); //console.log($scope.selected);
$scope.selected._id = field_id; $scope.selected._id = field_id;
$scope.selected.index = field_index; $scope.selected.index = field_index;
@ -106,7 +106,7 @@ angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter'
}; };
$rootScope.nextField = $scope.nextField = function(){ $rootScope.nextField = $scope.nextField = function(){
console.log('nextfield'); //console.log('nextfield');
//console.log($scope.selected.index); //console.log($scope.selected.index);
//console.log($scope.myform.form_fields.length-1); //console.log($scope.myform.form_fields.length-1);
if($scope.selected.index < $scope.myform.form_fields.length-1){ if($scope.selected.index < $scope.myform.form_fields.length-1){
@ -150,14 +150,14 @@ angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter'
setTimeout(function () { setTimeout(function () {
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form) $scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
.success(function (data, status, headers) { .success(function (data, status, headers) {
console.log('form submitted successfully'); //console.log('form submitted successfully');
$scope.myform.submitted = true; $scope.myform.submitted = true;
$scope.loading = false; $scope.loading = false;
}) })
.error(function (error) { .error(function (error) {
$scope.loading = false; $scope.loading = false;
console.log(error); //console.log(error);
$scope.error = error.message; $scope.error = error.message;
}); });
}, 500); }, 500);

View file

@ -7,7 +7,7 @@ angular.module('forms').factory('Forms', ['$resource',
formId: '@_id' formId: '@_id'
}, { }, {
'query' : { 'query' : {
method: 'GET', method: 'GET',
isArray: true, isArray: true,
//DAVID: TODO: Do we really need to get visible_form_fields for a Query? //DAVID: TODO: Do we really need to get visible_form_fields for a Query?
// transformResponse: function(data, header) { // transformResponse: function(data, header) {
@ -21,11 +21,11 @@ angular.module('forms').factory('Forms', ['$resource',
// } // }
}, },
'get' : { 'get' : {
method: 'GET', method: 'GET',
transformResponse: function(data, header) { transformResponse: function(data, header) {
var form = angular.fromJson(data); var form = angular.fromJson(data);
console.log(form); //console.log(form);
form.visible_form_fields = _.filter(form.form_fields, function(field){ form.visible_form_fields = _.filter(form.form_fields, function(field){
return (field.deletePreserved === false); return (field.deletePreserved === false);
}); });
@ -40,4 +40,4 @@ angular.module('forms').factory('Forms', ['$resource',
} }
}); });
} }
]); ]);

View file

@ -1,4 +1,6 @@
<div class="field row radio legal" ng-click="setActiveField(field._id, index, true)"> <div class="field row radio legal"
ng-click="setActiveField(field._id, index, true)"
on-enter-key="chooseDefaultOption('legal')">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"> <div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}">
<h3>{{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3> <h3>{{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3>
<br> <br>
@ -6,26 +8,30 @@
</div> </div>
<div class="col-xs-12 field-input container"> <div class="col-xs-12 field-input container">
<div class="row-fluid"> <div class="row-fluid">
<label class="btn col-xs-5"> <label class="btn col-xs-5"
ng-class="{activeBtn: field.fieldValue == 'true'}">
<input ng-focus="setActiveField(field._id, index, true)" <input ng-focus="setActiveField(field._id, index, true)"
class="focusOn" class="focusOn"
ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
type="radio" value="true" type="radio"
value="true"
ng-model="field.fieldValue" ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }" ng-model-options="{ debounce: 250 }"
ng-required="field.required" ng-required="field.required"
ng-click="$root.nextField()" ng-change="$root.nextField()"
ng-disabled="field.disabled"/> ng-disabled="field.disabled"/>
<span> I accept </span> <span> I accept </span>
</label> </label>
<label class="btn col-xs-5 col-xs-offset-1"> <label class="btn col-xs-5 col-xs-offset-1"
ng-class="{activeBtn: field.fieldValue == 'false'}">
<input ng-focus="setActiveField(field._id, index, true)" <input ng-focus="setActiveField(field._id, index, true)"
ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
type="radio" value="false" type="radio"
value="false"
ng-model="field.fieldValue" ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }" ng-model-options="{ debounce: 250 }"
ng-required="field.required" ng-required="field.required"
ng-click="$root.nextField()" ng-select="$root.nextField()"
ng-disabled="field.disabled"/> ng-disabled="field.disabled"/>
<span>I don't accept </span> <span>I don't accept </span>
</label> </label>

View file

@ -1,16 +0,0 @@
<div class="field row textfield natural" ng-click="setActiveField(field._id, index, true)">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"><h3><span class="fa fa-angle-double-right"></span> {{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3></div>
<div class="col-xs-12 field-input">
<input ng-focus="setActiveField(field._id, index, true)" ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" type="text"
class="text-field-input"
ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }"
value="field.fieldValue"
ng-required="field.required"
ng-disabled="field.disabled">
</div>
<br>
<div class="col-xs-12">
<span ng-bind="field.fieldMatchValue"></span>
</div>
</div>

View file

@ -1,6 +0,0 @@
<div class="field row" ng-click="setActiveField(field._id, index, true)">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"><h3><span class="fa fa-angle-double-right"></span> {{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3></div>
<div class="col-xs-12 field-input">
<input ng-focus="setActiveField(field._id, index, true)" ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" type="password" class="text-field-input" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" value="{{field.fieldValue}}" ng-required="field.required" ng-disabled="field.disabled">
</div>
</div>

View file

@ -1,18 +1,22 @@
<div class="field row radio" ng-click="setActiveField(field._id, index, true)" ng-if="field.fieldOptions.length > 0"> <div class="field row radio"
ng-click="setActiveField(field._id, index, true)"
ng-if="field.fieldOptions.length > 0"
on-enter-key="chooseDefaultOption()">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"><h3><span class="fa fa-angle-double-right"></span> {{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3></div> <div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"><h3><span class="fa fa-angle-double-right"></span> {{field.title}} <span class="required-error" ng-show="!field.required">optional</span></h3></div>
<div class="col-xs-12 field-input"> <div class="col-xs-12 field-input">
<div ng-repeat="option in field.fieldOptions" class="row-fluid"> <div ng-repeat="option in field.fieldOptions" class="row-fluid">
<label class="btn col-xs-4" <label class="btn col-xs-4"
style="margin: 0.5em; padding-left:30px" style="margin: 0.5em; padding-left:30px"
ng-click="$root.nextField()" ng-click="$root.nextField()"
ng-class="{activeBtn: field.fieldValue == field.fieldOptions[$index].option_id}"> ng-class="{activeBtn: field.fieldValue == field.fieldOptions[$index].option_value}">
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" <input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
type="radio" class="focusOn" type="radio" class="focusOn"
value="{{option.option_value}}" value="{{option.option_value}}"
ng-model="field.fieldValue" ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }" ng-model-options="{ debounce: 250 }"
ng-required="field.required" ng-required="field.required"
ng-disabled="field.disabled" /> ng-disabled="field.disabled"
ng-change="$root.nextField()"/>
<span ng-bind="option.option_value"></span> <span ng-bind="option.option_value"></span>
</label> </label>

View file

@ -1,4 +1,6 @@
<div class="textfield field row" ng-click="setActiveField(field._id, index, true)"> <div class="textfield field row"
ng-click="setActiveField(field._id, index, true)"
on-enter-key="chooseDefaultOption('rating')">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"> <div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}">
<h3> <h3>
<span class="fa fa-angle-double-right"></span> <span class="fa fa-angle-double-right"></span>

View file

@ -1,7 +1,8 @@
<div class="statement field row"> <div class="statement field row"
on-enter-key="$root.nextField()">
<div class="row field-title field-title"> <div class="row field-title field-title">
<div class="col-xs-1"><i class="fa fa-quote-left fa-1"></i></div> <div class="col-xs-1"><i class="fa fa-quote-left fa-1"></i></div>
<h2 class="text-left col-xs-9">{{field.title}} </h2> <h2 class="text-left col-xs-9">{{field.title}}</h2>
</div> </div>
<div class="row field-title field-input"> <div class="row field-title field-input">
<p class="col-xs-12" ng-if="field.description.length">{{field.description}} </p> <p class="col-xs-12" ng-if="field.description.length">{{field.description}} </p>

View file

@ -1,5 +1,5 @@
<div class="textfield field row" ng-click="setActiveField(field._id, index, true)"> <div class="textfield field row" ng-click="setActiveField(field._id, index, true)">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}" ng-style="{'color': design.colors.questionColor}"> <div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}">
<h3> <h3>
<span class="fa fa-angle-double-right"></span> {{field.title}} <span class="fa fa-angle-double-right"></span> {{field.title}}
<span class="required-error" ng-show="!field.required"> <span class="required-error" ng-show="!field.required">
@ -11,7 +11,8 @@
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}" <input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
ng-focus="setActiveField(field._id, index, true)" ng-focus="setActiveField(field._id, index, true)"
name="{{field.fieldType}}{{index}}" name="{{field.fieldType}}{{index}}"
type="{{field.input_type}}" type="{{field.input_type}}"
ng-pattern="field.validateRegex"
placeholder="{{field.placeholder}}" placeholder="{{field.placeholder}}"
ng-class="{ 'no-border': !!field.fieldValue }" ng-class="{ 'no-border': !!field.fieldValue }"
class="focusOn text-field-input" class="focusOn text-field-input"
@ -28,7 +29,7 @@
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span> <span class="sr-only">Error:</span>
<span ng-if="field.fieldType == 'email'"> Please enter a valid email address </span> <span ng-if="field.fieldType == 'email'"> Please enter a valid email address </span>
<span ng-if="field.fieldType == 'numbers'"> Please enter valid numbers only </span> <span ng-if="field.validateRegex"> Please enter valid numbers only </span>
<span ng-if="field.fieldType == 'link'"> Please a valid url </span> <span ng-if="field.fieldType == 'link'"> Please a valid url </span>
</div> </div>
</div> </div>

View file

@ -1,4 +1,5 @@
<div class="field row radio" ng-click="setActiveField(field._id, index, true)"> <div class="field row radio" ng-click="setActiveField(field._id, index, true)"
on-enter-key="chooseDefaultOption('yes_no')">
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}"> <div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}">
<h3 class="row"> <h3 class="row">
<span class="fa fa-angle-double-right"></span> {{field.title}} <span class="fa fa-angle-double-right"></span> {{field.title}}
@ -22,7 +23,7 @@
ng-model="field.fieldValue" ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }" ng-model-options="{ debounce: 250 }"
ng-required="field.required" ng-required="field.required"
ng-click="$root.nextField()" ng-change="$root.nextField()"
ng-disabled="field.disabled" /> ng-disabled="field.disabled" />
<div class="letter"> <div class="letter">
Y Y
@ -42,11 +43,11 @@
ng-model="field.fieldValue" ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }" ng-model-options="{ debounce: 250 }"
ng-required="field.required" ng-required="field.required"
ng-click="$root.nextField()" ng-change="$root.nextField()"
ng-disabled="field.disabled"/> ng-disabled="field.disabled"/>
<div class="letter"> <div class="letter">
N N
</div> </div>
<span>No</span> <span>No</span>
<i ng-show="field.fieldValue === 'false'" class="fa fa-check" aria-hidden="true"></i> <i ng-show="field.fieldValue === 'false'" class="fa fa-check" aria-hidden="true"></i>

View file

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('users').factory('Auth', ['$window', angular.module('users').factory('Auth', ['$window',
function($window) { function($window) {
var userState = { var userState = {
@ -18,24 +18,24 @@ angular.module('users').factory('Auth', ['$window',
// Auth <- $http <- $resource <- LoopBackResource <- User <- Auth // Auth <- $http <- $resource <- LoopBackResource <- User <- Auth
ensureHasCurrentUser: function(User) { ensureHasCurrentUser: function(User) {
if (service._currentUser && service._currentUser.username) { if (service._currentUser && service._currentUser.username) {
console.log('Using local current user.'); //console.log('Using local current user.');
console.log(service._currentUser); //console.log(service._currentUser);
return service._currentUser; return service._currentUser;
} }
else if ($window.user){ else if ($window.user){
console.log('Using cached current user.'); //console.log('Using cached current user.');
console.log($window.user); //console.log($window.user);
service._currentUser = $window.user; service._currentUser = $window.user;
return service._currentUser; return service._currentUser;
} }
else{ else{
console.log('Fetching current user from the server.'); //console.log('Fetching current user from the server.');
User.getCurrent().then(function(user) { User.getCurrent().then(function(user) {
// success // success
service._currentUser = user; service._currentUser = user;
userState.isLoggedIn = true; userState.isLoggedIn = true;
$window.user = service._currentUser; $window.user = service._currentUser;
return service._currentUser; return service._currentUser;
}, },
function(response) { function(response) {
userState.isLoggedIn = false; userState.isLoggedIn = false;
@ -67,6 +67,6 @@ angular.module('users').factory('Auth', ['$window',
}, },
}; };
return service; return service;
} }
]); ]);