Im trying to validate my form, if the fields are valid then it should post the data to the DB if not prevent from posting the data to DB. when I submit the form Im getting an error TypeError: Cannot read property '$valid' of undefined, I don't know how to overcome it, need help in this.
html:
<form name="formvalidation">
<ion-view ng-controller="ValidationCheck">
<ion-content>
<div>
<strong>User:</strong> <br/>
<input ng-model="name" type="text" name="name" required/>
<ng-messages for="formvalidation.name.$error" ng-if="formvalidation.name.$invalid">
<div ng-messages-include="error/validation.html"></div>
<ng-messages>
</div>
</from>
<button ng-click="check()">
controller:
myApp.controller('ValidationCheck',function($scope, applicationService)
{
$scope.check=function(formvalidation){
var name={'name'=$scope.name};
$scope.submitted=true;
if(formvalidation.$valid){
applicationService.save(name,$scope.home);
}}});
Just change your if condition formvalidation.$valid to formvalidation
. because you already pass formvalidation.$valid in your function via ng-click
if(formvalidation){
...
...
...
}
Remove ng-click and add a ng-submit:
<form name="formvalidation" ng-submit="check()" novalidate>
Try this : ( controller before form )
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
In your html you have:
<button ng-click="check(formvalidation.$valid)">
which calls the check function with either a true or false value (a boolean), depending on whether or not the form is valid.
In your controller you have the check function with the following if-statement:
if(formvalidation.$valid)
but formvalidation is a boolean (true or false)
I recommend removing the argument from check and simply access the formvalidation properties from the $scope variable.
so the html becomes
<button ng-click="check()">
and the controller becomes
$scope.check=function(){
var name={'name'=$scope.name};
$scope.submitted=true;
if($scope.formvalidation.$valid) {
applicationService.save(name,$scope.home);
}
}
<form> should come after controller declaration
<div ng-app="app">
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
<ion-content>
var app = angular.module("app", []);
app.controller('ValidationCheck', function($scope) {
$scope.check = function(formvalidationBoolean) {
alert(formvalidationBoolean);
var name = {
'name': $scope.name
};
$scope.submitted = true;
if (formvalidationBoolean) {
//applicationService.save(name, $scope.home);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<ion-view ng-controller="ValidationCheck">
<form name="formvalidation">
<ion-content>
<div>
<strong>User:</strong>
<br/>
<input ng-model="name" type="text" name="name" required/>
<ng-messages for="formvalidation.name.$error" ng-if="formvalidation.name.$invalid">
<div ng-messages-include="templates/admin/validation.html"></div>
<ng-messages>
</div>
</from>
<button ng-click="check(formvalidation.$valid)">Submit</button>
</div>
You are sending boolean value "ng-click="check(formvalidation.$valid)", So your statement if(formvalidation.$valid){ inside controller is wrong.
And You need to change "=" to ":" in var name = {'name': $scope.name };
Related
i am facing a weird issue with angular js.
I am using a textarea and have a default value for that. But when i change the value in the textarea manually its not being updated in my controller.
Also the other scope is not being binded into the default value.
my Html
<div ng-controller="req" class ="ng-cloak">
<form name="dynamic_fields_tm" ng-submit="goDynamicTm()">
<input type="text" ng-model="tmDynam.one">
<input type="submit" value="Go!" ng-show="tm_dynamic1">
</form>
<div class="request" ng-if="postrequest_disp">
<textarea>{{postrequest}}</textarea>
</div>
</div>
Js
app.controller('req', function($scope ,$rootScope ,$http ,$location ,$window, $timeout) {
$scope.postrequest = "{'event':{'event_id':" + $scope.tmDynam.one+"} ,'note':'Testing', 'is_display_price': 'true', 'ticket_ids':["+$scope.tmDynam.two+"] }";
$scope.postrequest_disp = true;
$scope.tm_dynamic1 = true;
$scope.goDynamicTm = function()
{
console.log($scope.postrequest);
}
});
First Issue. in the console i am only receiving the default value..but not the updated value when i update in textarea.
Second is the $scop.tmDynam.one is not being updated with the $scope.postrequest.
ALso i have used ng-model instead of {{}}. BUt still issue persists
Please help
Since you are using textarea inside ng-if it creates an isolated scope.So you need to access the parent scope. Use the ng-model in textarea with the $parent.postrequest.
Demo
var app = angular.module("myApp",[]);
app.controller('req', function($scope ,$rootScope ,$http ,$location ,$window, $timeout) {
$scope.tmDynam = {one:'', two: ''}
$scope.postrequest = "{'event':{'event_id':" + $scope.tmDynam.one+"} ,'note':'Testing', 'is_display_price': 'true', 'ticket_ids':["+$scope.tmDynam.two+"] }";
$scope.postrequest_disp = true;
$scope.tm_dynamic1 = true;
$scope.goDynamicTm = function()
{ $scope.postrequest = "{'event':{'event_id':" + $scope.tmDynam.one+"} ,'note':'Testing', 'is_display_price': 'true', 'ticket_ids':["+$scope.tmDynam.two+"] }";
console.log($scope.postrequest);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="req" class ="ng-cloak">
<form name="dynamic_fields_tm" ng-submit="goDynamicTm()">
<input type="text" ng-model="tmDynam.one">
<input type="submit" value="Go!" ng-show="tm_dynamic1">
</form>
<div class="request" ng-if="postrequest_disp">
<textarea ng-model="$parent.postrequest"></textarea>
</div>
</div>
</div>
I have the following Angular code
controller:
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.job = null;
vm.create = function (job) {
vm.job = job;
}
});
HTML:
<div ng-controller="MainCtrl as vm">
<span data-ng-bind="vm.job.position"></span>
<form name="form" data-ng-submit="vm.create(vm.job)">
<label for="position">Position</label>
<input id="position" name="vm.job.position" type="text" data-ng-model="vm.job.position" />
<button>Create</button>
</form>
</div>
But when I submit the form I don't see the Position value.
Any idea why?
Because
You forgot to add ng-app to the body or html element
You're using angular 1.0.8, which is completely obsolete, and doesn't support controller as.
Note that you don't even need to submit, since the job you're binding is already vm.job. Your create(vm.job) method call does nothing: it assigns vm.job to vm.job.
I have a form like this -
<form name="myForm" novalidate>
There are some fields in the form which I am validating and then submitting the form like this -
<input type="button" ng-click="Save(data)" value="Save">
In the controller, I want to check if the form is not valid then Save() should show some error on the page. For that, I am setting up a watch like this -
$scope.$watch('myForm.$valid', function(validity) {
if(validity == false)
// show errors
});
But I am always getting this error on running it -
Cannot read property '$valid' of undefined
Can someone explain why?
Thanks
You just misspelled "myForm" in your controller code. In order to remove the error, Write "myform" instead of "myForm".
However I expect what you want is like this.
$scope.Save = function(data){
alert($scope.myform.$valid);
}
I setup jsfiddle.
In my case I was wrapping the form in a modal created in the controller and therefore got the same error. I fixed it with:
HTML
<form name="form.editAddress" ng-submit="save()">
<div class="form-group">
<label for="street">Street</label>
<input name="street" type="text" class="form-control" id="street" placeholder="Street..." ng-model="Address.Street" required ng-minlength="2" />
<div class="error" ng-show="form.editAddress.street.$invalid">
<!-- errors... -->
</div>
</div>
<button type="submit" class="btn btn-primary" >Save address</button>
</form>
JS
angular.module("app").controller("addressController", function ($scope, $uibModal, service) {
$scope.Address = {};
$scope.form = {};
$scope.save = function() {
if (modalInstance !== null) {
if (isValidForm()) {
modalInstance.close($scope.Address);
}
}
};
var isValidForm = function () {
return $scope.form.editAddress.$valid;
}
});
I want my controller to perform some action when a user clicks in a form field (when the form field gets focus). How can I do this? See this plunker.
Here is my controller:
angular.module('myApp', [])
.controller('AppCtrl', ['$scope',
function($scope) {
$scope.field1 = "Default text";
$scope.focus = false;
$scope.formFieldJustGotFocus = function() {
$scope.focus = true;
// Do all the stuff I need to happen when the form has just gotten focus
}
}
]);
And here is the view:
<body ng-app="myApp" ng-controller="AppCtrl">
<h3>Testing</h3>
<p>I want to perform some action in the controller when a form field gets focus. How can I best achieve this?</p>
<form name="myForm">
<input type="text" name="field1" ng-model="field1">
</form>
<p>Form field has focus: {{focus}}</p>
</body>
You can use the ngFocus directive. The inverse is ngBlur.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<input type="text" ng-focus="isFocused = true" ng-blur="isFocused = false">
<p ng-if="isFocused">Focus !</p>
</div>
<input type="text" name="field1" ng-model="field1" ng-focus="formFieldJustGotFocus()">
use like this ng-focus
Try ng-focus.
See more info:
https://docs.angularjs.org/api/ng/directive/ngFocus
use -> ng-focus
<input type="text" name="field1" ng-model="field1" ng-focus="formFieldJustGotFocus();">
this plunker
in the code he had written the function formFieldJustGotFocus(), but it was not bound to the focus event
When I try to use form.$setPristine from TypeScript, it doesn't work and the debug says form is undefined. According to what I read, $scope.formName.$setPristine() shall set the form to pristine. To access $scope.formName from the controller, I added it to my custom scope interface as an ng.IFormController property. However, when I call $scope.form.$setPristine(), it doesn't work, and debug shows $scope.form is undefined.
TypeScript:
interface IMyScope extends ng.IScope {
employees: Array<IEmployee>;
employeeToAdd: IEmployee;
addEmployee(): void;
form: ng.IFormController;
}
class EmployeeAddController {
static $inject = ['$scope', 'Employees'];
constructor(
$scope: IMyScope,
$modalInstance: ng.ui.bootstrap.IModalServiceInstance,
Employees: IUpdateableResourceClass<IUpdateableResource>
) {
$scope.employees = new Array<IEmployee>();
$scope.employeeToAdd = {
Name: '',
Email: ''
};
$scope.addEmployee = function () {
Employees.save(null, $scope.employeeToAdd, function (employee: IEmployee) {
$scope.employees.push(employee);
$scope.employeeToAdd.Email = '';
$scope.employeeToAdd.Name = '';
$scope.form.$setPristine(); // $scope.form is undefined
});
};
}
}
HTML:
<form role="form" class="form-inline" name="form">
<div class="form-group" ng-class="{ 'has-error': form.name.$dirty && form.name.$invalid }">
<input type="text" class="form-control" ng-model="employeeToAdd.Name" name="name" required>
</div>
<div class="form-group" ng-class="{ 'has-error': form.email.$dirty && form.email.$invalid }">
<input type="email" class="form-control" ng-model="employeeToAdd.Email" name="email" required>
</div>
<button type="button" class="btn btn-default" ng-click="addEmployee()" ng-disabled="form.$invalid">Add</button>
</form>
What I have done in my application with form is to pass the form object into the method that clears it instead of working off the scope directly.
<button data-ng-click="clearAndResetForm(Form)"></button>
$scope.clearAndResetForm = (form:ng.IFormController)=> {
this.clearAndResetForm(form);
};
private clearAndResetForm(form:ng.IFormController) {
this.$scope.fieldOne = undefined;
this.$scope.fieldTwo = undefined;
form.$setPristine();
}
I'm not entirely sure why my code would work while yours doesn't. But hopefully this approach might help you.
Although Sobieck00's solution works as well, thanks to stevuu's suggestion, I have debugged it and found a way to do it without having to pass the form reference. form can be accessed as $scope.$$childTail.form:
interface IMyScope extends ng.IScope {
employees: Array<IEmployee>;
employeeToAdd: IEmployee;
addEmployee(): void;
$$childTail: any; // Add this to access $$childTail in current scope
}
Then in $scope.addEmployee() reset it with:
$scope.$$childTail.form.$setPristine();
I had a similar problem and the problem occurred because the <form> tags were in the view rather than the template. For example;
<!-- This was in the template -->
<div class='container-fluid body-content'>
<ng-view>
</ng-view>
</div>
<!-- And this was in the view -->
<form id="frmSection" name="frmSection" role="form" class="form" novalidate>
.
.
.
</form>
Once I changed this to;
<-- Template -->
<div class="container-fluid body-content">
<form id="frmSection" name="frmSection" role="form" class="form" novalidate>
<ng-view>
</ng-view>
</form>
</div>
<-- View -->
<fieldset>
<legend>Report Text</legend>
<div class="form-group">
.
.
.
</div>
</fieldset>
The line $scope.frmSection.$setPristine(); worked as expected.
The other answers may work but it seems they are overcomplicating things. If you use "controller as", you can just give the form a name based on the alias and be done with it.
Take a look at the following example. I just name the form as a property on my controller, and then as you can see from the JavaScript I can reference it directly by name. No tricks, gimmicks, or strange work arounds and no need to rely on $scope.
(function (app) {
function ctrl() {
}
angular.extend(ctrl.prototype, {
email: '',
submit: function () {
if (this.ctrlForm.email.$invalid) {
alert("Invalid email!");
return;
}
alert("Submitted " + this.email);
this.email = '';
this.ctrlForm.$setPristine();
}
});
app.controller("formCtrl", ctrl);
})(angular.module("formExample",[]));
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<div ng-app="formExample" ng-controller="formCtrl as ctrl">
<form name="ctrl.ctrlForm" role="form" novalidate="">
<input name="email" type="email" required="" ng-model="ctrl.email" placeholder="Enter a valid email."/>
<div ng-if="ctrl.ctrlForm.email.$invalid">Email is invalid!</div>
<button ng-click="ctrl.submit()" ng-disabled="ctrl.ctrlForm.$invalid || ctrl.ctrlForm.$pristine">Submit</button>
</form>
</div>
Note that formCtrl is the name I register the controller with, and ctrl is the alias for my controller (some people might prefer vm, so I name the form ctrl.ctrlForm. That is how I reference it in the HTML. The controller then gets that property, so it is referenced simply as this.ctrlForm.
Also as a fiddle: http://jsfiddle.net/jeremylikness/du5ptxyc/