Get pristine value in Angular controller - angularjs

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

Related

js form submit is not working

I am trying to submit a form, but the values are always empty.
my HTML:
<form novalidate name="creditCardForm" id="creditCardForm" method="POST">
<input type="hidden" name="EPS_MERCHANT" value="{{credit.data.merchantId}}">
<input type="hidden" name="EPS_TIMESTAMP" value="{{credit.data.currentGMTTimestamp}}">
<input type="hidden" name="EPS_TYPE" value="{{credit.data.epsType}}">
<div class="text-center">
<button class="btn btn-primary" ng-click="credit.save()">Save</button>
</div>
</form>
and my js part:
function save(){
document.getElementById("creditCardForm").setAttribute("action", this.data.crnUrl)
document.forms["creditCardForm"].submit()
}
and from inspection, these fields all have values
but from the request, these fields are all empty:
update my question:
because this is a special form post that it will call NAB bank api to verify something, so I cannot put each fields into an object and do a ajax/$resource/$http call.
thanks
That's a not angular way to submit the form via action attribute. Use ng-submit form attribute and make a $http.post request async.
<form novalidate name="creditCardForm" id="creditCardForm"
ng-submit="saveCredit(creditCardForm)">
<!-- no input hidden -->
<div class="text-center">
<button class="btn btn-primary">Save</button>
</div>
</form>
And you dont need hidden inputs in this way.
If I get your question and your requirement correct. You should be using following way:
<form novalidate name="creditCardForm" id="creditCardForm" method="POST">
<input type="hidden" name="EPS_MERCHANT" ng-model="credit.data.merchantId">
<input type="hidden" name="EPS_TIMESTAMP" ng-model="credit.data.currentGMTTimestamp">
<input type="hidden" name="EPS_TYPE" ng-model="credit.data.epsType">
<div class="text-center">
<button class="btn btn-primary" ng-click="credit.save(credit.data)">Save</button>
</div>
</form>
This is assuming that credit is the alias for your controller.
I have tried to keep your ways of ng-click to call a method on controller. However with forms in angular, you can do the same via ng-submit directive also.
In your controller you will have something like:
$scope.save = function(data){
//use data here as you like
//data.merchantId and other fields
}
If you are using alias form, then use:
//vm or any other name you have for your `this` instance
vm.save = function(){
// use data here as you like
}
I want to try to fix your problem. The first thing that you have to do is add ng-model and ng-value in your form. For example:
view:
<form novalidate name="creditCardForm" id="creditCardForm" ng-submit="save()">
<input type="hidden" ng-model="credit_card.eps_merchant" name="eps_timestamp" ng-value="{{credit.data.merchantId}}">
<input type="hidden" ng-model="credit_card.eps_timestamp" name="eps_timestamp" ng-value="{{credit.data.currentGMTTimestamp}}">
<input type="hidden" ng-model="credit_card.eps_type" name="eps_type" ng-value="{{credit.data.epsType}}">
<div class="text-center">
<button type="submit" class="btn btn-primary">Save</button>
</div>
</form>
For the next you can create controller. For example:
angular controller:
angular.module('cartApp')
.controller('AddCreditCartCtrl', [
'$scope',
'$location',
'$http',
function($scope, $location, $http) {
$scope.credit_card = {};
$scope.credit.data = {
merchantId: 'your-merchant-id',
currentGMTTimestamp: 'your-currentGMTTimestamp',
epsType: 'your-epsType'
}
$scope.save = function () {
$http.post('/yourUrl', {credit_card: $scope.credit_card}).then(function(res){
// Successfully create data
},
function(response) {
// Failed to create data
});
}
}]);
I hope this can help you. :)
thanks every body above. just want to share the root cause
I have a directive called <credit-card></credit-card>, and inside this directive, I have the form, with both name and id to be creditCardForm, so when this directive is used in several places, and in the controller I use document.forms["creditCardForm"], js did not know which is the target form, and this results in empty values in the request
hope it can help someone with same problem

Checkbox not sending false value

I have a rails application which use AngularJS and I have a problem with a form, the problem is that I want to use a checkbox to send values true or false, but it only send true if it's checked and false if it's checked and unchecked after that, but if the user doesn't touch the checkbox, then it's not even sent as parameter.
<div class="checkbox">
<label>
<input type="checkbox" ng-model="car"> Do you have a car?
</label>
</div>
What can I do to make it send false if it the user doesn't ever check it?
Edit: The entire form is this, BTW, the form it's about creating a Poll, the car thing was just an example...
<h1>Create Poll</h1>
<form ng-submit="addPoll()" style="margin-top:30px;">
<div class="form-group">
<label>Title</label>
<input type="text" class="form-control" ng-model="title"></input>
</div>
<div class="form-group">
<label>Description</label>
<textarea type="text" class="form-control" ng-model="description"></textarea>
</div>
<br>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="allow_anonymous_answer" ng-false-value="false"> Allow anonymous answers
</label>
</div>
<br>
<div class="form-group">
<label>Welcome message</label>
<textarea type="text" class="form-control" ng-model="initial_message"></textarea>
</div>
<div class="form-group">
<label>Outgoing Message</label>
<textarea type="text" class="form-control" ng-model="final_message"></textarea>
</div>
<button type="submit" class="btn btn-primary" style="float: right;">Continue</button>
</form>
When you hit Continue I make HTTP POST request with Restangular to create a Poll, but the problem is that when I don't touch the checkbox this is what I see in the log of Rails...
Started POST "/polls.json" for 127.0.0.1 at 2016-01-26 14:05:57 -0300
Processing by PollsController#create as JSON
Parameters: {"title"=>"asddddddddddddddda", "description"=>"aaaaaaaaaaaaaaaaaaaaa", "initial_message"=>"asdasdddddddddd", "final_message"=>"aaaaaaaaaaaaaaaaaaad", "poll"=>{"title"=>"asddddddddddddddda", "description"=>"aaaaaaaaaaaaaaaaaaaaa", "initial_message"=>"asdasdddddddddd", "final_message"=>"aaaaaaaaaaaaaaaaaaad"}}
Note that the parameter allow_anonymous_answer doesn't even appear, if I check the checkbox then I can see that the parameter is set as true, if I check it and then uncheck it, then it's set as false, but the problem is when the user doesn't even touch this, when this happens then the parameter is not even shown...
Just in case you wanna see, this is the controller of AngularJS...
angular.module('myapp').controller('CreatePollCtrl', ['$scope', 'Restangular',
function($scope, Restangular) {
Restangular.setFullResponse(true);
$scope.addPoll = function() {
var poll = {title: $scope.title, description: $scope.description, allow_anonymous_answer: $scope.allow_anonymous_answer, initial_message: $scope.initial_message, final_message: $scope.final_message};
Restangular.all('polls').post(poll).then(function(response) {
});
};
}]);
I think you should put a variable in your controller to achieve the binding between your HTML component and your JS code.
I am currently developing an Angular app, and what i do is to initialize all the ng-model variables in the first lines of my controller, so why dont you give a try to this:
In your first controllers lines:
$scope.allow_anonymous_answer = false;
Did you take a look at angular docs: https://docs.angularjs.org/api/ng/input/input[checkbox]
You can explicitly state what value the checkbox should send when it is not selected using ng-false-value
Add an ng-click to that checkbox and update the model there. Works fine.
<div class="checkbox">
<label>
<input type="checkbox" ng-model="car" ng-click="updateCar(this)">Do you have a car?</input>
</label>
</div>
In your controller:
var updateCar = function(checkbox) {
if (checkbox.checked) {
car = false;
}
else {
car = true;
}
}
I solved it...
In the controller
if ($scope.allow_anonymous_answer == null)
$scope.allow_anonymous_answer = false

AngularJS : ng model not updating via date picker

I have a datetimepicker.
Overall, it works fine and updates the text box fine. However, when I place a ng-model onto the input field, nothing gets passed through to the binding at the bottom of the page.
Here!s the form I'm using :
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' ng-model="package.timeA" value="" class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
This is my JS code :
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'LT'
});
});
For the input box give some id or class name then initialize datepicker with that id or class
<input type='text' ng-model="package.timeA" value="" class="mydatePicker form-control" />
$('.mydatePicker ').datetimepicker();
It will work.
You can try to use $apply who allow to force reload of the variable and $setViewValue who allow to set the variable of the view.
add ng-change on your input tag and pass the date.
In your controller you can make a function like this:
$scope.onChange = function(package.timeA)
{
$scope.$apply(function (){
YourCtrl.$setViewValue(package.timeA)
}
}

Angular form name is passed as string when passed as parameter

I'm simply trying to reset a form using the angular functions $setPristine & $setUntouched (several forms are created with ng-repeat).
I assign the form name dynamically by using the syntax {{ someName }} (the name is build on the server side and is passed as json (string)).
The name of the form is correctly assigned in the markup and validations are working as expected. The problem arrises when I pass that name as a parameter in the ng-click="reset(someName)" function.
When debugging the name comes as a string and not as the form object which causes the error. I did a quick test by hard-coding the name and pass that same name and it works fine.
My assumption is, the name coming from json is a string and the type is forwarded to the function as is, instead of the object.
So the question is: is there a way to convert that name so it is interpretated correctly by the controller. Or maybe there is something else I'm missing...
Here is the markup ( notice the name of the form uses {{ resto.contactForm }} ):
<form novalidate name="{{ resto.contactForm }}" ng-submit="submit(restoContact, resto.contactForm.$valid)" class="sky-form">
<div class="form-group">
<label class="checkbox state-success">
<input type="checkbox" ng-model="restoContact.sameAsUser" name="sameAsUser" id="sameAsUser" value="true" ng-click="contactAutoFill()"><i></i>Contact name is same as current user.
<input type="hidden" name="sameAsUser" value="false" />
</label>
</div>
<div class="form-group">
<label class="control-label" for="contactName">Contact Name</label>
<input type="text" ng-model="restoContact.contactName" name="contactName" id="contactName" placeholder="John, Doe" class="form-control" required />
<div ng-show="{{ resto.contactForm }}.contactName.$error.required && !{{ resto.contactForm }}.contactName.$pristine" class="note note-error">Please enter a name or check the box 'Same as current user'.</div>
</div>
<div class="form-group">
<label class="control-label" for="contactPhoneNumber">Contact Phone Number</label>
<input type="text" ng-model="restoContact.contactPhoneNumber" name="contactPhoneNumber" id="contactPhoneNumber" placeholder="+1 555-1234-567" class="form-control" required ng-pattern="phoneNumberPattern" />
<div ng-show="({{ resto.contactForm }}.contactPhoneNumber.$error.required || {{ resto.contactForm }}.contactPhoneNumber.$error.pattern) && !{{ resto.contactForm }}.contactPhoneNumber.$pristine" class="note note-error">Please enter a valid phone number.</div>
</div>
<div class="margin-leftM19">
<button class="btn btn-primary">Save Changes </button>
<button class="btn btn-default" ng-click="reset(resto.contactForm)">Cancel </button>
</div>
</form>
Here is the reset function in the controller (form comes as "contactForm1" which is the correct name but is a string and not the object):
$scope.reset = function (form) {
if (form) {
form.$setPristine();
form.$setUntouched();
}
//$scope.user = angular.copy($scope.master);
};
I have not implemented th submit method but I'm sure I will be running into the same issue.
Any suggestions or advices are welcome.
Thanks in advance...
Here is the fidle.js. the variable data is an exact response from the server.
[http://jsfiddle.net/bouchepat/v0mtbxep/]
SOLUTION:
http://jsfiddle.net/bouchepat/v0mtbxep/3/
I removed $setUntouched as it throws an error.
You can't dynamically name a <form> or <ng-form>.
Although what you want, is make the form usable in the controller. You could do the following:
// in controller
$scope.form = {};
$scope.reset = function() {
$scope.form.contact.$setPristine();
$scope.form.contact.$setUntouched();
};
// in html
<form name="form.contact">
This is happening because resto.contactForm is a string defined on the scope. The angular directive for form is just creating a variable on the scope with the same name. To get the variable by a string, use $eval. This should work:
$scope.reset = function (formName) {
var form = $scope.$eval(formName);
if (form) {
form.$setPristine();
form.$setUntouched();
}
//$scope.user = angular.copy($scope.master);
};

Cannot reset form

I'm new to Angular and I have a simple retrieve password form with 1 email field and a submit button. I want to clear the form after the form has been submitted, but I can't seem to do it even after following tutorials/answers online.
I think it might be something I'm not understanding fundamentally, so if you could please let me know that would be great.
I'm using Angular v1.2.22
HTML (signin.forgotpassword.html)
<form name="forgotPasswordForm" class="form" role="form" ng-submit="forgetPasswordSubmit(forgetForm.email)" novalidate >
<div>
<label for="input-email" class="col-sm-2 control-label">Email</label>
<div>
<input name="email" ng-model="forgetForm.email" type="email" class="form-control" id="input-email" />
</div>
</div>
<div class="form-group">
<div>
<button name="submit" type="submit">Reset Password</button>
</div>
</div>
</form>
Angular (AuthController)
var forgetPasswordClear = function(){
var defaultForm = {
email: ''
};
// clear input
$scope.forgetForm = defaultForm; // Doesn't clear
// set form as pristine
$scope.forgotPasswordForm.$setPristine(); // Get Cannot read property '$setPristine' of undefined
};
$scope.forgetPasswordSubmit = function(email){
forgetPasswordClear();
};
----------EDIT----------
I'm not sure if it's because my form is sitting in a different ui view? My structure looks something like this:
HTML
<section data-ng-controller="AuthController">
<div data-ui-view>
Some content in there originally
<a ui-sref="signin.forgetpassword">Click here to get password</a>
</div>
</section>
Ui router
.state('signin.forgotpassword', {
url: '/signup/forgot-password',
templateUrl: 'modules/core/templates/signin.forgotpassword.html'
})
You set the wrong model:
Your model is 'forgetForm'
<input name="email" ng-model="forgetForm.email" type="email" class="form-control" id="input-email" ng-pattern="/.+\#.+\..+/" autofocus required />
current:
$scope.forget = defaultForm;
should be:
$scope.forgetForm = defaultForm;
EDIT TO ADDRESS NEW PROBLEM
It's because this is a child scope.
You need to use event emitters and listeners.
$broadcast -- dispatches the event downwards to all child scopes,
$emit -- dispatches the event upwards through the scope hierarchy.
Read more here: Working with $scope.$emit and $scope.$on

Resources