My Blade is:
{!! Form::open(['method' => 'PUT', 'id' => 'confirmTCU',
'action' => ['TournamentUserController#confirmUser', $tournament->slug, $categoryTournament->id,$user->slug ]]) !!}
It generates my Form:
<form method="POST" action="http://laravel.dev/tournaments/bisque/categories/1/users/admin/confirm" accept-charset="UTF-8" id="confirmTCU">
<input name="_method" type="hidden" value="PUT">
<input name="_token" type="hidden" value="tiaIHtctMbo1NwbEK8TqoKOyrN8ZSyeQELSyYL9A">
<button type="submit" class="btn btn-flat text-warning-600 btnConfirmTCU" id="confirm_bisque_1_admin" data-tournament="bisque" data-category="1" data-user="admin">
<i class="text-danger glyphicon glyphicon-remove-sign"></i>
</button>
</form>
My AJAX is:
$('.btnConfirmTCU').on('click', function (e) {
e.preventDefault();
$(this).prop("disabled", true);
var inputData = $('#formDeleteTCU').serialize();
//var tournamentSlug = $(this).data('tournament');
var categoryId = $(this).data('category');
var userSlug = $(this).data('user');
$.ajax(
{
type: 'PUT',
url: url + '/categories/' + categoryId + '/users/' + userSlug + '/confirm',
data: inputData,
success: function (data) {
...
},
error: function (data) {
...
}
}
)
});
My route is:
Route::put('tournaments/{tournamentId}/categories/{categoryTournamentId}/users/{userId}/confirm', 'TournamentUserController#confirmUser');
My Controller is:
public function confirmUser($tournamentSlug, $tcId, $userSlug)
{
$user = User::findBySlug($userSlug);
$ctu = CategoryTournamentUser::where('category_tournament_id', $tcId)
->where('user_id', $user->id)->first();
$ctu->confirmed ? $ctu->confirmed = 0 : $ctu->confirmed = 1;
$ctu->save();
return redirect("tournaments/$tournamentSlug/users");
}
I saw a lot of topics about it, but none resolved my issue.
As PUT is not allowed for most of browser, Laravel send it like POST, but includes a hidden field _method with PUT value.
Beside, I am able to perform DELETE actions, but not PUT...
Besides, method works perfect when not using AJAX.
Where is my problem???
Your code should work fine, but it looks like you are serializing the wrong form. Your current code shows var inputData = $('#formDeleteTCU').serialize();, but the id for the form you've shown is confirmTCU.
Change your ajax type from 'PUT' to 'POST', Laravel will read your parameter '_method' and will take that 'POST' like a 'PUT'.
Related
I have a div that has lots of posts which is created dynamically from the database. The div has input for comment facility as well. I have no problems in posting the comments and I do it using a POST method. Then I redirect to the page using return redirect('/'); method. But it links to the beginning to the page which doesn't create a good impression on the user. The user might be in the middle of the page and when he/she comments he will go to the beginning of the page and will have to scroll down again. Luckily, I have the divs with class equal to the post_id. So, isn't there any method to go to the post in which the user posted using that class?
attach the id with the url like /#post-id
Inside your contorller where you are processing and saving the comments:
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;
public function yourCommentSaveFunction()
{
...
//Get the Post ID and store in $postid
return Redirect::to(URL::previous() . '#' .$postid);
}
This should work fine.
But the best way would be to use AJAX to post comments.
Edit (As request by OP)
THE AJAX METHOD
Controller will be something like:
public function saveComment(Request $request)
{
//you do the saving part..
...
$comment = $request->comment;
//after saving the comment return a json response
//you can also send other varibales like username, created at etc..
return Response::json(array(
'success' => true,
'comment' => $comment,
));
}
Route:
Route::post('/save-comment', [
'as' => 'save-comment',
'uses' => 'yourController#saveComment',
]);
And your View:
<form action="{{ route('save-comment') }}" class="comment-form">
<input type="text" name="comment">
<input type="submit" name="submit">
<input type="hidden" name="_token" value="{{ csrf_token() }}"
<div class="comment"></div>
</form>
<script>
$('.comment-form').submit(function(event){
event.preventDefault();
var comment = $this.val();
var token = $('.token').val();
var $url = "{{ route('save-comment') }}";
$.ajax({
url: route,
type: 'POST',
data: {_token: token, comment: comment},
dataType: 'JSON',
success: function (data) {
$(".comment").append('<div class="new-comment">' +data.comment +'</div>');
},
error: function(data) {
console.log("Something went wrong");
}
});
});
</script>
Please note: this is just a sample code.
In my laravel 5.4 app, i have a crud module. for the edit bit, the data is rendered in a bootstrap modal. the data is pulled successfully but on hitting the update button, the error shown is returned.
here's my blade form that's rendered in the modal:
<form id="formEdit" class="form-horizontal" role="form" method="put">
//form elements
</form>
here's the ajax that handles it:
//edit_id is defined globally
$('#updateClass').click(function(){
var name = $("#formEdit #name").val();
var status = ($('#formEdit #status').prop("checked") == true) ? 1 : 0;
var token = $('meta[name="csrf-token"]').attr('content');
var id = edit_id;
var url = "classes/update/"+id;
var formdata = {
'name' : name,
'status' : status,
'_token' : token
};
$.ajax({
method: "PUT",
url: url,
data: formdata,
dataType: "json"
})
.done(function(data) {
//
})
.fail(function(data) {
//
});
});
});
updateClass is the button that displays the edit form on the modal..
here's my routes in web.php:
Route::resource('classes', 'ClassesController');
Route::group(['prefix' => 'admin'], function () {
Route::get('classes', 'ClassesController#index');
Route::get('classes/edit/{id}', 'ClassesController#edit');
Route::put('classes/update/{id}', 'ClassesController#update');
});
and finally, my update function in the classes controller:
public function update(Request $request, $id)
{
$validator = $this->validator($request->all());
$errors = $validator->errors();
$errors = json_decode($errors);
if ($validator->passes())
{
Dl_class::find($id)->update($request->all());
return response()->json();
}
else
{
return response()->json($errors, 422);
}
}
what i'm i missing?
To send PUT request from form you need to send a hiddne input element named as method. Something like this:
<input type='hidden' name='_method' value='PUT'>
there is a helper method to do the same like:
{{ method_field('PUT') }}
Only then Laravel can recognize your PUT request.
Or alternatively, you can enclose this value to your ajax call also Something like:
var formdata = {
'name' : name,
'status' : status,
'_token' : token,
'_method' : 'PUT'
};
I want to send post request with ajax to controller in laravel. The ajax request send two input arguments and I want controller to find the column in the database with the first argument and then to set the name attribute with the second input argument. But I have this error message in console 500 (Internal Server Error).
Ajax function:
var $emailInput = $('input[name=eemail]').val();
var $finduser = $('[name=userName]').val();
$.ajax({
type:"POST",
url:'/code/task1/public/editUserAdmin',
data: {
'emailInput' : $emailInput,
'finduser' : $finduser,
},
success:function(data){
// $("#editEmail").attr("readonly", true);
// $("#editEmail").val(data[0].name);
alert("OK");
}
});
Route:
Route::post('/editUserAdmin', 'usersController#editUserAdmin');
Controller function:
$findUserInput = $request->input('finduser');
$user = User::where('name',$findUserInput)->first();
if(!$user){
return response()->json(['status'=>false,'Description' => 'User could not be found.']);
}
//$user->name = $request->input('nameInput');
$user->email = $request->input('emailInput');
$user->save();
}
And also i import csrf everywhere because last time when I was making AJAX call i have problem with this csrf and the following code has fixed my problem, but now is not working.
<meta name="csrf-token" content="{{ csrf_token() }}">
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN' : $('meta[name="csft-token"]').attr('content')
}
});
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('[name="_token"]').val()
}
});
and this
<h3 class="media-heading" name="userName">{{ $user->name }}</h3>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="text" class="form-control paddingzero" class=text-center" readonly value="Name Name">
<input type="text" class="form-control paddingzero" class=text-center" name="eemail" id="editEmail" readonly value="{{ $user->email }}">
Any idea?
Ajax does not have a "type" property. You will need to pass POST as method
$.ajax({
method: "POST",
url:'/code/task1/public/editUserAdmin',
data: {
'emailInput' : $emailInput,
'finduser' : $finduser,
},
success:function(data){
alert("OK");
}
});
If you are in dev mode you should enable error loggin / output. You can just open dev tools F12 (in chrome for example) and have a look at the error output. Proably it would be method not allowed or whatever.
Another minor thing is that i would recommend to not prefix actual variables with $ if you do not reference the jquery object.
var $emailInput = $('input[name=eemail]').val();
var $finduser = $('[name=userName]').val();
Instead do
var $emailInput = $('input[name=eemail]'); // if you need it more than once
var email = $emailInput.val();
or if you only need it ones better name it
var emailInput = $('input[name=eemail]').val();
I developed this shape with laravel code
When I click on + the quantity of this product increase by 1.
When I click - the quantity of this product decrease by 1.
cart.blade.php (view):
<div class="cart_quantity_button">
<a class="cart_quantity_up" href='{{url("cart?product_id=$item->id&increment=1")}}'> + </a>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<a class="cart_quantity_down" href='{{url("cart?product_id=$item->id&decrease=1")}}'> - </a>
</div>
Cart function in controller:
public function cart()
{
if (Request::isMethod('POST')) {
$product_id = Request::get('product_id');
$product = Product::find($product_id);
Cart::add(array('id' => $product_id,'name' => $product->name, 'qty' => 1, 'price' => $product->price,'options'=>array('image'=>$product->image)));
}
$id = Request::get('product_id');
//increment the quantity
if ($id && (Request::get('increment')) == 1) {
$p = Request::get('increment');
$rowId = Cart::search(array('id' => $id));
// echo "row id".$rowId."and the p=".$p;
$item = Cart::get($rowId[0]);
// echo "row id".$rowId;
$add = $item->qty + 1;
Cart::update($rowId[0], $add);
}
//decrease the quantity
if ($id && (Request::get('decrease')) == 1) {
$rowId = Cart::search(array('id' => $id));
$item = Cart::get($rowId[0]);
$sub = $item->qty - 1;
echo "item" . $sub;
Cart::update($rowId[0], $sub);
}
if ($id && (Request::get('remove')) == 1) {
$rowId = Cart::search(array('id' => $id));
Cart::remove($rowId[0]);
}
$cart = Cart::content();
return view('cart', array('cart' => $cart,'title' => 'Welcome', 'description' => '', 'page' => 'home','subscribe'=>"",'brands' => $this->brands));
}
public function cart_remove()
{
Cart::destroy();
return Redirect::away('cart');
}
public function checkout()
{
$cart = Cart::content();
return view('checkout', array('cart' => $cart,'title' => 'Welcome', 'description' => '', 'page' => 'home','subscribe'=>"",'brands' => $this->brands));
}
I want to convert this with ajax code, I do simple code for this
<script>
function getMessage($id)
{
$.ajax({
type: 'POST',
url: 'getmsg',
dataType: 'json',
data: {
valu_id: $id
},
success: function(data) {
$("#msg").html(data.msg);
}
});
}
</script>
<?php
$item_id = 3;
echo Form::button('+',['onClick'=>'getMessage($item_id)']);
?>
<div id='msg'>
<input id="msg" type="text" name="quantity" autocomplete="off" size="2">
</div>
Controller function:
public function ajax()
{
$value= $_POST['valu_id']+1;
return response()->json(array('msg'=>$value), 200);
}
I don't know how to complete this code .I have many question about this code.
like
How to get the product id from cart.blade.php view and put it in getmessage() to use it in ajax function?
How to put getmessage() in <div class="cart_quantity_button"> instead of button onclick to respect of the shape above?
How to return the quantity in the input field as the shape above?
Note: This answer doesn't simply giving you a working solution but an idea on how to handle ajax request/response.
Firstly, even tough event.preventDefault() would prevent default action which is following the URL, I'd rather store the URL to data- attribute.
<div class="cart_quantity_button">
<a class="cart_quantity_up" href="javascript:void(0)" data-route="{{url('cart?product_id=$item->id&increment=1')}}"> + </a>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<a class="cart_quantity_down" href="javascript:void(0)" data-route="{{url('cart?product_id=$item->id&decrease=1')}}"> - </a>
</div>
How to get the product id from cart.blade.php view and put it in getmessage() to use it in ajax function?
It's always better to listen to an event, which is click in this case.
$('.cart_quantity_up').on('click', function(e) {
//an ajax call here
});
Same code applies for the other one
$('.cart_quantity_down').on('click', function(e) {
//an ajax call here
});
Now, two click events has been attached to each corresponding element. Then, it's time to wrap the ajax function up.
function updateQty(url){
var $qty = $('.cart_quantity_input');
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: {
cart_qty: $qty.val()
},
success:function(data){
$qty.val(data.qty);
}
});
}
The function above is simply
takes a parameter which is URL for ajax to call to,
does a post request with uri param key 'cart_qty'
returns response which is a value of 'qty' from controller to cart_quantity_input input element
And then, put the ajax function to the first snippets (click event)
$('.cart_quantity_up').on('click', function(e) {
e.preventDefault();
//get the data-route
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
$('.cart_quantity_down').on('click', function(e) {
e.preventDefault();
//get the data-route
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
Actually to make things simpler, you can attach the event from multiple selectors at one go.
$('.cart_quantity_up, .cart_quantity_down').on('click', function(e) {
e.preventDefault();
//get the data-route for the 'up'
var url = $(this).data('route');
//call the ajax function
updateQty(url);
});
Now, you get the idea on how to create ajax post and retrieve its response to attach it to the input element afterward.
At this point, I'm going to refactor your code. And oh, all of your questions should have been answered at this stage.
Your controller looks a bit messy as you handle both post and get requests for such simple situation. I would rather do just post. Instead of having bunch of conditions, I'll put the footprint inside the data- attribute (again). In the end, I wrap them inside a form, because CSRF token gives more security on your end.
<form name="cart_form">
{{ csrf_field() }}
<input type="hidden" class="item_id" value="{{ $item->id }}">
<div class="cart_quantity_button">
<button type="button" class="cart_quantity_up" data-route="{{url('cart')}}" data-increase="1"> + </button>
<input class="cart_quantity_input" type="text" name="quantity" value="{{$item->qty}}" autocomplete="off" size="2">
<button class="cart_quantity_down" data-route="{{url('cart')}}" data-increase="0"> - </button>
</div>
</form>
You're free to design your own view as long as you're going to do a post request (as I'm doing on it). I'll explain a bit above the logic I'm going to make.
Hold the $item->id on hidden field
Going to make ajax request to url('cart') route and store it to data-route
Add data-increase to differentiate each request should increase or decrease
Now listen up on click event
$('.cart_quantity_up, .cart_quantity_down').on('click', function(e) {
e.preventDefault();
var $this = $(this),
url = $this.data('route'),
increase = $this.data('increase');
updateQty(url, increase);
});
Below updateQty function is a bit different from the first one I made. It accepts the second parameter increase as (pseudo-)boolean value. Also notice I'm posting the token as request header rather than body.
function updateQty(url, increase){
var $qty = $('.cart_quantity_input'),
itemId = $('.item_id').val();
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
headers: {
'X-CSRF-Token' : $('input[name="_token"]').val()
},
data: {
'cart_qty': $qty.val(),
'item_id': itemId,
'increase': increase
},
success:function(data){
$qty.val(data.qty);
}
});
}
Your controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Cart;
use App\Http\Requests;
class YourController extends Controller
{
public function cart(Request $request)
{
if ($request->ajax()) {
$id = $request->item_id;
$cart = Cart::search(['id' => $id]);
//Note: This code may not working as what you expect
// but it should give you the idea that laravel
// actually has increment and decrement methods
// and else.
if ($request->increase) {
$cart->increment('qty');
} else {
$cart->decrement('qty');
}
$qty = $cart->first(['qty']);
return response()->json(['qty' => $qty]);
}
//rest is your code
//...
}
}
In the above code, I'm trying to
treat ajax request separately from your code,
update qty column based on $_POST['increase']
If 1, do increment. If 0, decrements it
grab the value of qty column (though Im not sure it's going to work)
return the value keyed 'qty' as json
it will then update your input element based on $qty.val(data.qty)
I am working on this laravel 5 app and I can't seem to figure out why my Ajax call is not working for this particular form because it has been working well for other forms. Sample code below.
{!! Form::model($training, ['url' => 'trainings/' . $training->id,
'method' => 'PUT',
'class' => 'form-horizontal',
'id' => 'edit_training_form',
'role' => 'form']) !!}
// Form body
{{ Form::close() }}
Ajax Call Sample code below:
$("document").ready(function() {
$("#edit_academic_form").on('submit', updateAcademic);
$("#edit_training_form").on('submit', updateTraining);
}
function ajaxCall(context) {
$.ajax({
type: "PUT",
data: context.serialize(),
url: context.attr('action'),
dataType: 'json',
cache: false,
beforeSend: function() {
$(".validation-errors").hide().empty();
$(".success-message").hide().empty();
},
success: function(data){
$(".success-message").append(data.message).show();
$(".success-message").delay( 2000 ).fadeOut();
},
error: function(data){
var errors = data.responseJSON;
console.log(errors);
// Render errors with JS
$.each(errors, function(index, value)
{
if (value.length != 0)
{
$(".validation-errors").append('<li>'+ value +'</li>');
}
});
$(".validation-errors").show();
}
});
}
function updateTraining(e){
e.preventDefault();
ajaxCall($(this))
}
function updateAcademic(e){
e.preventDefault();
ajaxCall($(this))
}
The call for updateAcademic is working pretty well but updateTraining is not working. Firebug does not show any error. It's kind of doing some direct form submit. I have cleared browser cache to make sure the js is being read, change browser but no result. Looking at the source of the code from my browser the form is well defined (id is ok) as shown below:
<form method="POST" action="http://localhost:8000/trainings/1"
accept-charset="UTF-8" class="form-horizontal"
id="edit_training_form" role="form">
<input name="_method" type="hidden" value="PUT">
<input name="_token" type="hidden" value="QvvgMIWZN1VYGUOF2zGE8ALgVnAYaZUS5SseW4i5">
</form>
Edit
Firebug does not give any error. I have my controller like so:
public function update(UpdateTrainingRequest $request, $id)
{
$data = $request->all();
$this->training->save_training($data, $id);
$result['message'] = "Training Updated Successfully";
return response()->json($result);
}
When I hit save all I get is a blank browser page with the message:
{"message":"Training Updated Successfully"} suggesting the form is posting directly.
Appreciate help
The problem was with my js. My js look like so:
$("document").ready(function() {
limitCharacters();
$("#edit_academic_form").on('submit', updateAcademic);
$("#edit_training_form").on('submit', updateTraining);
}
The function limitCharacters() had some syntax errors thus preventing the codes beneath it from ever getting called hence reason why the Ajax didn't work. I resolved issues in limitCharacters and now everything is working fine.