I have a form inside an ng-if inside a controller with an ng-include, which doesn't submit...
I know ng-if and ng-include creates their own scopes, but I thought you could access controller methods..
index.html
<div data-ng-controller="myCtrl">
<div data-ng-include="form.html" data-ng-if="loadForm"></div>
</div>
form.html
<form action="" data-ng-submit="submit($event)">
<input type="text" name="foo" data-ng-model="foo">
<input type="submit" value="Go!">
</form>
ctrl.js
'use strict';
app.controller('myCtrl', function ($scope, $element, $http, $log) {
$scope.loadForm = true;
$scope.submit = function(e) {
e.preventDefault();
console.log("hello");
};
}
);
When I click on submit, nothing is logged into console, also e.preventDefault(); not firing...
I know the issue is scope hierarchy... I can't do data-ng-submit="$parent.submit($event)" because the form will be used elsewhere and form code needs to be reusable.
#Robert, you can use ng-show instead of using ng-if.
Because ng-if create/destroy the new DOM tree based on expression evaluation true/false respectively.
Related
Having these two files:
HTML:
<form name="registrationForm" ng-submit="registerUser()">
...
</form>
JS (inside the Angular controller):
$scope.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);
I get the error that Cannot read property 'confirmPassword' of undefined
This leads me to believe that I have no access to the form registrationForm in the controller. Based on this (https://docs.angularjs.org/api/ng/type/ngModel.NgModelController) I imagined that I should.
Other solutions that I've seen include passing the form to the controller when the form is submitted, but what I need to do (set custom validation) needs to happen way before that.
Other solution mentioned adding the controller to the form via ng-controller but that changed nothing.
EDIT:
From the website above, is there a reason why in here (https://plnkr.co/edit/ZT0G6ajdbescT72qLKSU?p=preview) $scope.myForm can be accessed, but only inside of the $scope.setEmpty function?
I recommend using the controller itself instead of the $scope provider for this. This was one of the first issues I came across when working with angularjs
In your controller:
function MyController($scope) {
var vm = this;
vm.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);
}
In your form:
<form name="vm.registrationForm" ng-submit="registerUser()">
...
</form>
The only gotcha is that you need to specify the controllerAs property in your route or ngInclude:
ng-include="templates/my-template.html" ng-controller="MyController as vm"
or
when('/my-route', {
templateUrl: 'templates/my-template.html',
controller: 'MyController as vm'
})
You need to add a name attribute to form element.
<form name="registrationForm" ng-submit="registerUser()">
...
</form>
this form must rely on a controller indeed. please take a look at the example:
angular.module("fooApp",[]);
angular.module("fooApp")
.controller("formctl",function(){
this.user={};
this.dosave=function(){
if(this.user.pwd == this.user.confpwd)
alert(this.user.username+" logged");
else
alert("pwd does not match");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="fooApp">
<h1>sample</h1>
<div ng-controller="formctl as ctl">
<form ng-submit="ctl.dosave()">
<label>username</label><br/>
<input ng-model="ctl.user.username" required/><br/>
<label>password</label><br/>
<input ng-model="ctl.user.pwd" type="password" required/><br/>
<label>confirm password</label><br/>
<input ng-model="ctl.user.confpwd" type="password"/><br/>
<input type="submit"/>
</form>
</div>
</div>
You'll want to pass the form into the submit function to pass the entire form into the controller. Use the form name.
<form name="registrationForm" ng-submit="registerUser(registrationForm)">
...
</form>
The other option would be to pass the inputs directly in as params
<form name="myForm" novalidate >
some input: <input type="text" name="sometext" ng-model="myInput">
<input type="submit" ng-click="doAction(myInput)">
</form>
Quick Plunk
https://plnkr.co/edit/s0Al2LTHkvUPoLYNzTpm?p=info
If you're just after the value of the inputs, it's easier to test if you have explicit parameters that you expect on the method instead of dumping in the entire form.
I am trying to write convert my current api call into a factory which is reusable inside ApiService factory. However, I can't seem to clear the form.
So, what i can i do to make the clearForm function work as it is.
<form name="formName">
<input type="name" ng-model="form.username"></input>
<input type="password" ng=model="form.password"></input>
<button type="submit" ng-click="submitForm()">Submit</button>
<form>
form is in $scope. You can't access it without using $scope and factory don't have $scope.
try like this
$scope.formName.$setPristine();
All you can do is to pass that form to service and clear it
'clearForm': function(formName) {
formName.$setPristine();
formName.$setUntouched();
}
from controller
FormFactory.clearForm($scope.formName);
Hello I am running an app wich needs a lot of form validation across pages, so I am trying to get validation patterns from a service i am using amongst the controllers.
The problem here is the ng-pattern isn't reacting the right way when I enter a correct email address.
This is a plunker and here's the code for the form
<form method="POST" action="#" name="newsletterForm" id="newsletterForm" ng-controller="newsletterForm" novalidate>
<input ng-pattern="/{{patterns.email}}/" type="email" name="email" ng-model="email" required />
<button type="submit">Invia</button>
{{newsletterForm.email.$error.pattern}}
</form>
This is the app.js code
var app = angular.module('plunker', []);
app.controller('MainCtrl', function(){});
app.service('validationPatterns', function() {
this.getPatterns = function() {
return {
email: "^([a-zA-Z0-9\'\.\-\_]{2,64})([\#]{1})([a-zA-Z0-9\.\-\_]{2,64})([\.]{1})([a-zA-Z]{2,16})$"
}
}
});
app.controller('newsletterForm', function($scope, validationPatterns){
$scope.patterns = validationPatterns.getPatterns();
});
I assume the problem might be that when angular renders the pattern inside the input tag it renders it escaping the backslashes
^([a-zA-Z0-9'.-_]{2,64})([#]{1})([a-zA-Z0-9.-_]{2,64})([.]{1})([a-zA-Z]{2,16})$
I have already tried adding the double backslashes in the service to make angular render it correctly but it's still not working.
Any ideas?
ng-pattern works with a $scope variable. In your case it should be
<input ng-pattern="patterns.email"
Updated plunker
The idea is disable the 'Submit Me' button when form 'myForm' is invalid. I tried searching but all of the examples are within the form. Can someone shed some ideas on how to do this?
Note: The button I want to disable is outside the form, buttons within the form will be disabled.
EDIT Additional: the form in being added using ng-include and the button is added using a separate ng-include. Sorry for not adding this detail maybe this is the reason it does not work in my case.
Plunkr: http://plnkr.co/edit/7BY2kwciERqQLNGfcDtz <--- this is working now.
Form.html
<form name="myForm">
<input name="myText" type="text" ng-model="mytext" required />
<button ng-disabled="myForm.$invalid">Save</button>
</form>
Button.html
<button ng-disabled="myForm.$invalid">Submit Me</button>
HtmlBody:
<body>
<div class="slide-animate" ng-include="'form.html'"></div>
<div class="slide-animate" ng-include="'button.html'"></div>
</body>
Basically what i did was create a parentForm using ng-form so I can access the child scopes produced by ng-include. See the plunkr for more information.
I have added this plunkr:
http://plnkr.co/edit/7BY2kwciERqQLNGfcDtz
You can watch the validity of a given form in your controller and update a scope value based on that:
$scope.$watch('myForm.$valid', function(newVal) {
$scope.myFormValid = newVal;
});
Then on your button:
<button ng-disabled="!myFormValid">Submit Me</button>
You break the form logic by putting the submit button outside de form.
However, I copy/pasted your html code in a jsfiddle and it worked fine without any change. The submit button is disabled when the field is empty.
Here is the fiddle : http://jsfiddle.net/LAeeF/
I just added a basic controller :
function myCtrl($scope) {
$scope.submit = function () {
alert('Submit button enabled');
}
}
I am building an AngularJS application that includes modal windows which contain forms and are loaded into the DOM asynchronously (when the appropriate button is clicked). The forms work fine, but I cannot properly check if they are valid. Here's an example:
HTML
<div ng-app="myapp" ng-controller="MyCtrl">
<form novalidate name="myform" ng-submit="submitForm(myform)">
<input type="text" required ng-model="myname" />
</form>
</div>
JavaScript
var app = angular.module('myapp', []);
app.controller("MyCtrl", function($scope) {
$scope.submitForm(form) {
if(form.$valid) {
// Do http stuff here
}
};
});
If this form is loaded asynchronously, the form variable has value NaN and form.$valid is undefined. However, if I load it with the rest of the page, it works fine. Does anyone know how to force AngularJS to populate the scope variable for the form? Thanks!
When you include a form using ng-include a childScope is created. The parent and the childScope cant access eachothers scopes. Therefore the .$valid comes up empty.
I had a similiar issue the other day and got a working solution that suited me in this thread:
AngularJS $setValidity on childScope form