I just implemented SortableJS in my Laravel project and want to rearrange the order of some elements. I have a list of "Blocks" which all have a database field of "Order" which is an integer. I show these blocks in descending order based on the value of the "Order" field.
Now I want to update these values with SortableJS using Ajax. How can I accomplish this?
Currently, I have a simple list
<div class="block-order-list">
#foreach($blocks as $block)
<div class="list-group-item"><i class="far fa-arrows handle mr-3"></i> {{$block->name}}</div>
#endforeach
</div>
And call an Ajax request like so:
$('.block-order-list').sortable({
animation: 150,
handle: '.handle',
store: {
set: function (sortable) {
let order = sortable.toArray();
console.log(order);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{ route('change_order', ['url', $page->url]) }}',
type: 'POST',
data: order,
success: function(data){
console.log(data)
}
})
}
}
});
To my PageController which contains
public function changeOrder($data)
{
return $data;
}
The request now only returns a string that says url which I find odd. In the url of the ajax request, I give a parameter called URL which I need to find the blocks attached to this specific page. My blocks database table looks like this
How can I accomplish this?
I guess you must use ID in your HTML list :
<div class="block-order-list">
#foreach($blocks as $block)
<div class="list-group-item" data-id="{{ $block->id }}>
<i class="far fa-arrows handle mr-3"></i> {{ $block->name }}
</div>
#endforeach
</div>
Then in your JS, build an array with ID => order :
let order = {};
$('.list-group-item').each(function() {
order[$(this).data('id')] = $(this).index();
});
Then in your ajax call :
$.ajax({
url: '{{ route('change_order', ['url', $page->url]) }}',
type: 'POST',
data: {order: order},
success: function(data){
console.log(data)
}
})
And in your controller :
public function changeOrder(Request $request)
{
foreach($request->get('order') as $id => $order) {
Block::find($id)->update(['order' => $order]);
}
}
Related
How to create dynamically tooltip using AJAX in Laravel?
I've got table, each element of table has it own ID, stored in <div id="[numbers]" hover="tooltip(this.id);"></div>
For each element I want to "create" or display tooltip(for displaying data like name, date, etc.).
Is it possible? This is what I've got at the moment:
// blade.view
function test(id)
{
$.ajax({{
type: "GET",
data:
{
id:id,
},
url: "{{ route('box.getData') }}",
success: function(data){
alert("data");
}
}});
}
Route:
Route::get('/box', 'App\Http\Controllers\BoxController#getData')->name('box.getData');
How to proceed with that in Controller?
Added controller:
public function getData(Request $request)
{
$absence = Absence::findOrFail($request->id);
return response()->json($absence, 200);
}
I'm creating this functionality where user can like a product and unlike it with javascript, if user likes the product it should add to the database and also if he unlike the product it should be deleted in database. Everything works fine in normal way but if I use javascript, the like button isn't working and either not adding anything in database same thing applies for unlike button. How can I make this work (like and unlike this should work in database too not changing the icons of like and unlike)?
Javascript
// Like product
function addToFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `/product/like/${productid}`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
// Unlike product
function deleteFromFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `product/${productid}/unlike`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
Route
Route::post('product/like/{id}', ['as' => 'product.like', 'uses' => 'LikeController#likeProduct']);
Route::post('product/{product}/unlike', 'LikeController#destroy')->name('product.unlike');
Blade File
#if($product->isLiked)
<div id="deletefavourite{{$product->id}}"onClick="deleteFromFavourites({{$product->id}}, {{ Auth::user()->id }})"> unlike </div>
#else
<div id="addfavourites{{$product->id}}" onClick="addToFavourites({{$product->id}}, {{ Auth::user()->id }})" > like </div>
#endif
How I add to favorite
public function likeProduct($id)
{
if(Auth::check()){
$this->handleLike(Product::class, $id);
return redirect()->back();
}
else{
return redirect()->route('login')
}
}
public function handleLike($type, $id)
{
$existing_like = Like::withTrashed()->whereLikeableType($type)->whereLikeableId($id)->whereUserId(Auth::id())->first();
if (is_null($existing_like)) {
Like::create([
'user_id' => Auth::id(),
'likeable_id' => $id,
'product_id' => $id,
'likeable_type' => $type,
]);
} else {
if (is_null($existing_like->deleted_at)) {
$existing_like->delete();
} else {
$existing_like->restore();
}
}
}
I think you have not completed curly braces of function check my code
function addToFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `/product/like/${productid}`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
console.log($('#addfavourites' + productid));
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
}
// Unlike product
function deleteFromFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `product/${productid}/unlike`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
console.log($('#addfavourites' + productid));
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
}
first you must check in network for see request and response from inspect element
this thing will make you can follow problem . you may have a problem with route so please
check the network during post request.
First of all I suggest change routes. I mean, use same pattern for both actions: like and unlike
Route::post('product/like/{id}', ['as' => 'product.like', 'uses' => 'LikeController#likeProduct']);
Route::post('product/unlike/{id}', 'LikeController#destroy')->name('product.unlike');
Then inspect what you see on server, log incoming data. It should help to understand, why you algorithm didn't work.
Second, you have to render both div's in your blade template
<div class="CLASS_SHOW_ITEM" id="deletefavourite{{$product- >id}}"onClick="deleteFromFavourites({{$product->id}}, {{ Auth::user()->id }})"> unlike </div>
<div class="CLASS_HIDE_ITEM" id="addfavourites{{$product->id}}" onClick="addToFavourites({{$product->id}}, {{ Auth::user()->id }})" > like </div>
You have to choose class by value of attribute $product->isLiked
UPDATED QUESTION:
I want to update a database table column with AJAX and Laravel 5.2 framework. I have a button Delier when i will click on that button then it will update a column from Not Shipped to Shipped. I also using sweetAlert plugin for popup styling. I have searched a lot. But i didn't find perfect procedure of it. I have tried this way:
Routes:
Route::get('/winner/status/{id}', ['as' => 'winner.status', 'uses' => 'WinnerController#statusUpdate']);
WinnerController:
public function statusUpdate(Request $request, $id)
{
$winner = Winner::find($id);
$winner->product_stat = "Shipped";
$winner->save();
$request->session()->flash('alert-info', 'Product Status Updated!');
return Redirect::to('admin/winner/detail');
}
Script in View:
$(".action-button").click(function(){
swal({
type : 'warning',
title: 'Submit what you want',
input: 'text',
showCancelButton: false,
confirmButtonText: 'Submit',
showLoaderOnConfirm: true,
allowOutsideClick: false
}).then(function (text) {
$.ajax({
type: "POST",
url : '',
success: function(data){
swal('Confirmed!','success')
}
});
})
});
Blade:
#foreach($dataQrDetails as $dataQr)
<tr>
<td> {{ $dataQr->product_name }} </td>
<td> {{ $dataQr->product_stat }} </td>
<td> {{ $dataQr->created_at }} </td>
<td> <a class="btn btn-info btn-xs action-button" href="{{route('winner.status',$dataQr->id)}}">Delier</a></td>
</tr>
#endforeach
Blade frontend:
This is updating column but after updated its redirected another page and its showing just popup its not need to submit confirm button of popup. Is there anyway to do this? Please could anyone answer my below question:
What will be the best procedure to using AJAX with Laravel.
What will be route call for update data?
How i define AJAX url?
Many JavaScript frameworks also use "curly" braces to indicate a given expression should be displayed in the browser
best ways to pass variable in ajax request in laravel]
your route is
Route::get('testUrl/{id}', 'TestController#getAjax');
ajax request
<script>
var Id = <?php echo $id; ?>
$(function(){
$('#button').click(function() {
$.ajax({
url: 'testUrl/{id}',
type: 'GET',
data: { id: Id },
success: function(response)
{
$('#something').html(response);
}
});
});
});
</script>
TestController.php
public function getAjax()
{
$id = $_GET['id'];
return $id // any value return as a response
}
What is do here is, when you load the form I'll save the user id in Hidden field and when i submit will pass that to controller as well
In Form
<input type="hidden" name="id" value="{{ $id }}">
In AJAX
$.ajax({
url: "/update-winner",
type:'POST',
data: {_token:_token, id:id, .....},
success: function(data) {
if($.isEmptyObject(data.error)){
swal('Confirmed!',data.success); # or swal('Confirmed!','success')
}else{
swal('error!',data.error); # or swal('error!','Errorrrrr')
}
}
});
In Route
Route::post('update-winner','HomeController#statusUpdate');
In Controller
function statusUpdate()
{
<!-- if need -->
$validator = Validator::make($request->all(), [
/....
]);
if ($validate->fails())
{
return response()->json(['error'=>$validator->errors()->all()]);
}
else
{
$id = $request->input("id");
$winner = Winner::find($id);
$winner->product_stat = "Shipped";
$winner->save();
return response()->json(['success'=>'Added new records.']);
}
}
Edit 01
In delete button add this data-delete="{{ id_fiedld_name}"
and in Ajax you can catch
var id = ($(this).data('delete'));
I'am new in Ajax and I intregated one ajax request. The purpose is one user can like, unlike an article. Look my code :
controller
public function likeAction(Request $request, Article $article, $slug)
{
if (!$this->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
throw $this->createAccessDeniedException();
}
if ($request->isXmlHttpRequest()) {
$tokenStorage = $this->get('security.token_storage');
$currentUser = $tokenStorage->getToken()->getUser();
$likes = $article->getLikes();
foreach ($likes->getUsers() as $user) {
if ($user == $currentUser) {
throw new \Exception('Vous aimez déjà cet article !');
}
}
$likes->addUser($currentUser);
$likes->setCount($likes->getCount() + 1);
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
$count = $article->getLikes()->getCount();
return new JsonResponse(array('data' => $count));
}
return $this->redirectToRoute('pm_platform_view', array('slug' => $slug));
}
route
pm_platform_like:
path: /like/{slug}
defaults:
_controller: PMPlatformBundle:Article:like
view
<a class="btn btn-blue-grey" id="like" role="button"></a>
<span class="counter" id="counter">{{ article.likes.count }}</span>
<script>
$( document ).ready(function() {
$(document).on('click', '#like', function (e) {
$this = $(this);
$.ajax({
type: 'GET',
url: '{{ path('pm_platform_like', {slug: article.slug}) }}',
dataType: 'JSON',
data: {},
success: function() {
//refresh article.count here
}
});
});
});
</script>
Currently the ajax request works and the "like" is persisted in database. But in my view nothing change, I have to "refresh" data, more precisly the like count attribute of article entity after the success of the ajax request. I need help for that.
Assuming you have another ajax request that gets like count.
success: function(response) {
//Recall function here that gets like count.
fnGetLikeCount();
}
Edited:
Can you post that function/ajax request that gets like count?
Edit 2:
Yes you can send response from controller and can assign/set that count in like lable/div or what ever you are using.
Your AJAX request is already send total counts in response. So, all you need to update "counter" div with total like count.
objResponse holds response of ajax request and total like count would be stored inobjResponse.data .
success: function(objResponse) { // "objResponse" is response os ajax request
$("#counter").html(objResponse.data);
^^
}
Full Code
<a class="btn btn-blue-grey" id="like" role="button"></a>
<span class="counter" id="counter">{{ article.likes.count }}</span>
<script>
$( document ).ready(function() {
$(document).on('click', '#like', function (e) {
$this = $(this);
$.ajax({
type: 'GET',
url: '{{ path('pm_platform_like', {slug: article.slug}) }}',
dataType: 'JSON',
data: {},
success: function(objResponse) { // "objResponse" is response os ajax request
//refresh article.countcounter here
$("#counter").html(objResponse.data);
^^
}
});
});
});
</script>
Read more about ajax
I am trying to create a live search using jquery, ajax and laravel. I also use pjax on the same page, this might be an issue?. Quite simply it should query the database and filter through results as they type.
When using Ajax type:POST I am getting 500 errors in my console. I get zero errors using GET but instead of returning in #foreach it will a full page view (this might be because of pjax).
Where am I going wrong?
Route:
Route::post('retailers/{search}', array(
'as' => 'search-retailers', 'uses' => 'RetailersController#search'));
Controller:
public function search($keyword) {
if(isset($keyword)) {
$data = array('store_listings' => RetailersListings::search($keyword));
return $data;
} else {
return "no results";
}
}
Model:
public static function search($keyword)
{
$finder = DB::table('retailers_listings')
->Where('city', 'LIKE', "%{$keyword}%")
->orWhere('country', 'LIKE', "{$keyword}")
->orderBy('country', 'asc')
->get();
return $finder;
}
View (store.blade.php):
<div id="flash"></div> //loading
<div id="live"> // hide content
<div id="searchword"><span class="searchword"></span></div> //search word
<table class="table">
<tbody>
#foreach($store_listings as $store)
<tr>
<td></td> //echo out all fields eg: {{ $store->name }}
</tr>
#endforeach
</tbody>
</table>
</div>
Form:
<form method="get" action="">
<input type="text" class="search-retailers" id="search" name="search">
</form>
Ajax and JS:
$(function() {
$("#search").keyup(function() {
var keyword = $("#search").val();
var dataString = 'keyword='+ keyword;
if(keyword=='') {
} else {
$.ajax({
type: "GET",
url: "{{ URL::route('search-retailers') }}",
data: dataString,
cache: false,
beforeSend: function(html)
{
document.getElementById("live").innerHTML = '';
$("#flash").show();
$("#keyword").show();
$(".keyword").html(keyword);
$("#flash").html('Loading Results');
},
success: function(html)
{
$("#live").show();
$("#live").append(html);
$("#flash").hide();
}
});
} return false;
});
});
Additional, Here is my controller for pjax, It is important to note I am using the view store.blade.php foreach in for the search and for this store listing.
public function stores($city)
{
$this->layout->header = $city;
$content = View::make('retailers.stores', with(new RetailersService())->RetailersData())
->with('header', $this->layout->header)
->with('store_listings', RetailersListings::stores($city));
if (Request::header('X-PJAX')) {
return $content;
} else {
$this->layout->content = $content;
}
}
Your route is Route::post('retailers/{search}', [...]) and there you go. You pass data to your ajax-call. In GET you get something like url?key=value but using POST the data are added to the request body not to the url.
Knowing this your route is no longer valid since it only looks up for retailers/{search} and not for retailers only (which is the url POST is using).
Well maybe it could help somebody.
As a first problem you are defining the route as POST and then in the ajax request the type GET so it would not work
Also when making POST request Laravel has the csrf check so in order to work, provide it. The js function will be like
$(function() {
$("#search").keyup(function() {
var keyword = $("#search").val();
if(keyword=='') {
} else {
$.ajax({
type: "post",
url: "{{ URL::route('search-retailers') }}",
data: {
'keyword': keywork,
'_token': '{{ csrf_token() }}';
},
dataType: 'html',
cache: false,
beforeSend: function(html)
{
document.getElementById("live").innerHTML = '';
$("#flash").show();
$("#keyword").show();
$(".keyword").html(keyword);
$("#flash").html('Loading Results');
},
success: function(html)
{
$("#live").show();
$("#live").append(html);
$("#flash").hide();
}
});
} return false;
});
});
And you can test your PHP search method doing separate tests for it.