Checking which submit button was clicked - forms

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.

Related

How to have one form with multiple actions

I have one doubt is it possible to have a single form(view page) with multiple actions like i want to save,update and delete on the same view page..if the user click on anyof the button then it have to call on a necessary controller function is it possible??
You have some ways to do it, but all of the them require some javascript code.
The easiest I can think of is to dynamically change the form action when clicking each button (of type button, not submit which is the default), and then submit the form.
Example:
<form id="myform" name="myform" method="post" action="">
<input id="myinput" name="myinput" type="text"/>
[..]other inputs[/..]
<button type="button" onClick="deleteAction()">DELETE</button>
<button type="button" onClick="updateAction()">UPDATE</button>
<button type="button" onClick="saveAction()">SAVE</button>
</form>
Where the JS functions are:
function deleteAction() {
changeActionAndSubmit('/action/delete');
}
function updateAction() {
changeActionAndSubmit('/action/update');
}
function saveAction() {
changeActionAndSubmit('/action/save');
}
function changeActionAndSubmit(action) {
document.getElementById('myform').action = action;
document.getElementById('myform').submit();
}
Hope I got your doubt and that this solves your issue :)
A non-JS way to achieve the same goal would be to use the name/value parameters on each button to have your backend decide what to do.
Example
<?php echo form_open('controller/method'); ?>
// form fields go here
<button type="submit" name="add" value="y">press to add</button>
<button type="submit" name="update" value="y">press to update</button>
<button type="submit" name="delete" value="y">press to delete</button>
<?php echo form_close(); ?>
then, on your controller, after validating user input, you can determine which button was pressed by reading what the buttons send about themselves to the controller (I'll assume you use CI's form helper)
if ($this->input->post('add') == 'y')
{
// the user wants to add
}
else if ($this->input->post('update') == 'y')
{
// user wants to update
}
else
{
// user wants to delete
}
// rest of code goes here
on each if structure, you can take the appropriate actions depending on which button the user pressed

Form gets invalid after form.reset() - Angular2

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!

In Redux, how to get user input

I have a form, how to get the use input in the handleSubmit() method?
handleSubmit(e) {
e.preventDefault()
//how to get the user input?
}
render() {
return (
<div className="col-sm-4">
<form onSubmit={this.handleSubmit}>
<input type="text" placeholder="user"/>
<input type="text" placeholder="comments"/>
<input type="submit" hidden/>
</form>
</div>
)
}
so far, I know three solutions:
The first one, use refs, but I can see there are lots of people saying that we should avoid using it
The second one, add onChange() to each <input>, e.g.
class Example extends React.Component {
state = {
inputValue: ""
};
handleInputChanged(e) {
this.setState({
inputValue: e.target.value
});
}
render() {
return (
<div>
<input onChange={this.handleInputChanged.bind(this)} value={this.state.inputValue}>
</div>
);
}
}
this one is fine with a few inputs. But if the form has 20 input fields, then there are 20 different onChange methods?
third, use some npm module, like redux-form.
any other suggestion? Thanks
You can actually just do an onChange on the parent form like so:
onChange(e) {
switch(e.target.type) {
case 'checkbox':
this.setState({ [e.target.name]: e.target.checked });
break;
default:
this.setState({ [e.target.name]: e.target.value });
break;
}
}
// in render
<form onChange={this.onChange.bind(this)}>
<input name="foo1" />
<input name="foo2" />
<input name="foo3" />
<input name="foo4" />
<input name="foo5" />
<input name="foo6" />
<input name="foo7" />
<input name="foo8" />
</form>
There are certain libraries like https://github.com/christianalfoni/formsy-react, https://github.com/prometheusresearch/react-forms. These forms have additional functions pre written for form submitting, validations. I think using refs is a tedious and unwanted task if the form is big with the reason being that if it is controlled form you need to access the state value for controlled components which brings unnecessary complications. You can do it but it is better to use prewritten libraries.

Proper way of clearing forms without redux-form

This is my form
<form className="input-group" onSubmit={this.handleSubmit}>
<input className="form-control"
type="text"
placeholder="Insert name"
autofocus="true" />
<span className="input-group-btn">
<button type="submit" className={classNames}>Add</button>
</span>
</form>
This is my event handler:
handleSubmit(e) {
e.preventDefault();
let name = e.target[0].value;
if (name.length > 0) {
this.props.dispatch(createClassroom(name));
}
}
My question is:
what's the proper "redux way" to clearing the form after submitting it?
Do I need to dispatch a different action or should I use the existing createClassroom action?
Note: I'd rather not use redux-form package.
First, you have to make sure that the <input> is a controlled component by passing its respective value from the state:
const { classroom } = this.props;
// in return:
<input type="text" value={ classroom.name } />
Then, the form can be cleared by ideally submitting a RESET action that your classroom reducer acts upon:
const initialState = {};
function classroomReducer(state = initialState, action) {
switch (action.type) {
// ...
case 'RESET_CLASSROOM':
return initialState;
default:
return state;
}
}

HTML form doesn't submit after successful AJAX validation

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.