Detect if user changed inputbox in input form with angular? - angularjs

I want to be able to detect when a field is changed. My form fields are generated using ng-repeat.
Assume formfields is as follows: {"FIELD1":"", "FIELD2":"", "FIELD3":"Prepopulated", "FIELD4":""}
<div ng-controller="MyController">
<form name="myform">
<div ng-repeat="(key, keyvalue) in formfields">
<input name="{{key}}" ng-model="formfields[key]">
</div>
</form>
</div>
My problem is, when I try to log with "console.log($scope.myForm.FIELD1)" inside of my checkPristine() function, pristine is always set to true and never changes to false. How can I check to see if fields have changed? Open to alternatives to pristine if it does not work.

You could add an ng-blur directive to the input like this:
https://jsfiddle.net/54r4991j/
Angular
vm.formfields = {"FIELD1":"", "FIELD2":"", "FIELD3":"Prepopulated", "FIELD4":""};
vm.watchFormField = function(fieldKey) {
alert(fieldKey + 'changed to ' + vm.formfields[fieldKey]);
}
HTML
<form name="myform">
<div ng-repeat="(key, keyvalue) in ctrl.formfields">
<input name="{{key}}" ng-model="ctrl.formfields[key]" ng-blur="ctrl.watchFormField(key)">
</div>
</form>

Related

How to validate AngularJS form input while is using ng-repeat

I have a form which has input fields that is dynamically built using ng-repeat. How I can validate these fields are greater than another input field. Please look at this sample code.
<html ng-app>
<head>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body ng-init="weekDays = ['monday', 'tuesday', 'wednesday','thursday', 'friday', 'saturday','sunday']">
<h1>Fun with Fields and ngModel</h1>
<p>days: {{weekDays}}</p>
<h3>Binding to each element directly:</h3>
<div ng-repeat="weekday in weekDays">
Value: {{weekday}}
{{day='day_'+weekday; ""}}
<input name="{{day}}" ng-model="val">
</div>
<div>
Number to validate : <input name="numToValidate">
</div>
</body>
I am very new to angularJS and still learning. However I couldn't able to think through this simple validation. Please help.
Html:
<form name="form">
<div ng-repeat="weekday in weekDays">
Value: {{weekday}}
{{day='day_'+weekday; ""}}
<input name="{{day}}" ng-model="val" required>
</div>
<div>
Number to validate : <input name="numToValidate" required>
</div>
</form>
Script:
if($scope.form.$valid){
// You can write your code here what you want to do after validate.
}
You can use html form element with min attribute to check validity
<input name="{{day}}" ng-model="weekday.val" min="{{numToValidate}}">
you will need seperate model for each of your inputs in your ng-repeat therefore I changed your ng-model with the following
ng-model="weekday.val"
if you do not want to use form you can check the validity of your value with ng-blur directive (triggered when input loses focus).
html
<input name="{{day}}" ng-model="weekday.val" ng-blur="checkValid(weekday.val)">
js
$scope.checkValid = function(value){
if(value > $scope.numToValidate){
alert("please enter a valid number");
}
}

How to catch errors or validate angular material datepicker in the controller?

In angular material datepicker, Error messages are shown using ng-Messages but how do I catch those in the controller and validate if no error is there.
<form name="myForm">
<md-datepicker name="dateField" ng-model="myDate" md-placeholder="Enter date"
required md-min-date="minDate" md-max-date="maxDate" md-open-on-focus></md-datepicker>
<div class="validation-messages" ng-messages="myForm.dateField.$error">
<div ng-message="required">This date is required!</div>
<div ng-message="mindate">Date is too early!</div>
<div ng-message="maxdate">Date is too late!</div>
<div ng-message="valid">The entered value is not a date!</div>
</div>
{{myForm.dateField.$error}}
</form>
<button ng-click="check(myForm.dateField.$error)">Click</button>
I want to validate errors on click of button in the controller
$scope.check=function(errors){
};
Angularjs creates a scope variable for form whenever it is used to check the validation of that form. Now you can directly use form.$valid , formName.$invalid and many more pre-defined properties in html directly. But if you want to use it in the controller just pass it to the controller using md-button (while submitting the form).
<form name="myForm">
<md-datepicker name="dateField" ng-model="myDate" md-placeholder="Enter date" required="" md-min-date="minDate" md-max-date="maxDate" md-date-filter="onlyWeekendsPredicate"></md-datepicker>
<div class="validation-messages" ng-messages="myForm.dateField.$error">
<div ng-message="valid">The entered value is not a date!</div>
<div ng-message="required">This date is required!</div>
<div ng-message="mindate">Date is too early!</div>
<div ng-message="maxdate">Date is too late!</div>
<div ng-message="filtered">Only weekends are allowed!</div>
</div>
<md-button ng-click="check(myForm)">check/md-button>
</form>
Here is a working example. You can the whole object in console which is printed by controller as desired. http://codepen.io/next1/pen/rLebeK
You already got that right but missing the validation. The correct way is to check the property $scope.myForm.$valid, that will be true when the form is valid and false otherwise. Check the Developer Guide.
Other way is to check for the empty object (so no errors) but it checks for that input only:
in the HTML:
<button ng-click="check(myForm.myName.$error)">Click</button>
in the controller:
$scope.check = function (val){
// check if is empty
var ok = !!(Object.keys(val).length === 0 && val.constructor === Object);
}
I don't recommend this approach unless you want to do it yourself or deal with specific errors.
See this Plunker with both ways

Get pristine value in Angular controller

I need to be able to see in the Angular controller if the datepicker is pristine or not. Tried all sorts of things including sending the pristine value in a method but cannot get this value. Below is the view code:
<form name="myForm">
<!-- Datepicker From -->
<div class="small-6 medium-5 large-2 columns" ng-if="vm.subViewActive">
<div class="input-group">
<input name="valuationDatePickerFrom" ng-model="name" type="text" class="datepicker" id="valuationDatePickerFrom" placeholder="DD/MM/YYYY" pikaday="vm.datePickerFrom" on-select="vm.selectStartDate(pikaday)" year-range="{{ vm.yearRange }}" >
<div class="input-group-addon">
<label for="valuationDatePickerFrom" class="postfix">
<i class="fa fa-calendar"></i> From
</label>
</div>
</div>
</div>
</form>
and then I also tried :
var isPristine = $scope.myForm.valuationDatePickerFrom.$pristine;
console.log(isPristine);
in my controller but cannot get the pristine value. Read lots of posts here but mainly to do with CSS classes and front-end control or setting the pristine state from the backend not getting or checking the pristine state.
Thanks anybody that can help.
You are using:
var isPristine = $scope.myForm.valuationDatePickerFrom.$pristine;
but your form's name is not myForm.
Change <input name="name"... <input name="valuationDatePickerFrom"...
Then you can use:
var isPristine = $scope.userForm.valuationDatePickerFrom.$pristine;
Also, the controller is getting called before the view is created, so no myForm exists at the time the controller runs. Try adding a $timeout like so:
$timeout(function() {
var isPristine = $scope.userForm.valuationDatePickerFrom.$pristine;
console.log(isPristine);
}, 100);
plunkr
The above solution only works on page load, but you need to know this value when the page is being used. Instead pass the value to the controller when an action happens:
<form name="myForm">
<input type="text" name="valuationDatePickerFrom" ng-model="valuationDatePicker" ng-blur="alerty(myForm.$pristine)">
</form>
.controller('MainController', function($scope) {
$scope.alerty = function(isPristine){
alert('isPristine: ' + isPristine);
};
https://plnkr.co/edit/f0EWvYmoXCn8UOH3QCfE?p=preview

Angular ng-model is being set to undefined on edit

I'm creating a modal dialog and trying to read the fields back when the dialog is closed, but when the input is edited, the ng-model for the input field is being set to undefined. With the Plunk, if you click the dialog button and then press Ok without modifying the text field, it will display "blah". But if you modify the text input at all, then nothing will be displayed.
The dialog template is:
<script type="text/ng-template" id="simpleModal.html">
<div class="modal-header">
<h3 class="modal-title">Simple Modal</h3>
</div>
<div class="modal-body">
<div class="form-group">
<label for="emailInput">Email</label>
<input id="emailInput" type="email" class="form-control" ng-model="user.email">
</div>
</div>
<div class="modal-footer">
<button class="btn" type="button" ng-click="ok()">Ok</button>
</div>
</script>
And the controller for the modal dialog:
app.controller('SimpleModalController', function($scope, $uibModalInstance, $log) {
$scope.user = {
email: "blah"
};
$scope.ok = function() {
$log.debug('simpleModal ok called ' + $scope.user.email);
$uibModalInstance.close($scope.user.email);
};
});
I've seen reference to https://stackoverflow.com/a/22768720/552936, but I've changed my code to reflect this and it hasn't fixed the issue.
You have declared input type="email" in your input field in modal
<input id="emailInput" type="email" class="form-control" ng-model="user.email">
It'll pass value if data according to email . like a#b.com
You can check if data has valid email
HTML
<form name="myForm">
<input type="email" name="myEmail" model="myEmail" />
<span>Valid Email {{myForm.myInput.$valid}}
</form>
PLUNKR
If you wanna pass any string then you have to make it type="text".
The reason it's being set to undefined is because you have the input for the email address as type=email. If you put anything but a valid email address in that field user.email will be set to undefined.
I just ran your plunker and put in a valid email address and can see it's has been set correctly. This is an instance where you should be validating that it's a well formed email address before allowing submission.

Angular is not setting the text from input to the model I assigned

I have a JSON object with some keys and values. I want the user to be able to define what the values should be, so I generate some input boxes from the JSON object, using ng-repeat.
<div ng-repeat="(key, value) in argsJson">
<label>{{key}}</label><input type="text" ng-model="val"/>
</div>
However, when I type in the input, it's not added to the model, as evidenced by an alert function I activate when I'm done typing.
$scope.makeAlert = function(){
alert(JSON.stringify($scope.argsJson));
}
Here's the JSFiddle: http://jsfiddle.net/6nx87fzo/1/
Change the ng-model from val to argsJson[key]. See JSFiddle or code below. Also you had a typo (val and value) which dcodesmith pointed out in the comments.
<div ng-app="App" ng-controller="ctrl">
<div ng-repeat="(key, val) in argsJson">
<label>{{key}}</label><input type="text" ng-model="argsJson[key]"/>
</div>
<button ng-click="makeAlert()">Alert</button>
</div>

Resources