Angular not submitting parameter with ng-click - javascript

I'm trying to submit a standard form within an angular app.
Everything works well until I tried to add ng-click to the submit button of the form
The action on the click is just cosmetic to give the user some feedback.
The behavior I have is a bit strange. The submit is done and the call to the click behavior are both called, however, there is no parameters submitted with the form.
I've been googling a bit, and people seems to say that using ng-click on a form disable the submit, but it doesn't, Every works fine , except the form parameters which are not send.
I know I can probably redefine my own submit function, intercept the post using ng-submit and do the post myself, it just seems an overkill, as I want to do is almost working.
(in that case, how do you I get the form parameters from within the angular callback ?)
Update
Here is a live example : http://jsfiddle.net/hHapg/5/.If you check a box and submit, there is no parameter on the URL.
If you edit the file and remove the ng-click on the submit button, it works.
<form ng-app="test" action="/echo/jsonp" name="orders" target="_blank" ng-controller="test">
<table>
<tr ng-repeat="order in [{orderId:1}, {orderId:4}]" >
<td>
<input type="checkbox" name="order_ids{{i}}" value="{{order.orderId}}"></input>
</td>
<td>
{{order.orderId}} : {{ order.checked}}
</td>
</tr>
</table>
<input type="submit" name="action" value="Picking List" class="btn btn-primary picked" ng-clik="submit(true)">
</form>
Solution
Found the problem. Even though the real code wasn't exactly the one I published. with the help of Langdon I manage to solve it. The problem was I had an hardcoded array in the form declaration (not in the ng-repeat as in my example). (It was hardcoded from an angular point of view, but in fact generated at runtime). Moving this array to the top (same as ng-ap), solved the prome.

Are you setting the name attribute on all your input and select tags? I imagine most Angular examples do not include the name attribute because submitting forms seems a thing of the past.
The simplified example below works fine. I would need to see your specific code to help you troubleshoot what else the problem might be.
http://jsfiddle.net/langdonx/DUV9q/
HTML:
<form ng-app="test" ng-controller="test" action="/echo/jsonp/" method="get">
<input type="text" name="value1" ng-model="value1"/>
<input type="text" name="value2" ng-model="value2"/>
<input type="submit" ng-click="submit()">
</div>
JavaScript:
var app = angular.module('test', []);
app.controller('test', function ($scope, $http) {
$scope.value1 = "val 1 here";
$scope.value2 = "and val 2 here";
$scope.submit = function () {
alert('it should submit now, if it worked, you\'ll see some json');
}
});

Related

AngularJs - submit the form programmatically

I read several answers on this topic but they don't seem to apply to my problem. My problem is quite complex. I have a form which uses ReportViewer.ASPX. The form is defined as following:
<form name="form" novalidate role="form"
sm-dirty-check
id="reportViewer"
method="post"
action="~/Infrastructure/ReportViewer/reportViewer.aspx"
target="viewerIFrame"
ng-show="crud.showForm" class="ng-cloak">
#* Form inputs *#
<input type="hidden" name="labelType" value="Rental" />
<input type="hidden" name="labelLayoutId" value="{{ crud.model.lbLayoutId }}" />
<input type="hidden" name="itemsToPrint" value="{{ crud.jsItemsToPrint }}" />
The actual forms are defined in the tabs using ng-form (I only shared the top portion of my Edit form which is relevant to my question).
I also have these buttons at the bottom of the form:
<button type="submit"
ng-if="crud.model.lbLayoutId!==0"
name="generateLabelButton"
id="generateLabelButton"
class="btn btn-primary pull-left"
ng-click="crud.generateLabel()"
ng-disabled="crud.isSaveButtonDisabled">
#Labels.generateLabel
</button>
<div class="pull-left generateLabelButton">
<data-desc:type ng-if="crud.model.lbLayoutId===0"
value="#Labels.generateLabel"
keep-pristine="true"
on-after-selection="crud.layoutSelected(selectedValue)"
title="{{ '#string.Format(Labels.selectX, Labels.labelLayout)'}}"
param="layouts"
message="#string.Format(Labels.selectX, Labels.labelLayout)"
selected="crud.model.lbLayoutId"
descrip-value="descrip"
id="layoutPickerButton"
name="layoutPickerButton"
button-type="button"
type="7"
filter-by="Label"
description="crud.model.lbLayout">
</data-desc:type>
</div>
So, if I have lblLayoutId defined, I have my regular submit button and I press it and get my form submitted and all is well.
If I don't have the lblLayoutId defined (it's 0), I need to use a directive which has a template for a button, when I press it, it opens a modal form to pick the layout, etc.
So, my problem is that after I picked the layout, I need to submit my form so the label can appear.
I tried making the directive to be of type submit (button-type property), this didn't work.
I also tried the following code in the method which is executed by the button when value is selected:
rentalEquipmentsCrudController.prototype.layoutSelected = function (selectedValue) {
this.model.lbLayoutId = selectedValue;
$("#generateLabelButton").click();
}
rentalEquipmentsCrudController.prototype.generateLabel = function () {
if (this.model.lbLayoutId === 0) return;
this.jsItemsToPrint = "";
this.itemsToPrint = this.getItemsToPrint();
this.jsItemsToPrint = JSON.stringify(this.itemsToPrint);
angular.element($("#viewerIFrame").contents()
.find("#reportViewer_ReportViewer")).empty();
let actionPath = angular.element($("#reportViewer")).attr("action");
if (actionPath.slice(-3) !== "pdf") actionPath += "/Labels.pdf";
angular.element($("#reportViewer")).attr("action", actionPath);
this.showViewer = true;
};
The layoutSelected method is executed from my directive and the next code is executed by my regular button.
So, I'm at lost as how to make it work.
The role of forms in client-side AngularJS applications is different than in classical roundtrip apps, it is desirable for the browser not to translate the form submission into a full page reload. Instead post JSON data and receive JSON data responses. Go to the server for data, but not html/js/css etc.
Read AngularJS <form> Directive API Reference - Submitting a form and preventing the default action.
You don't want to combine ng-click with a button of type="submit", this will still cause the form to submit (non-programmatically). Instead, use type="button". Alternatively, you can keep type="submit" but add the ng-submit="crud.generateLabel()" to the form element
<form>
...
<button type="button" ng-click="crud.generateLabel()">...</button>
</form>
Alternatively:
<form ng-submit="crud.generateLabel()">
...
<button type="submit">...</button>
</form>

onsubmit not being called on an HTML form

I have the following form as part of my webpage:
<form id="collabAccess" onsubmit="submitCollabForm()" >
<div id="row-1">
<div class="two-col" id="email"><input type="text" placeholder="Enter email addresses separated by commas"/></div>
<div id="collabSelect" class="collab two-col styled-select">
<select id="collabaccess">
<option>Can Read</option>
<option>Can Write</option>
<option>Can Read & Write </option>
<option>Administrator </option>
</select>
</div>
</div>
<div id="message">
<textarea id="personalMessage" cols="154" rows="10" placeholder="Optional: include a personal message"></textarea>
</div>
<div id="submit-wrapper"><input type="submit" value="Add Collaborators" id="addCollaborators" disabled='disabled' class="small-btn disabled"/></div>
</form>
The function submitCollabForm() is as follows:
function submitCollabForm() {
console.log('in submitCollabForm');
var valid = validateEmails();
if (valid == false) {
var email = document.getElementById('email');
email.addClass('error');
}
}
where validateEmails() is just another js function for validating that the email addresses int he form have the correct format.
However, it looks like onsubmit is not being called at all. Even if I change things to onsubmit="console.log('xyz'), no console statement is being output. I've also checked for javascript errors in the console, but I am getting nothing.
Is there any reason why onsubmit is not working properly?
Your validation function needs to return false to stop the form from submitting. It's better to have
onsubmit="return submitCollabForm()"
See With form validation: why onsubmit="return functionname()" instead of onsubmit="functionname()"? for details.
The onsubmit handler is not called, because the form cannot be submitted by any normal means, i.e. the submit event cannot be caused. There is only one submit control, and it is declared as disabled.
if you feel all code is correct still it's not working then,
Simple steps to do,
1) create one script tag in the same page where your form is, create one function and set one alert and test it. If it is working then try following steps.
2) Try to check the path of your javascript file.
3) if path is correct, then change the name of your javascript function sometimes your name tag conflicts with your function name, and submit points to it, so your call is not reaching at your function. It happened with me. so I posted it here, hope it will be helpful to someone.

How do I disable a button in an ng-include when a form in a sibling ng-include is $invalid?

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');
}
}

Using Javascript to submit forms

EDIT: For some reason if I change the input into an , the submit code works fine. Ok, this works, I'll just style the a tag to look like an input tag in css.
I am using a jQuery function to submit a form when a certain button is pressed, however this seems to have no effect on the form.
My code is as follows:
HTML:
<form id="loginForm" action="" method="POST">
<input class="loginInput" type="hidden" name="action" value="login">
<input id="step1a" class="loginInput" type="text" name="username">
<input id="step2a" class="loginInput" type="password" name="password" style="display:none;">
<input id="step1b" class="loginSubmit" onclick="loginProceed();" type="button" name="submit" value="Proceed" title="Proceed" />
<input id="step2b" class="loginSubmit" onclick="submitlogin();" type="button" value="Validate" title="Validate" style="display:none;" />
</form>
Javascript:
function submitlogin()
{
$("#loginForm").submit();
}
function loginProceed()
{
$("#step1a").fadeOut("slow",function(){
$("#step2a").fadeIn("slow", function(){
$("#step2a").focus();
});
});
$("#step1b").fadeOut("slow",function(){
$("#step2b").fadeIn("slow");
});
$("#step1c").fadeOut("slow",function(){
$("#step2c").fadeIn("slow");
});
}
However, when I press the button, absolutely nothing occurs.
PS. This function may seem meaningless since I can just use a input type="submit" but I originally intended this to have some more functionality, I stripped the function to its bare bones for testing purposes.
Try to use another name for input with name="submit". Without this it works fine for me.
You need to specify one form.
$("#loginForm").submit();
EDIT: Additional information added to question. You appear to be calling the wrong function. The submit button that is not display:none calls loginProceed() not submitlogin().
Also, if the functions are defined within jQuery's ready() function, they will be out of scope unless you define them as global.
Live example: http://jsfiddle.net/eSeuH/
Updated example: http://jsfiddle.net/eSeuH/2/
If the code you noted in the comment runs before the DOM is loaded, it will not work. You need to ensure that it does not run until the DOM has loaded (or at least the element it references has loaded).
$(document).ready(function() {
$("#loginForm").submit(function() { alert("clicked"); });
});
Additionally, your action attribute in your form tag is empty. What do you expect to happen when the form is submitted?
Try look in to Firefox debug console. Maybe you have errors in javascripts???
Because even if action is empty, all works.
For some reason if I change the input into an , the submit code works fine. Ok, this works, I'll just style the a tag to look like an input tag in css.
There's no jquery 'submit' method (not for ajax, at least): http://api.jquery.com/category/ajax/
You probably want to invoke form's submit method:
$("#loginForm")[0].submit();
Remember, jquery selector always returns array.
edit
'submit' will actually bind handler to submit event, not submit form:
http://api.jquery.com/submit/

Is there a better jQuery solution to this.form.submit();?

I want to trigger the submit event of the form the current element is in. A method I know works sometimes is:
this.form.submit();
I'm wondering if there is a better solution, possibly using jQuery, as I'm not 100% sure method works in every browser.
Edit:
The situation I have is, as follows:
<form method="get">
<p><label>Field Label
<select onchange="this.form.submit();">
<option value="blah">Blah</option>
....
</select></label>
</p>
</form>
I want to be able to submit the form on change of the <select>.
What I'm looking for is a solution that works on any field within any form without knowing the id or name on the form. $('form:first') and $('form') won't work because the form could be the third on the page. Also, I am using jQuery on the site already, so using a bit of jQuery is not a big deal.
So, is there a way to have jQuery retrieve the form the input/select/textarea is in?
I think what you are looking for is something like this:
$(field).closest("form").submit();
For example, to handle the onchange event, you would have this:
$(select your fields here).change(function() {
$(this).closest("form").submit();
});
If, for some reason you aren't using jQuery 1.3 or above, you can call parents instead of closest.
this.form.submit();
This is probably your best bet. Especially if you are not already using jQuery in your project, there is no need to add it (or any other JS library) just for this purpose.
I have found that using jQuery the best solution is
$(this.form).submit()
Using this statement jquery plugins (e.g. jquery form plugin) works correctly and jquery DOM traversing overhead is minimized.
Similar to Matthew's answer, I just found that you can do the following:
$(this).closest('form').submit();
Wrong: The problem with using the parent functionality is that the field needs to be immediately within the form to work (not inside tds, labels, etc).
I stand corrected: parents (with an s) also works. Thxs Paolo for pointing that out.
You can always JQuery-ize your form.submit, but it may just call the same thing:
$("form").submit(); // probably able to affect multiple forms (good or bad)
// or you can address it by ID
$("#yourFormId").submit();
You can also attach functions to the submit event, but that is a different concept.
Your question in somewhat confusing in that that you don't explain what you mean by "current element".
If you have multiple forms on a page with all kinds of input elements and a button of type "submit", then hitting "enter" upon filling any of it's fields will trigger submission of that form. You don't need any Javascript there.
But if you have multiple "submit" buttons on a form and no other inputs (e.g. "edit row" and/or "delete row" buttons in table), then the line you posted could be the way to do it.
Another way (no Javascript needed) could be to give different values to all your buttons (that are of type "submit"). Like this:
<form action="...">
<input type="hidden" name="rowId" value="...">
<button type="submit" name="myaction" value="edit">Edit</button>
<button type="submit" name="myaction" value="delete">Delete</button>
</form>
When you click a button only the form containing the button will be submitted, and only the value of the button you hit will be sent (along other input values).
Then on the server you just read the value of the variable "myaction" and decide what to do.
In JQuery you can call
$("form:first").trigger("submit")
Don't know if that is much better. I think form.submit(); is pretty universal.
<form method="get">
<p><label>Field Label
<select onchange="this.form.submit();">
<option value="blah">Blah</option>
....
</select>
</label>
</p>
**<!-- <input name="submit" type="submit" /> // name="submit_new_name" -->**
</form>
<!--
this.form.submit == this.form.elements['submit'];
-->

Categories

Resources