Textbox validation onfous using Angularjs - angularjs

I'm trying to build an Angular JS form. I'd like user to be able to set the focus on a text field when entering data in text field.
Thanks

If you want default autofocus to a particular text field then you can add a directive like below-
.directive('autoFocus', function($timeout) {
return {
restrict: 'A',
link: function($scope, $element) {
$timeout(function() {
$element[0].focus();
}, 0);
}
};
})
And use it with text box like -

You can use ng-focus
<input type="text" ng-focus="focus=true;blur=false;" ng-blur="blur=true;focus=false;"/>
<p>focus: {{focus}}</p>
<p>blur: {{blur}} </p>
if you want to set focus, or you can do like this
<input type="text" ng-focus="validate('somevalue')"/>
and
$scope.validate= function(text)
{
// validate here
}

Related

compare two input field values in a table using angular

I am a beginner in angularjs and I am trying to make a dynamic table but with custom validations. for instance, I have 2 input fields namely totalSalary and pension paid. The pension paid entered should not be greater than the totalSalary. I am trying to build a custom directive for the pension paid field but how to get the value of the totalSalary field to do the comparison?
Thanks to help.
Ashley
Updated:
This is the table I have made so far as per the next link. Dynamic table made so far
Below are two fields I need to compare.
<td><input type="text" class="form-control" ng-model="employee.details.salary" fcsa-number required/></td>
<td><input type="text" class="form-control" ng-model="employee.details.pension" fcsa-number not-greater-than-yearly-sal required/></td>
The directive so far I have worked on is as per below. I got the value of pension1 but now how to get the value of salary. On leaving the input for pension1, if the amount is greater than the salary, it should prompt the user and clear the value.
angular.module('app').directive("notGreaterThanYearlySal", function () {
return {
restrict: "A",
require: "?ngModel",
link: function (scope, element, attributes, ngModel) {
element.bind('blur', function(event){
alert(element.val());
});
}
};
});
One way you achieve with custom directives
for example here i match email :
<p>Email:<input type="email" name="email1" ng-model="emailReg">
Repeat Email:<input type="email" name="email2" ng-model="emailReg2" ng-match="emailReg"></p>
<span data-ng-show="myForm.emailReg2.$error.match">Emails have to match!</span>
Without using custom Directives :
<button ng-click="add()></button>
<span ng-show="IsMatch">Emails have to match!</span>
$scope.add = function() {
if ($scope.emailReg != $scope.emailReg2) {
$scope.IsMatch=true;
return false;
}
$scope.IsMatch=false;
}
I think this is a really neat way of doing this. You could set something like ng-max to the second input and set it's value as the other inputs ng-model. Then according to this you could show a error message.
<form name="numberForm">
First input:
<input type="number" name="number1" ng-model="number1">
Second input:
<input type="number" name="number2" ng-model="number2" ng-max="number1">
<span ng-show="numberForm.number2.$error.max">This field should not be larger than the other</span>
</form>
Here's a JSFiddle: https://jsfiddle.net/thepio/dpgfuy06/
No need for directive!
Make the following changes in your code:-
Use ng-repeat to iterate over your array of elements in the employee details like this:-
<div ng-repeat ="details in employee.details">
</div>
where all your elements should be put in the employee.details array
Accordingly change your ng-model to "details.pension" and "details.salary"
Make a div below your input fields and specify the condition you want in ng-show
and display an error message for the same.
For instance, in your case it would look like:-
<div ng-show="details.pension > details.salary">Pension cannot be greater than salary!
</div>
This should do the validations there and then itself.
Using custom directive:
.directive("compareTo", function () {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function (scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function (modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function () {
ngModel.$validate();
});
}
};
})

AngularJS trigger field validation after form loads

I have set of data fields.
They look like this:
// Read-Only
<div class="field-group" ng-if="feature.edit == false">
<div class="label" ng-class="{'feature-required': field.Validations.Required === true}">{{field.Label}}</div>
<div class="value">{{field.Value}}</div>
</div>
// Editor
<div class="field-group" ng-show="feature.edit == true">
<label for="F{{field.FieldID}}">
<span ng-class="{'feature-required': field.Validations.Required === true, 'feature-notrequired': field.Validations.Required === false}">{{field.Label}}</span>
<input type="text"
id="F{{field.FieldID}}"
name="F{{field.FieldID}}"
ng-change="onFieldUpdate()"
ng-model="field.Value"
jd-field-attributes attr-field="field"
jd-validate on-error="onFieldError"
field="field">
</label>
</div>
feature.edit is controlled by button and you can have data read-olny or editable. Each field has some validation, usually, if required it must be different than null.
I want to trigger that validation after I click edit and input fields show up.
One way to do it is to loop through all input fields and use jQuery trigger("change"). I have to do it with some delay (it takes Angular to populate all fields).
Is there any way to trigger ng-change or run onFieldUpdate(), after that input becomes visible?
I have tried ng-init, but it didn't work.
You could move your validation logic to custom validators in the ngModel $validators pipeline. Functions you add to this pipeline will evaluate against the input model value every time it changes and automatically add the associated valid/invalid classes to the input.
Here's an example of how you can add custom validators:
app.directive('moreValidation', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.first = function(input) {
return true; // add your custom logic here
}
ngModel.$validators.second = function(input) {
return true;
}
ngModel.$validators.third = function(input) {
return true;
}
}
};
});
// markup
<input type="text" ng-model="modelObject" more-validation />
Here's a small working plnkr example: http://plnkr.co/edit/mKKuhNqcnGXQ4sMePrym?p=preview

New line issue in Angularjs

I have a form in AngularJS. In the form I have a field named "description".
If user enters description as:
This is description:
1)point 1
2)point 2
I am saving this as :
"This is description:<br/>1)point 1 <br/> 2)point 2"
Now after saving it,to show it on page I am using something like :
<span class="summary"><em ng-bind-html="(x.DES)"></em></span>
This code is working.
If users click on the record then I am loading the form in edit mode :
the form having the line in edit mode to show the description:
<textarea ng-focus="onFocusDescrption()" maxlength="600" name="cepDes" class="form-control" rows="3" cols="16" ng-model="description" ng-disabled="isDescDisable" placeholder="Enter a description ..." id="description"></textarea>
Now the problem comes here. In controller I am setting the model value as :
$scope.description = $scope.timeEntry.DES;
Where in $scope.timeEntry.DES is having the value which is saved. The value is displayed in textarea having <br>.
It doesn't seem to be possible to use markup in a textarea as you can see in this plunkr I have created, and more information in this post. A solution would be to use a directive which allows for editable content. This way you can use a div for displaying and editing:
<div ng-bind-html="modelname"
contenteditable="true"
ng-model="modelname">
</div>
The directive (also on github):
app.directive("contenteditable", function() {
return {
restrict: "A",
require: "ngModel",
link: function(scope, element, attrs, ngModel) {
function read() {
ngModel.$setViewValue(element.html());
}
ngModel.$render = function() {
element.html(ngModel.$viewValue || "");
};
element.bind("blur keyup change", function() {
scope.$apply(read);
});
}
};
});

Display value in a field but don't save to model

Let's say I have an input, like this:
<input ng-model="myinput" />
I want it to display a default value of Hello on page load/render but not touch myinput.
I can't use a placeholder since I want the user to have the ability to edit the default value of hello. Once that default value is changed by the user, then that change should be reflected in myinput.
Anyone have any ideas?
Edit: For context, these input field default values are settings that the user saved which are being displayed on an item page. If the default value is saved to the model and the item is updated, then that default value sticks. Meaning, if they change the setting, then that item won't have the new setting value. Only if the user explicitly changed the field should it save that data to the item.
If I understand you correctly, one way of doing this is like this:
$scope.myinput= '';
$scope.tempVal = "some default value";
$scope.$watch('tempVal', function(newValue, oldValue) {
if (newValue != "some default value") {
$scope.myinput= newValue;
}
});
in the html:
<input type="text" ng-model="tempVal" />
you use a temp variable for the input and only when the value is not the default change myinput
note:
Are you sure you don't want to save the default value in the variable? I find it hard to imagine a use case in which it's not the best approach. Can you describe your use case?
Initialize myinput inside of your controller:
JavaScript
app.controller('ctrl', function($scope) {
$scope.myinput = 'hello';
});
HTML
<div ng-controller='ctrl'>
<input ng-model="myinput" />
</div>
I write a directive base on how I understand the requirement , hope it can help:
https://jsfiddle.net/tm5yv4Lk/
angular.module('myApp',[])
.controller('MainController', ['$scope', function($scope) {
$scope.myinput = 'my text';
$scope.myFakeInput = 'fake text';
}])
.directive('inputMask', ['$timeout', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
scope: {
inputMask: '='
},
link: function(scope, element, attrs, ctrl ) {
$timeout(function() {
element[0].value = scope.inputMask;
}, 0);
}
};
}]);
HTML:
<input ng-model="myinput" input-mask="myFakeInput"/>

AngularJS prevent ngModel sync

I have a simple directive called po-datepicker, it displays a datepicker on the screen, but allows the user to type a date manually:
<input type="text" ng-model="model" po-datepicker required />
and this is the directive:
myApp.directive('poDatepicker', function () {
return {
require: ['?^ngModel'],
restrict: 'A',
link: function ($scope, elem, attrs, ctrl) {
var ngModel = ctrl[0];
var picker = elem.datepicker();
picker.on('changeDate', function(e) {
ngModel.$setViewValue(e.date);
...
});
elem.parent().find('button').on('click', function() {
picker.datepicker('show');
});
var changeFn = function(e) {
// Here I have some logic that calls $setViewValue();
};
picker.on('hide', changeFn);
elem.on('keyup blur', changeFn);
}
};
});
this works as expected, but when I try to type a value in the input, it updates the ngModel, changing the variable in the scope, how can I prevent ngModel from being changed in the input?
Here is a plunkr, try manually writing a value and you'll understand what I'm talking.
Actually, after some research, I found a solution for this problem.
What I found on forums and questions is that I needed to unbind the element's events, like this:
elem.unbind('input').unbind('keydown').unbind('change');
But that solution didn't work as expected.
The problem is that I'm currently using Angular 1.2.x, I found out that you need also to set some priority to the directive, such as:
return {
require: ['?^ngModel'],
priority: 1,
...
}
The priority: 1 is needed in this case, because of the priority of some internal Angular.js directives.
Here is an updated plunker with the right priority set up.
Just add 'disabled' to the input http://plnkr.co/edit/xFeAmSCtKdNSQR1zbAsd?p=preview
<input type="text" class="form-control" ng-model="test" po-datepicker required feedback disabled/>

Resources