Form Validation with Jhipster - javascript

My JHipster generator version is: generator-jhipster 2.27.1
I am using show-validation for my Form validation. Everything seems to be working alright except the following scenario.
Assume I have a text field which is required.
Enter one character, Field becomes valid.
Delete the text, Field becomes Invalid, error message appears and the form-group for input turns red.
Now Re-enter text. Field becomes valid and error message disappears, but the
has-error class on form-group is not yet removed. Form group still remains red.
When you proceed to enter the
second character, the has-error is now removed.
This is the relevant code from form.directive.js
$inputs.each(function() {
var $input = $(this);
scope.$watch(function() {
return $input.hasClass('ng-invalid') && $input.hasClass('ng-dirty');
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
}
The form-validation directive is not updating immediately but is behind by one input change. I am not able to figure out which part of the code needs modifying.
Added console logs, but to no avail. I assume it has got something to do with text value vis-a-vis model value, but don't know how to fix it.

How about this?
(added: attrs, formCtrl attr to link function and changed $watch.function - uncomment dirty check if needed)
link: function (scope, element, attrs, formCtrl) {
element.find('.form-group').each(function() {
var $formGroup = $(this);
var $inputs = $formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if ($inputs.length > 0) {
$inputs.each(function() {
var $input = $(this);
scope.$watch(function() {
//inputs need to have 'name' attribute for this to work
return formCtrl[$input[0].name].$invalid;
//&& formCtrl[$input[0].name].$dirty;
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
});
}
});
}

Related

autoscroll to first blank required field using angular js

I have created a form using angular js with around 7 input elements. When I click on submit, I want the form to get scrolled up to the first blank field which is required. But now it is not correctly pointing to the field left blank. Any solution to resolve this ?
Check the error here.
before submitting the form, you can check whether the form is valid or not and use .focus() to focus on that element.
$scope.onSubmit = function(yourForm) {
if (!yourForm.$valid) {
angular.element("[name='" + yourForm.$name + "']").find('.ng-invalid:visible:first').focus();
return false;
}
};
method #2 - You can also use $anchorScroll service
see the documentation here
$scope.onSubmit = function(yourForm) {
if (!yourForm.$valid) {
var id = angular.element("[name='" + yourForm.$name + "']").find('.ng-invalid:visible:first').data('id');
$location.hash(id);
$anchorScroll();
return false;
}
};

Why is my angular directive causing incomplete values to be deleted upon tabbing to another field?

On a project I'm working on, I have a U.S. phone directive that is giving me some trouble. The short of it is, if you enter an incomplete value and tab to another field, the value is lost.
I've created a plunker of the problem in motion, and the offending directive is below:
angular.module('app').directive('someInput', [
'$filter', someInputDir
]);
function someInputDir($filter) {
return {
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
// Build mask.
var mask = '(999) 999-9999';
if (attrs.useExtension)
mask += attrs.useExtension.toLowerCase() === 'true' ? '? x99999' : '';
$(element).mask(mask);
var nonDigitCharacters = /[^0-9]/g;
// HACK: It turns out that angular and the jQuery Masked Input plugin
// don't play nicely together. In order for the masked input to work properly,
// we have to bind an event handler for key down events (since Masked Input
// blocks key down events) and force a change event to get the parsers to work
// properly.
element.on('keydown', function (evt) {
scope.$evalAsync(element.triggerHandler.bind(element, 'change', evt));
});
ctrl.$validators.minLength = function (modelValue) {
var minLength = 0;
if (attrs.minlength)
minLength = parseInt(attrs.minlength);
var stringValue = $filter('tel')(modelValue, false),
longEnough = stringValue.length >= minLength;
// If value not required, and nothing is entered, the value is valid.
if (!attrs.required && stringValue.length === 0)
return true;
// If value is required, and nothing is entered, this value is 'valid'.
// The point of this code is to not interfere with a required attribute!
if (attrs.required && stringValue.length === 0)
return true;
return longEnough;
};
ctrl.$parsers.unshift(function(viewValue) {
var digitsOnly = viewValue.replace(nonDigitCharacters, '');
return digitsOnly;
});
ctrl.$formatters.push(function (value) {
return $filter('tel')(value, false);
});
}
};
}
At first, I thought it was the custom $validator that I created to simulate a minlength validation (this implementation causes a regular minlength to not work properly due to the mask.) However, in my plunker, you will see that I made a version without the $validator that has the exact same problem.
Question: I don't understand what about this directive is causing an incomplete value to be deleted on blur. Also, in what way can I prevent the invalid value from being deleted, but allowing the field to still be tagged as invalid?
Looks like you have an issue with JQuery maskedinput plugin.
Try change $(element).mask(mask); to $(element).mask(mask, {autoclear:false});
Here is plunker with changes http://plnkr.co/edit/b1knRUgREox2Su8xdVIN

jQuery validate not working for two fields

I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show. Using jQuery validate, I can check that the domain is correct, but its not validating the placeholder field. The playerClass rule is not being applied:
$(function() {
$("#form").validate({
rules: {
playerClass: {
required: true
}
},
submitHandler: function() {
$("body").append("<p>Validation Complete!</p>");
}
});
});
jQuery.validator.addMethod("domainChk", function(value, element, params) {
$(".submit").show();
if (this.optional(element)) return true;
var regExp = new RegExp("^(?!www\\.|http:\/\/www\.)(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$");
return regExp.test(value);
},
function errmess(params, element) {
$(".submit").hide();
return "Valid hostname required for player code";
});
jQuery.validator.addClassRules({
domainChk: {
domainChk: true
}
});
jsFiddle: Link
The playerClass rule is not being applied
Your second field, with name="playerClass" is not being validated because you've applied no validation rules to it. There is no such rule called playerClass in your jsFiddle or in your OP, and you've applied no rules to the playerClass field in your jsFiddle.
Even if playerClass was a custom rule, the form is considered valid because the playerClass field is optional in your jsFiddle. Without the required rule, when the field is left blank, it's valid.
You've also failed to close your <form> element in the jsFiddle. There is no </form> tag.
EDIT:
As per documentation, any ajax() should go inside the submitHandler function within the .validate() method.
In other words, you are breaking the validation plugin with your click handler.
I need to validate that both the domain field is correct and that the placeholder field has a value. Once both are true, the Submit button will show.
Then why are you showing the submit button from within the domainChk rule? Once this rule is passed, you're showing the button with $(".submit").show().
You would typically use the .valid() method to test the form and show/hide the button.
$('input[type="text"]').on('click keyup blur', function() {
if ($('#form').valid()) {
$(".submit").show();
} else {
$(".submit").hide();
}
});
This is much closer to how it should be: http://jsfiddle.net/e04rca0t/2/

Return to text box after click

I have a text box and an options list where options can be added to the current text that is in that box. The problem I'm having is that when I click on an option, and that option is added to the text, I want the cursor to be put back into the text box so the user can continue typing. Any help is much appreciated.
Text field:
input type='text' ng-model='comment.text' ng-change='userList(comment.text)'
JS:
$scope.addUserToComment = function(user) {
$scope.comment.text += user + " ";
$scope.usersShow = false;
};
Avoid modifying the DOM in the controllers.
edit: but to answer your question, ng-focus was me being lazy.
I would create a directive
angular.module('focus-me', []).
.directive('focusMe', function(){
return {
scope: { watch_this: '=' },
link: function(scope, element, attrs){
scope.$watch('watch_this', function(){
$(element).focus();
}
}
}
});
this gives you two options
input type='text' focus-me='comment.text' ng-model='comment.text' ng-change='userList(comment.text)'
or
input type='text' focus-me='some_obj_attr_you_toggle' ng-model='comment.text' ng-change='userList(comment.text)'
1st will call the watcher function more times than necessary, when you are typing as well (not really a big deal).
2nd will only call the watcher function when you toggle the attr in your addUserTo function.
A simpler way (although you are modifying the dom in the controller) would be:
$scope.addUserToComment = function(user, $event) {
$($event.target).find('css selector to navigate to textbox').focus();
$scope.comment.text += user + " ";
$scope.usersShow = false;
};
in your ng-click add another parameter
ng-click='addUserToComment(user, $event)'
PS. Code might not be 100% correct but you get the idea.
$('a').on('click', '#options', function(){
$('input').focus();
});

How to validate a memorized value in an input box

I have the following code:
$(":input").bind("keyup change", function(e) {
var comboVal = $('.emailrequerido1').val()+$('.emailrequerido2').val()+$('.emailrequerido3').val()+$('.emailrequerido4').val()+$('.emailrequerido5').val();
if(comboVal == 'nullnull' || comboVal == ""){
$("#enviarForm").attr('disabled', true);
}else{
$("#enviarForm").removeAttr('disabled');
}
});
What I am trying to accomplish is that when you select a memorized value from the input box by double clicking in the box a history of inputs shows (these values are saved by the browser (I believe)) and if you choose one of these and the field has that text you selected the button should enable.
Here is a JSFiddle example: JSFiddle example
In the example I added a value to the first field since these dont memorize as I expalined before to show a demonstration of what I mean.
I have cleaned up the code a bit: http://jsfiddle.net/kam5B/1/
I've swapped the classes and ids so that the ids are unique, and the classes are common.
Here is a checkEmails function that runs the validation and enables/disables the checkbox.
checkEmails is run every time an input changes, and when the page loads the first time:
$(document).ready(function () {
function checkEmails() {
var nonempty = $('form .email_contactopadrino').filter(function() {
return $(this).val() != '';
});
if (nonempty.length) {
$('#enviarForm').removeAttr('disabled');
}
else {
$('#enviarForm').attr('disabled', true);
}
};
$('form').on('keyup change', '.email_contactopadrino', checkEmails);
checkEmails();
});

Categories

Resources