So I ran into issue, that If i click fast enough subnmit button, my form is submited several times. How can I prevent this? Token is added automatically, but it doesnt help at all I guess.
Form example:
<div class="row padding-10">
{!! Form::open(array('class' => 'form-horizontal margin-top-10')) !!}
<div class="form-group">
{!! Form::label('title', 'Title', ['class' => 'col-md-1 control-label padding-right-10']) !!}
<div class="col-md-offset-0 col-md-11">
{!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>
</div>
<div class="form-group">
{!! Form::label('body', 'Body', ['class' => 'col-md-1 control-label padding-right-10']) !!}
<div class="col-md-offset-0 col-md-11">
{!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
</div>
<div class="col-md-offset-5 col-md-3">
{!! Form::submit('Submit News', ['class' => 'btn btn-primary form-control']) !!}
</div>
{!! Form::close() !!}
</div>
My NewsController store method:
public function store()
{
$validator = Validator::make($data = Input::all(), array(
'title' => 'required|min:8',
'body' => 'required|min:8',
));
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput();
}
News::create($data);
return Redirect::to('/news');
}
One approach is to use a click handler for the button where it first disables the button, then submits the form.
<script>
function submitForm(btn) {
// disable the button
btn.disabled = true;
// submit the form
btn.form.submit();
}
</script>
<input id="submitButton" type="button" value="Submit" onclick="submitForm(this);" />
Use PHP sessions to set a session variable (for example $_SESSION['posttimer']) to the current timestamp on post. Before actually processing the form in PHP, check if the $_SESSION['posttimer'] variable exists and check for a certain timestamp difference (IE: 2 seconds). This way, you can easily filter out multiple submits.
// form.html
<form action="foo.php" method="post">
<input type="text" name="bar" />
<input type="submit" value="Save">
</form>
// foo.php
if (isset($_POST) && !empty($_POST))
{
if (isset($_SESSION['posttimer']))
{
if ( (time() - $_SESSION['posttimer']) <= 2)
{
// less then 2 seconds since last post
}
else
{
// more than 2 seconds since last post
}
}
$_SESSION['posttimer'] = time();
}
Original POST
How to prevent multiple inserts when submitting a form in PHP?
Want to submit value of button as well and prevent double form submit?
If you are using button of type submit and want to submit value of button as well, which will not happen if the button is disabled, you can set a form data attribute and test afterwards.
// Add class disableonsubmit to your form
$(document).ready(function () {
$('form.disableonsubmit').submit(function(e) {
if ($(this).data('submitted') === true) {
// Form is already submitted
console.log('Form is already submitted, waiting response.');
// Stop form from submitting again
e.preventDefault();
} else {
// Set the data-submitted attribute to true for record
$(this).data('submitted', true);
}
});
});
Step 1: write a class name in the form tag Exp: "from-prevent-multiple-submits"
<form class="pt-4 from-prevent-multiple-submits" action="{{ route('messages.store') }}" method="POST">
#csrf
Step 2: write a class in button section
<button type="submit" id="submit" class="btn btn-primary from-prevent-multiple-submits">{{ translate('Send') }}</button>
Step 3: write this script code
(function(){
$('.from-prevent-multiple-submits').on('submit', function(){
$('.from-prevent-multiple-submits').attr('disabled','true');
})
})();
Related
EDIT:
Your solutions are working for text inputs and textareas, but checkboxes are not working correctly for me.
This was my original checkbox:
{{ Form::checkbox('active', true, (isset($user->active)) ? old($user->active) : true, ['class' => 'custom-control-input', 'id' => 'active']) }}
I've tried a lot of possible solutions like adding old('active', isset($user) ? $user->active: true) instead, but when an error occurs I lose the values from this input. On the controller I was checking this, but if I change the input to the 'new solution' active is always false on my db:
if(!array_key_exists('active', $validated)){
$validated = array_add($validated, 'active', '0');
}
ORIGINAL QUESTION (PARTIALLY RESOLVED):
I have one blade view call edit with two forms, but each one is calling his own method/route. One form is for edit/store the user and the other is a form in a modal to change the user password. When I change the password and no validation error happens, the other form still has all of his values that is getting from old() or $user variable via index method. But if for example the passwords do not match, a validation error occurs, and the values from the edit/store user form disappear.
Forms are pretty simple (remember, they are on the same view, and the one that is giving me problems is the edit/create one), and each one call a different method from UserController
Form 1 for edit users (simplified)
#if($user->exists)
{{ Form::model($user, ['route' => ['users.update', $user], 'class' => 'needs-validation', 'novalidate'=>'']) }}
#method('PATCH')
#else
{{ Form::model($user, ['route' => ['users.store'], 'class' => 'needs-validation', 'novalidate'=>'']) }}
#method('POST')
#endif
#csrf
<div class="form-group">
<div class="row">
<div class="col-sm-4">
{{ Form::label('cif', __('users.cif'), ['class' => 'form-label']) }}
{{ Form::text('cif', (isset($user->cif)) ? old($user->cif) : '', ['class' => 'form-control', 'required','maxlength'=>'12', 'minlength'=>'9']) }}
{{ Form::hidden('validate','', ['class' => 'form-control', 'required', 'id'=>'validate']) }}
</div>
<div class="col-sm-6">
{{ Form::label('name', __('users.name'), ['class' => 'form-label']) }}
{{ Form::text('name', (isset($user->name)) ? old($user->name) : '', ['class' => 'form-control','required','maxlength'=>'255']) }}
</div>
<div class="col-sm-2">
{{ Form::label('initials', __('users.initials'), ['class' => 'form-label']) }}
{{ Form::text('initials', (isset($user->initials)) ? old($user->initials) : '', ['class' => 'form-control', 'required','maxlength'=>'5']) }}
</div>
</div>
<div class="col-sm-6">
{{ Form::label('province', __('users.province'), ['class' => 'form-label']) }}
{{ Form::text('province', (isset($user->city)) ? $user->city->province->name : '', ['class' => 'form-control', 'disabled'=>'']) }}
</div>
{!! Form::close() !!}
Form 2: Update password
<form id="change-password" action="{{route('users.change.password', $user)}}" method="POST">
#csrf
<div class="modal-body">
<div class="card-body">
<div class="panel-tag">
<p>Las contraseñas debe de coincidir y tener más de 8 carácteres</p>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">Contraseña</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control #error('password') is-invalid #enderror" name="password" required autocomplete="new-password" minlength="8">
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirmation" class="col-md-4 col-form-label text-md-right">Confirmar contraseña</label>
<div class="col-md-6">
<input id="password-confirmation" type="password" class="form-control #error('password') is-invalid #enderror" name="password_confirmation" required autocomplete="new-password" minlength="8">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button id="change" type="submit" form="change-password" class="btn btn-primary">Confirmar</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
</div>
</form>
UserController I'm going to paste two methods, one for store/user, the other for change the password. Update method is very similar.
public function store(StoreUserRequest $request)
{
if( $request['validate'] == 1 ){
$validated = $request->validated();
$validated['password'] = Hash::make($validated['password']);
$id = DB::table('users')->insertGetId($validated);
return redirect()->route('users.edit',['user'=>$id])->with('status', 'created');
} else {
return redirect()->back()->withInput()->with('status', 'error_dni');
}
}
public function changePassword(PasswordUserRequest $request, User $user)
{ // HERE IS WHERE I THINK IS THE PROBLEM, IF VALIDATION FAILS (FOR EXAMPLE PASSWORD CONFIRM) VALUES FROM THE OTHER FORM DISAPPEAR AND IT DOESNT GET INTO THIS METHOD
$pass = Hash::make($request->password);
$user->password = $pass;
$action = $user->save();
if ($action) {
return redirect()->back()->with('status', 'change_password_ok');
}
return redirect()->back()->with('status', 'error_change_password');
}
PasswordUserRequest This is the request to validate the password form
public function rules()
{
return [
'password' => 'required|string|confirmed';
];
}
The route would be something like:
users/{user}/edit
I've spent all day trying to fix this and still didn't found a solution. My english is not very good so please tell me if I'm not explaining something correctly and I will edit the question.
Thanks and hope that I can find a solution.
old values are from input name
<input type="text" name="input" value="{{old('input')}}"
example
<div class="col-sm-4">
{{ Form::label('cif', __('users.cif'), ['class' => 'form-label']) }}
{{ Form::text('cif', old('cif', $user->cif ?? ''), ['class' => 'form-control', 'required','maxlength'=>'12', 'minlength'=>'9']) }}
{{ Form::hidden('validate','', ['class' => 'form-control', 'required', 'id'=>'validate']) }}
</div>
//$user->cif ?? '' <- left or right hand-side operand, return right-hand if left is null or undefined
//old('input', $user->cif ?? '') <- if old input available, use old input, if not, $user will be displayed
form::checkbox:
First argument : name
Second argument : value
Third argument : checked or not checked (true or false)
Fourth argument : additional attributes
note that value is attribute(value) and checked is attribute(checked)
then
{{ Form::checkbox('active', true, (isset($user->active)) ? $user->active : true, ['class' => 'custom-control-input', 'id' => 'active']) }}
//2nd parameter (true) will always set checkbox value to 1(true)
//(isset($user->active)) ? $user->active : true <- will set default to true (checked) if $user is null or undefined
//maybe try
{{ Form::checkbox('active', $user->active ?? false, $user->active ?? false) }}
//if $user != null, put $user->active else put false
//if $user != null, set checked value based on $user->active else put false
in html looks like this
<input type="checkbox" value="1" checked="checked">
then you need to add inline event onchange="$(this).is(':checked') ? $(this).val(1) : $(this).val(0);" in the 4th parameter of form::checkbox to change the default on runtime
If I understood all correctly, you should do this way:
old('name', isset($user) ? $user->name : ''),
Here you trying to get old name input, and if it doesn't exist, in second parameter od old function you are getting default value, which is user's name in case of user exists
There is documentation, which can help you to understand much more.
i want to add new law details with a form, this form has two buttons like update and cancel.
when i hit on cancel button the form gets cancelled and is redirected to previous page, and when i hit update button without filling form details it asks for validation.
after filling all required details of form, when i hit update button it throws me error as MethodNotAllowedHttpException in RouteCollection.php line 218:
my form is this:
{!! Form::open(array('url' => 'admin/companymaster/updateLocation', 'id'=>'updatelocations', 'class' => 'form-horizontal create_form', 'files' => true)) !!}
<input type="hidden" value="{{$value->id}}" name="company_master_id">
<div id="sublaws_content1"></div>
<div id="save" style="display:none; margin-bottom: 20px;">
<button type="submit" class="btn btn-success" id="senddatepicker">Update</button>
<a class="btn red" href="{{ URL::to('admin/companymaster/'.$company_master->id) }}">Cancel</a>
</div>
</form>
my route is:
Route::post('admin/companymaster/updatelocations', 'CompanyController#updateLocation');
my controller is:
public function updateLocation(){
//dd(Input::all());
/*Insert Company Law Details*/
$companydetails_id = Input::get('company_master_id');
$company_sub_laws = Input::get('company_sub_laws');
if($company_sub_laws!="")
{
$cld=0;
foreach($company_sub_laws as $rescompany_sublaws)
{
if($companydetails_id!="" && $rescompany_sublaws!="")
{
$law_reg_no = $_POST['law_reg_no'];
$sub_law_start_date = $_POST['sub_law_start_date'][$cld];
$sub_law_end_date = $_POST['sub_law_end_date'][$cld];
$companylawdetails = new CompanyLawDetails;
$companylawdetails->company_master_details_id = $companydetails_id;
$companylawdetails->company_sub_law_id = $rescompany_sublaws;
$companylawdetails->law_reg_no = $law_reg_no;
$company_sub_law_start_date = $sub_law_start_date;
$company_sub_law_end_date = $sub_law_end_date;
if($company_sub_law_end_date!="")
{
$res_company_sub_law_end_date=explode("-",$company_sub_law_end_date);
$company_sub_law_end_date=$res_company_sub_law_end_date[2]."-".$res_company_sub_law_end_date[1]."-".$res_company_sub_law_end_date[0];
$companylawdetails->law_end_date = $company_sub_law_end_date;
}
if($company_sub_law_start_date!="")
{
$res_company_sub_law_start_date=explode("-",$company_sub_law_start_date);
$company_sub_law_start_date=$res_company_sub_law_start_date[2]."-".$res_company_sub_law_start_date[1]."-".$res_company_sub_law_start_date[0];
$companylawdetails->law_start_date = $company_sub_law_start_date;
}
$companylawdetails->save();
}
$cld++;
}
}
$sublaws = CompanyLawDetails::where('company_master_details_id',$companydetails_id)->select('company_sub_law_id')->get()->toArray();
$sublaws = join(",",array_column($sublaws,'company_sub_law_id'));
$update = CompanyDetails::where('id',$companydetails_id)->update(['company_sub_laws' => $sublaws]);
//return Redirect::back();
}
when i submit my form by clicking on update button i get an error page as:
can anyone help me out with this.?
It seems that you are going on the wrong route, and you have an error on url, try this way;
Route::post('admin/companymaster/updatelocations', ['uses'=>'CompanyController#updateLocation',
'as'=>'upload.locations']);
on your blade
{!! Form::open(array('route'=> 'upload.locations', 'method'=>'post', 'id'=>'updatelocations', 'class' => 'form-horizontal create_form', 'files' => true)) !!}
<input type="hidden" value="{{$value->id}}" name="company_master_id">
<div id="sublaws_content1"></div>
<div id="save" style="display:none; margin-bottom: 20px;">
<button type="submit" class="btn btn-success" id="senddatepicker">Update</button>
<a class="btn red" href="{{ URL::to('admin/companymaster/'.$company_master->id) }}">Cancel</a>
</div>
</form>
Please add form method as 'method' => 'post',
{!! Form::open(array('url' => 'admin/companymaster/updateLocation', 'id'=>'updatelocations', 'class' => 'form-horizontal create_form', 'files' => true,'method' => 'post')) !!}
Hope you understand.
Spelling error change your url form
{!! Form::open(array('url' => 'admin/companymaster/updateLocation', 'id'=>'updatelocations', 'class' => 'form-horizontal create_form', 'files' => true)) !!}
to
{!! Form::open(array('url' => 'admin/companymaster/updatelocations', 'id'=>'updatelocations', 'class' => 'form-horizontal create_form', 'files' => true)) !!}
I have a form in my application. I also have a view component that creates an input field using vue-google-maps.
I use this component within my but there is no name attribute so my server does not recognize a submitted value.
How can I submit the data from the input field to my server? I am using Laravel 5.3.
<template>
<place-input
:place.sync="placeInput.place"
:types.sync="placeInput.types"
:component-restrictions.sync="placeInput.restrictions"
class='form-control'
label='Location: '
name='location'
></place-input>
<pre>{{ placeInput.place | json }}</pre>
</template>
<script>
import { PlaceInput, Map } from 'vue-google-maps'
export default {
data() {
return {
placeInput: {
place: {
name: ''
},
types: [],
restrictions: {'country': 'usa'}
}
}
},
components: {
PlaceInput
},
ready() {
}
}
</script>
<style>
label { display: block; }
</style>
My Laravel form looks like this:
{!! Form::open(['action' => 'CandidateController#store']) !!}
<div class='form-group'>
{!! Form::label('email', 'Email:') !!}
{!! Form::email('email', null, ['class' => 'form-control']) !!}
</div>
<div class='form-group'>
{!! Form::label('phone', 'Phone:') !!}
{!! Form::text('phone', null, ['class' => 'form-control']) !!}
</div>
<div class='form-group'>
<location-input></location-input>
</div>
{!! Form::close() !!}
Where location-input is the vue-google-maps component that generates an input.
When I submit the form and dump the data to the screen no location data is available!
on server
$input = Request::all();
dd($input);
The raw input looks like this (the name attribute on the component does not add to the input field):
How do I submit the location-input data along with my form?
I'd still like to see your generated html but I think the problem is that there's no name attribute on the input you're creating. Thus, it's not part of the posted data.
<place-input
:place.sync="placeInput.place"
:types.sync="placeInput.types"
:component-restrictions.sync="placeInput.restrictions"
class='form-control'
name='location'
label='Location: '
></place-input>
I am not familiar with vue but what about sending your form through vue and adding manually adding the location to the ajax request? Something like
<form v-on:submit.prevent="onSubmit">
//Your form
</form>
and
methods: {
onSubmit: function (event) {
//You can ajax your form data + manually add your location-input from your component
}
}
Would that solve your problem?
I have an edit view and i am using a partial _form view.
Is there a way to check if the form is a patch or post?
What i plan to do is to change the hidden field in edit form
#if (form is post)
{!! Form::hidden('signature') !!}
#else
<div class="form-group">
{!! Form::label('signature', 'Signature: ', ['class' => 'col-md-4 control-label']) !!}
<div class="col-md-6">
{!! Form::text('signature', null, ['class' => 'col-md-2 form-control', 'required']) !!}
</div>
</div>
#endif
because this variable is already saved to DB and i want to load it for edit.
Or to check if form is post, that would work also!
I usually pass the variable to a view where I set action, like:
$action = 'store';
Then I use this variable to build route name:
{!! Form::open(['route' => 'post'.$action, ....
And detect what type of action is needed:
#if ($action == 'store')
I guess it's the most readable and simple way to achieve what you're trying to achieve. You can do something similar.
Try this:
$isPut= Request::isMethod('put');
if($isPut) {
//
}
I have a blade form in Laravel
{!! Form::open(array('url' => '/'.$cpe_mac.'/device/'.$device_mac.'/update', 'class' => 'form-horizontal', 'role' =>'form','method' => 'PUT')) !!}
<span class="pull-left">
<div class="col-sm-6">
<p>Downlink </p>
<select type="text" class="form-control" name="max_down" >
#foreach ($rate_limit as $key => $value)
<option value="{{$value or ''}}">{{$value or ''}} Kbps</option>
#endforeach
</select>
</div>
<div class="col-sm-6">
<p>Uplink</p>
<select type="text" class="form-control" name="max_up" >
#foreach ($rate_limit as $key => $value)
<option value="{{$value or ''}}">{{$value or ''}} Kbps</option>
#endforeach
</select>
</div>
</span><br>
{!! Form::hidden('cpe_mac', $cpe_mac)!!}
{!! Form::hidden('device_mac', $device_mac)!!}
<span class="pull-right">
<button class="saveRateLimitBTN btn btn-xs btn-info pull-right">Save</button>
</span>
{!! Form::close();!!}
I want to be make a Ajax HTTP PUT without refresh my page.
How should my form look like ?
Right now, it keep redirecting me to url/update, and then redirecting it back.
How do I send all those data to my controller in the background ?
Any hints / suggestion on this will be a huge helps !
Usually I place my forms in a modal popup with a data-dismiss button that will simply close after you hit submit and run everything in the background.
For your case, after hitting submit without refreshing the page after hitting the submit button would seem a bit odd wouldn't it?
However here's a bit of jQuery to get you going either way:
$("#mySubmitButton").on('click', function(event){
var form = '#myForm';
$.post($(form).attr('action'),$(form).serialize());
});
Add an ID to your form:
{!! Form::open(array('url' => '/'.$cpe_mac.'/device/'.$device_mac.'/update', 'class' => 'form-horizontal', 'role' =>'form','method' => 'PUT', 'id' => 'myForm')) !!}
Add an ID to your button:
<button id="mySubmitButton" class="saveRateLimitBTN btn btn-xs btn-info pull-right">Save</button>
Add a TYPE to your button (to prevent it from submitting/refreshing);
<button type="button" id="mySubmitButton" class="saveRateLimitBTN btn btn-xs btn-info pull-right">Save</button>
If your routes are properly setup to lead to your controller then all your form input variables are now accessible via $request or Input:
public function processForm(Request $request)
{
$variable1 = $request->input('myforminputname1');
$variable2 = $request->input('myforminputname2');
// Or get it through Input
$variable1 = \Input::get('myforminputname1');
$variable2 = \Input::get('myforminputname2');
}