After I click submit in a form, some javascript runs to modify the data and sends it to whatever the form action is specified in the HTML:
// Submit the form:
// $form.get(0).submit();
$('.submit', $(event.target.form)).click();
I would like to instead use ng-click and send that info to an angular function, such as vm.checkout().
How can I make this happen?
Use ngSubmit directive instead of ngClick for form submit.It binds to the submit event which is fired when a form is submitted.
ng-submit works only when forms submitted.
where as ng-click can work without form submit event.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.submitMe = function () {
alert('Submitted');
};
});
<div ng-app="myApp" ng-controller="MyCtrl">
<form ng-submit="submitMe()" name="myForm">
<button type="submit">submit</button>
</form>
</div>
JavaScript
$scope.submit = function(data){
// do something with data
}
HTML
<form>
<input type="text" ng-model="temp.name" name="name"/>
<button type="button" ng-click="submit(temp)">Submit</button>
</form>
If it is a form you are submitting you should use ng-submit. Add the ng-submit tag with the corresponding function which will be in your controller. Then, you will be able to handle the data from your form submission.
For example:
<form ng-submit="submit()" ng-controller="ExampleController"></form>
Related
I have gone through several questions regarding this issue, but none solved my issue
I am using a form in which two submit type button calling same function. One button is send an extra variable with it on ng-click. when I submit my function is being called twice.
I am using an approach told in the second answer of this question (mostly voted)
I have not included controller as ng-controller in HTML
<form ng-submit="SaveContent(Form)">
<button type="submit">Save</button>
<button type="submit" ng-click="Data.IsSent = true">Save & Send</button>
</form>
How to handle this issue ?
The angular form docs specifies it as
if a form has one or more input fields and one or more buttons or
input[type=submit] then hitting enter in any of the input fields will
trigger the click handler on the first button or input[type=submit]
(ngClick) and a submit handler on the enclosing form (ngSubmit)
I inserted your code in below example and it behaves exactly like it is specified in the docs and only one submit (the first) is executed when submitting the form
angular.module("app",[]).controller("myCtrl",function($scope){
$scope.Data ={};
$scope.Data.IsSent = false;
$scope.SaveContent = function(form){
if($scope.Data.IsSent){
alert('submitted- and ngclick is invoked');
}else{
alert('submitted');
}
$scope.Data.IsSent = false;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<form ng-submit="SaveContent(Form)">
<input type="text" name="text1"/>
<button type="submit">Save</button>
<button type="submit" ng-click="Data.IsSent = true">Save & Send</button>
</form>
</div>
I had the same issue and it took me 5 days to figure it out. Do not add (ngSubmit) in the opening tag of the form.
I have sample code like this:
Html Code:
<body ng-controller="MainCtrl">
<form name="myForm">
<input name="myText" type="text" name="test" ng-model="mytext" required />
<button ng-click="save()" ng-disabled="myForm.$invalid">Save</button>
</form>
</body>
Js code:
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.save = function(){
//logic or http method
console.log("Test");
}
});
Attached the code in this link: Click Here
Logic:
Default save button disabled.
After enter the form enable the button.
After save again disable the save button.
Again user enter the text need to enable save button.
Note: Here I attached only one input but I have multiple input fields.
Also, In save function I had logic data save into database.
You can use $pristine to identify if there were any changes to the form and enable button only then:
<body ng-controller="MainCtrl">
<form name="myForm">
<input name="myText" type="text" name="test" ng-model="mytext" required />
<button ng-click="save(myForm)" ng-disabled="myForm.$invalid || myForm.$pristine">Save</button>
</form>
</body>
Notice how $pristine is used on ng-disabled:
ng-disabled="myForm.$invalid || myForm.$pristine"
In this case button will be disabled if form is invalid or if there were no changes to the form.
If you use this approach you also need to set the form to pristine after saving the data. You can use method $setPristine:
$scope.save = function(myForm) {
// set form to pristine
myForm.$setPristine();
}
Notice that there is a form parameter which is used to pass a form to the method. In HTML you also need to pass this parameter as part of ng-click:
ng-click="save(myForm)"
Here is JSFiddle that demonstrates the functionality
For more information check out documentation of FormController.
you have disabled the submit button when the form is invalid.
myForm.$invalid
so whenever a required field is blank the form will be invalid and button will be disabled. As soon as all the required input in the form have values, submit button will be enabled.
To make it disabled you need to reset all the modal variables of the required inputs once the save has done its work i.e on the success call back of http request reset the model variables.
Well here is how i would do it, i'll add another tracking variable. something like this.
$scope.btnStatus = true;
$scope.save = function(){
//logic or http method
$scope.btnStatus = false;
console.log("Test");
}
$scope.onChange = function(){
if($scope.btnStatus == false)
$scope.btnStatus = true;
}
and the html would look like this.
<form name="myForm">
<input name="myText" type="text" name="test" ng-change="onChange()" ng-model="mytext" required />
<button ng-click="save()" ng-disabled="myForm.$invalid || !btnStatus">Save</button>
</form>
Here is a working code based off of your code.
I have a form where the url action come from an API call.
So, in the submit event of the form I need to call an API that receive the URL then I need set the action of the form and trigger the POST.
But, all the steps must run only when the user click on the submit button.
I tried:
<form name="myForm" ng-submit="form.submit()" method="post" enctype="multipart/form-data" >
<input type="file" name="file" id="file">
<input type="submit" value="Upload Image" name="submit">
</form>
and
angular.module('formCtrl', ['formService', 'authService'])
.controller('formController', function($scope, $http, Form, AuthToken) {
var vm = this;
vm.submit = function() {
Form.get().success(function(data)
{
if (data.url)
{
document.myForm.action = data.url;
document.myForm.submit();
}
});
}
});
But didn't work. Actually, I tried a lot of thing without success.
And I'm not using jquery in my project.
Can some one give me some help in how to do it ?
Add submit to your $scope and specify ng-controller as your controller formController
The user of my web should enter a simple code using buttons in my form and after that he should click Ok or hit enter and continue with proccess.
The thing is that the enter key is not submiting my form, is executing other method that is called from ng-click. How can avoid enter key call the ng-click method?
myapp.js
var myApp = angular.module('myApp',[]);
myApp.controller('myformcontroller', ['$scope', function ($scope){
// Procesing data from form.
$scope.signin = function () {
}
}]);
myApp.controller('mycontroller', ['$scope', function ($scope){
$scope.do = function() {
alert('ng-click pressed!');
}
}]);
myform.html
<div ng-controller="myformcontroller">
<form name="myForm"
role="form"
ng-submit="signin()"
novalidate>
<input type="text"/>
<div ng-controller="mycontroller">
<a href="javascript:void(0);" ng-click="do()">
clickme!
</a>
</div>
<button type="submit">Ok</button>
</form>
</div>
Press click me and hit enter key after on My Fiddle
You can ommit html rules with jquery.
Add id to a form and button first:
<form id="mydiv" name="myForm"
role="form"
ng-submit="signin()"
novalidate>
<div ng-controller="mycontroller">
<a href="javascript:void(0);" ng-click="do()">
<img src="img/a-letter.png" alt="">
</a>
</div>
<button id="mydiv2" type="submit">Ok</button>
</form>
And then set listener on enter up:
$("#mydiv").keyup(function(event){
if(event.keyCode == 13){
$("#mydiv2").click();
}
});
So it's not elegant, but you can submit form with simulating click on enter pressed.
It is not blocking. You're missing a standard input to bubble the properly handled click event. If there is no input, the form is not submitted by default. It's not an angular issue. Take a look here https://stackoverflow.com/a/477699/4573999
EDIT
More detailed explanation based on comments. The question is not about the submit element. Sure, you have a button type submit. The for other elements inside the form there is a default behavior. And for input element the default on enter key is to submit the form that it is surrounded by. But for the anchor tag it is not. Because it is not supposed to provide any data. Why would you want to submit a form on a link? So in your case you should submit the form programmatically by calling appropriate method.
myApp.controller('myformcontroller', ['$scope', function ($scope){
$scope.signin = function () {
alert('submit!');
}
}]);
myApp.controller('mycontroller', ['$scope', function ($scope){
$scope.do = function() {
alert('ng-click pressed!');
$scope.signin();
}
}]);
Check updated fiddle
If you'd like to get this in a generic way, you can parse the ng-submit value like here How to programmatically submit a form with AngularJS
How can I prevent submitting a form in Angular until I receive a callback?
I have something along these lines:
<form method="post" action="http://example.com/external" ng-submit="submit()">
<input type="hidden" name="foo" value="{{bar}}" />
<input type="submit" />
</form>
Before submitting the form, I need to get the {{bar}} value from a local API call (using $http), and place it in the scope before allowing the actual form to submit (not POSTed using $http). How can this be done?
The form directive in Angular will wrap it in a formController and intercept it. You can still run your asynchronous code but you will need to reference the DOM form to submit it. I have an example fiddle with the solution - basically it sets up a button to submit the form, asynchronously sets the hidden field, then posts it.
Here is the relevant code:
MyController = function ($scope, MyService) {
$scope.boo = "";
$scope.submit = function () {
MyService.getAsync().then(function(result) {
$scope.boo = result;
document.myForm.action = "http://example.com/";
document.myForm.submit();
});
};
};
If you run a fiddle you will see the hidden field is populated:
http://jsfiddle.net/jeremylikness/T6B2X/
The "ugly" part of the code is the direct reference to:
document.myForm
If you wanted to clean this up, you could write your own directive that allows you to place an attribute on the form and interacts with a service to manipulate it. I.e. MyFormService and then I could do MyFormService.setAction(url) and MyFormService.submit() - that would be more cleaner and reusable but time wouldn't permit me to set that up for you.
As docs for ng-submit state:
Additionally it prevents the default action (which for form means
sending the request to the server and reloading the current page) but
only if the form does not contain an action attribute.
So remove that action attribute and handle it directly yourself in the submit() handler on the scope.
Make yours http call and in then success handler submit the form manually.
Can you not just use the submit button's onClick event to call a function that returns false if the submit is not allowed?
i.e. onClick='return CheckIfFooPopulated();'
Then in that function return false is foo as not yet been set or true if it OK to submit.
The problem is that ng-submit doesn't work with an action attribute, as stated in the docs.
Then, you can do whatever you want inside of submit() in your controller. However, I would use ng-model for the form input fields because it gives you better control over the model.
You would use this $scope.formModel to bind the input fields to the scope.
You could implement submit like that:
$scope.submit = function() {
$http.get("URL").success(function(data) {
$http.post("URL2", { model: $scope.formModel, bar: data.bar }).success(function() {
$location.path("/new-route");
});
});
}
There many possibilityes, but a less risky is to use ng-switch.
ng-switch do not load DOM if not needed.
<span ng-switch on="barNotEmpty">
<span ng-switch-when="true">
<form method="post" action="http://example.com/external" ng-submit="submit()">
<input type="hidden" name="foo" value="{{bar}}" />
</form>
</span>
<span ng-switch-default>
<form>
<input type="hidden" name="foo" value="{{bar}}" />
</form>
</span>