I have a simple HTML form that uses uses ajax in part of the validtion. the ajax works correctly and display errors correctly, but if all validation passes, the form doesn't submit. Basically, nothing happens. Nothing happens in Firebug, nothing happens on the page itself, etc. This is the Javascript that's called to validate the form:
var pass_form = $('#pass_form');
pass_form.submit( valid_pass_sett );
function valid_pass_sett() {
$('.caption_error').remove();
$('input').removeClass('error');
pass_old = $('input[name=pass_old]').val();
pass_new = $('input[name=pass_new]').val();
pass_confirm_new = $('input[name=pass_confirm_new]').val();
if (pass_old === "") {
//display error on form - snipped
return false;
} else if (pass_new === "") {
//display error on form - snipped
return false;
} else if (pass_new != pass_confirm_new) {
//display error on form - snipped
return false;
} else if (pass_new.length < 8) {
//display error on form - snipped
return false;
} else {
$.post("http://www.example.com/ajax/validate.php",{ // async validation
type: 'valid_old_change_pass',
pass_old: pass_old,
pass_new: pass_new
}, valid_pass_combo_callback);
}
return false; // cancel form submission
}
function valid_pass_combo_callback( data ) {
if (data == 'valid') {
//only if the form is valid!
pass_form[0].unbind('submit').submit();
//pass_form[0].submit();
} else if (data == "invalid_old") {
//display error on form - snipped
}
else if (data == "invalid_new") {
//display error on form - snipped
}
else {
//display error on form - snipped
}
}
and here's the basic HTML code for the form:
<form id="pass_form" class="standard" method="post" action="http://www.example.com/preferences" onsubmit="return valid_pass_sett()">
<fieldset>
<div>
<label for="pass_old">Old password:</label>
<input type="password" id="pass_old" name="pass_old" />
</div>
<div>
<label for="pass_new">New password:</label>
<input type="password" id="pass_new" name="pass_new" />
</div>
<div>
<label for="pass_confirm_new">Confirm new password:</label>
<input type="password" id="pass_confirm_new" name="pass_confirm_new" />
</div>
<div>
<label></label>
<input type="submit" id="pass_submit" name="pass_submit" value="Change password"/>
<input type="reset" id="pass_reset" name="pass_reset" value="Cancel"/>
</div>
</fieldset>
</form>
The script makes it all the way to the pass_form[0].unbind('submit').submit(); line, but then the form doesn't submit. Any help here?
Change the below line in your callback method valid_pass_combo_callback
//Replace this line
pass_form[0].unbind('submit').submit();
//By this
pass_form.unbind('submit').submit();
I decided to forgo binding this function to submit, and instead bound to an onclick event for a button on the form (which I'm using in place of a submit button) and that solved the problem. Validation is called when the button is clicked, and if client-side validation passes, then the form is submitted to the server for validation there.
Related
I'm quite new to Angular, and I've already searched the web, without finding a correct solution for my situation.
I have a dynamic form created by a *ngFor. I need to disabled the submit button if the inputs are all empty and show the alert div; but I need to enable the submit if at least one of those forms contains something different from ''.
Here is my html code
<form class="form-inline" #form="ngForm">
<div class="form-group" *ngFor="let meta of state.metaById; let i = index" style="margin: 5px">
<label>{{meta.nome}}</label>
<input type="text" class="form-control" #nome (blur)="inputInArray(nome.value, i);">
</div>
<button type="button" class="btn btn-primary" (click)="getCustomUnitaDocumentaliRow(this.param)" [disabled]="fieldNotCompiled">invia</button>
</form>
<div class="alert-notification" [hidden]="!fieldNotCompiled">
<div class="alert alert-danger">
<strong>Va compilato almeno un campo.</strong>
</div>
</div>
and here is my Typescript code
inputInArray(nome: string, indice) {
if (this.state.controlloMetaId = true) {
this.state.metadatoForm[indice] = nome;
}
// this.fieldNotCompiled = false;
for (const i in this.state.metaById) {
console.log(this.state.metadatoForm);
if (isUndefined(this.state.metadatoForm[i]) || this.state.metadatoForm[i] === '') {
this.fieldNotCompiled = true && this.fieldNotCompiled;
} else {
this.fieldNotCompiled = false && this.fieldNotCompiled;
}
console.log(this.fieldNotCompiled);
}
With this code I can check the first time a user type something in one input, but it fails if it empty one of them (or all of them)
Thanks for your time
UPDATE
Check if any input got a change that is different from empty or space, just by doing:
<input ... #nome (input)="fieldNotCompiled = !nome.value.trim()" ....>
DEMO
You can set a listener to the form changes:
#ViewChild('form') myForm: NgForm;
....
ngOnInit() {
this.myForm.valueChanges.subscribe((value: any) => {
console.log("One of the inputs has changed");
});
}
I have a template based form in my Angular2 app for user registration. There, I am passing the form instance to the Submit function and I reset the from once the async call to the server is done.
Following are some important part from the form.
<form class="form-horizontal" #f="ngForm" novalidate (ngSubmit)="onSignUpFormSubmit(f.value, f.valid, newUserCreateForm, $event)" #newUserCreateForm="ngForm">
<div class="form-group">
<label class="control-label col-sm-3" for="first-name">First Name:</label>
<div class="col-sm-9">
<input type="text" class="form-control" placeholder="Your First Name" name="firstName" [(ngModel)]="_userCreateForm.firstName"
#firstName="ngModel" required>
<small [hidden]="firstName.valid || (firstName.pristine && !f.submitted)" class="text-danger">
First Name is required !
</small>
</div>
</div>
.......
.......
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="submit" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
</form>
In my component file, I have written following function.
onSignUpFormSubmit(model: UserCreateForm, isValid: boolean, form: FormGroup, event:Event) {
event.preventDefault();
if (isValid) {
this._userEmail = model.email;
this._authService.signUp(this._userCreateForm).subscribe(
res => {
console.log("In component res status = "+res.status);
if(res.status == 201){
//user creation sucess, Go home or Login
console.log("res status = 201");
this._status = 201;
}else if(res.status == 409){
//there is a user for given email. conflict, Try again with a different email or reset password if you cannot remember
this._status = 409;
}else{
//some thing has gone wrong, pls try again
this._serverError = true;
console.log("status code in server error = "+res.status);
}
form.reset();
alert("async call done");
}
);
}
}
If I submit an empty form, I get all validations working correctly. But, when I submit a valid form, Once the form submission and the async call to the server is done, I get all the fields of the form invalid again.
See the following screen captures.
I cannot understand why this is happening. If I comment out form.reset(), I do not get the issue. But form contains old data i submitted.
How can I fix this issue?
I solved this By adding these lines:
function Submit(){
....
....
// after submit to db
// reset the form
this.userForm.reset();
// reset the errors of all the controls
for (let name in this.userForm.controls) {
this.userForm.controls[name].setErrors(null);
}
}
You can just initialize a new model to the property the form is bound to and set submitted = false like:
public onSignUpFormSubmit() {
...
this.submitted = false;
this._userCreateForm = new UserCreateForm();
}
You need to change the button type submit to button as following.
<div class="form-group">
<div class="col-sm-offset-3 col-sm-12">
<button type="button" class="btn btn-default">Submit</button>
<button type="reset" class="btn btn-link">Reset</button>
</div>
</div>
Reseting the form in simple javascript is the solution for now.
var form : HTMLFormElement =
<HTMLFormElement>document.getElementById('id');
form.reset();
this is how finally I had achieved this. I am using Angular5.
I have created a form group named ="firstFormGrop".
If you are not using form groups you can name the form as follow:
<form #myNgForm="ngForm">
In the html doc:
<form [formGroup]="firstFormGroup">
<button mat-button (click)='$event.preventDefault();this.clearForm();'>
<span class="font-medium">Create New</span>
</button>
</form>
In the .ts file:
this.model = new MyModel();
this.firstFormGroup.reset();
if you where using #myNgForm="ngForm then use instead:
myNgForm.reset();
// or this.myNgForm.reset()
This is a very common issue that after clicking the reset button we created the validators are not reset to its initial state, and it looks ugly.
To avoid that we have two options,the button is outside the form, or we prevent the submission when the button is tagged inside the form.
To prevent this default behaviour we need to call $event.preventDefault() before whatever method we are choosing to clear the form.
$event.preventDefault() is the key point.
The solution:
TEMPLATE:
<form
action=""
[formGroup]="representativeForm"
(submit)="register(myform)"
#myform="ngForm"
>
*ngIf="registrationForm.get('companyName').errors?.required && myform.submitted"
COMPONENT:
register(form) {
form.submitted = false;
}
Try changing the button type from "submit" to "button", e.g. :
<button type="button">Submit</button>
And move the submit method to click event of the button. Worked for me!
I am devoloping a web application using J2EE and Spring Roo as framework.
I want to create a form with two submit buttons:
One for save and continue
Another for save and finish
<form action="mycontroller" method="post">
<input type="submit" value="Save and continue"/>
<input type="submit" value="Save and finish"/>
</form>
So I can choose to either store the data in the database and add more entries or to store the data and finish the process.
How can I check what submit button was clicked in the method of the controller that processes the action?
public class MyController {
void actionMethod(...) {
// check which submit was clicked
}
}
You should add a name field to both buttons:
<input type="submit" name="button" value="Save and continue"/>
<input type="submit" name="button" value="Save and finish"/>
Once in the controller, you can recover the element by this name field and check its value field:
String field = request.getParameter("button");
if ("Save and continue".equals(button)){
// Do stuff
}
else if ("Save and finish".equals(button)){
// Do a different stuff
}
else {
// None of them were pressed
}
Or also you can use a different name value for both buttons:
<input type="submit" name="button1" value="Save and continue"/>
<input type="submit" name="button2" value="Save and finish"/>
In your controller:
String button1 = request.getParameter("button1");
String button2 = request.getParameter("button2");
if (button1 != null){
// Do stuff
}
else if (button2 != null){
// Do a different stuff
}
else {
// None of them were pressed
}
Second solution is preferred because it doesn't depend on the value of the elements
To reduce if-else if you can, and benefit from Spring framework to handle these mapping, try the following solution (if you don't have many meta parameters to send in the form):
<form action="AddToCartListController" method="post">
<input type="submit" value="Save and continue"/>
</form>
<form action="CommitCartListController" method="post">
<input type="submit" value="Save and finish"/>
</form>
...
public class CartListController {
void AddToCartListController(...) {
// business code
}
void CommitCartListController(...) {
// business code
}
}
// ... or ...
public class AddToCartListController {
void actionMethod(...) {
// business code
}
}
public class CommitCartListController {
void actionMethod(...) {
// business code
}
}
and define a proper mapping in Spring configuration.
I have a div element and I want that when I click on it i submit a form which is hidden.
div code
<div class="a15 training-exercise">
some text
<form accept-charset="UTF-8" action="/trainings/1/training_exercises/5" data-remote="true" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓"><input name="_method" type="hidden" value="put"></div>
<input id="training_exercise_done" name="training_exercise[done]" type="text" value="false">
<input name="commit" type="submit" value="subit">
</form>
</div>
coffescript
$ ->
$('.training-exercise').click ->
if $(this).hasClass('done')
$(this).removeClass('done')
$(this).find('input:text').val(false)
$(this).closest("form").submit()
else
$(this).addClass('done')
$(this).find('input:text').val(true)
$(this).closest('form').submit()
corresponding JS code
$(function() {
return $('.training-exercise').click(function() {
if ($(this).hasClass('done')) {
$(this).removeClass('done');
$(this).find('input:text').val(false);
return $(this).closest("form").submit;
} else {
$(this).addClass('done');
$(this).find('input:text').val(true);
return $(this).closest('form').submit;
}
});
});
i didn't put checkbox for true and false because f.checkbox gave me some strange results
The problem here is:
1) Everything is happening except form submitting
2) form has visibility: hidden; and it is hidden, but there is empty space where the form is, I want that it looks like there is nothing there
For 1st problem, try
$(function() {
$('.training-exercise').click(function() {
var element = $(this);
if (element.hasClass('done')) {
element.removeClass('done');
element.find('input:text').val(false);
element.closest('form').submit(); //<-- brackets here.
} else {
element.addClass('done');
element.find('input:text').val(true);
element.closest('form').submit();
}
});
});
For 2nd problem use display:none; instead of visibility:hidden.
It seems that form selecting didn't work (although it work when I tried from console)
The solution that works is:
$(this).find('input:submit').submit()
I'm using jQuery validation and trying to get the error message for a pair of radio buttons to show up before the first button.
Here is the validation:
errorPlacement: function(error, element) {
if (element.attr("type") == "radio")
error.insertBefore(element.first());
else
error.insertAfter(element);
}
Here is the html:
<div class="full">
<label id="sample">Have you received your sample pack?</label>
<input type="radio" name="sample" id="sample_yes" value="yes" />
<label for="eliteflexsample_yes">Yes</label>
<input type="radio" name="sample" id="sample_no" value="no" />
<label for="eliteflexsample_no">No</label>
</div>
Right now the error is showing up after the first radio button.
This is working:
$(document).ready(function() {
$('form').validate({
// your validation options,
errorPlacement: function(error, element) {
if (element.attr("type") == "radio") {
error.insertBefore(element);
} else {
error.insertAfter(element);
}
}
});
});
Working Demo:
http://jsfiddle.net/DR5Aw/2/