Ajax Search with pagination [Laravel] - ajax

I've read both https://gist.github.com/tobysteward/6163902 & AJAX pagination with Laravel but it seems I have a different problem so anyway.
Long story short: When I search, the right data gets fetched and the ajax works "display data, no refresh" only for the first page, but from next page on the page refreshes, so how to make an ajax call that loop through the returned data and display it according to each page?
Also how to add the search query to the URL, currently when the data gets fetched, the URL doesn't update, instead it stays on its current state (i.e. index?page=3).
search form
{{ Form::open(['route' => 'search', 'method' => 'GET', 'id' => 's-form',])}}
{{ Form::text('search', null, ['id' => 'search', 'placeholder' => 'Search For ...']) }}
{{ Form::submit(Go) }}
{{ Form::close() }}
search controller
public function search() {
$input = Input::get('search');
$posts = Post::where('title','LIKE',$input)->paginate(4);
if (Request::ajax()) {
return View::make('posts.search')->withPosts($posts);
}
return View::make('posts.index')->withPosts($posts);
}
search view
#forelse ($posts as $post)
// do stuff
#endforeach
<nav>{{ $posts->appends(Request::except('page'))->links() }}</nav>
the js
$('#s-form').submit(function(e)
{
e.preventDefault();
$.ajax({
url: $(this).attr('action'),
data:{
search: $('#search').val()
},
success: function(data){
$('#result').html(data);
}
});
});

This is all it needed:
$(document).ajaxComplete(function() {
$('.pagination li a').click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
$.ajax({
url: url,
success: function(data) {
$('#result').html(data);
}
});
});
});
Now I just need to update the URL according to each page.

Related

Laravel: Ajax update to database

i just want to update my data via ajax i am getting error.
Error Console:
POST http://abc.local/teachers/users/1 404 (Not Found)
here is my controller:
public function policyupdate(Request $request, $id)
{
$user = DB::table('users')->find($id);
$user->update($request->all());
return response()->json([
'status' => 'success',
'msg' => 'has been updated'
]);
}
web.php:
Route::post('users/{user}','TeachersController#policyupdate') ;
js:
jQuery(document).ready(function(e) {
alert(1);
$('#update-policy').on('click', function(e) {
console.log('Update policy clicked!')
e.preventDefault(e);
$.ajax({
type: "POST",
url: "users/" + $('#update-policy').attr("value"),
data: $(this).serialize(),
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success: function (data) {
alert(updated);
},
});
});
});
I only notice a couple of issues.
url: "users/" + $('#update-policy').attr("value"),
In the url of the ajax call you don't have a slash at the beginning, so the url will be relative to the url of the page where the function is located, instead of the base url. to solve it just add that slash at the beginning
url: "/users/" + $('#update-policy').attr("value"),
The other one is that you have an input with the put method,
<input type="hidden" name="_method" value="put" />
so the Laravel route should be put (it makes sense if it takes into account that it is a route to update)
Route::put('users/{user}','TeachersController#policyupdate') ;
Well, and as you yourself discovered, with query builder, the update() method works if you query with where() instead of find()
$user = DB::table('users')->where('id', $id)->update( $request->all() );

Laravel Ajax on Update data getting Success Message on same Page

i am trying to update data using Ajax in Laravel, my data is being updated successfully but when i click on update it's success message is showing on next page, i want it to show message and updated data on same Page without loading page.
Laravel Controller:
public function update(Request $request, $id)
{
$teacher = Teacher::find($id);
$teacher->efirst = $request->efirst;
$teacher->esecond = $request->esecond;
$teacher->save();
return response()->json([
'status' => 'success',
'msg' => 'esecond has been updated'
]);
}
AJAX function: Update.Js,
jQuery(document).ready(function($) {
$("#update-form").submit(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "teachers/" + $('#update-id').attr("value"),
dataType: 'json',
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
data : $(this).serialize(),
success: function (data) {
let teacher = Object.entries(data.teacher);
teacher.forEach(item => { $(`[name=${item[0]}]`).val('item[1]'); });
},
});
});
});
view:
it contains table to show list of teacher with edit, and form under table with update button.
My data is being updated, but i don't want page reload. maybe something to do with append?
if you want to refresh the data
you can make this
var table = $('#tableId');
table.DataTable().ajax.reload();
this command can reload the data,
also in your view,
you can make the button
type="button"
or add to the form
onsubmit="return false;"

Post 403 forbidden on Yii2 Ajax Call

I know there's other topic on this in stackoverflow but it still didn't work for me. I try to make a simple dynamic menu that generate dynamic content based on the chosen <li> id.
This is the code to generate the menu :
foreach($cabang as $index=>$model){
echo '<li id='.$model->idDpd->id_dpd.'>
<a class="nav-link" href="#" role="tab" data-toggle="tab">'.$model->idDpd->dpd.'</a>
</li>';
}
The menu is created successfully. But I have the problem with the content generated with Ajax
This is what I have in my view file :
$script = <<< JS
$(document).ready(function(){
function load_page_details(id)
{
$.ajax({
url: "<?=Url::to(['/site/fetch']) ?>",
method:"POST",
data:{id:id}, //pass the 'id' of Load_page_details function parameter to the targeted URL
success:function(data)
{
$('#page_details').html(data);
}
});
}
//load page-details where the id in the database table equals 1. Set the default to 1 while page is loading for the first time.
/* load_page_details(1);*/
$('.nav li').click(function(){
var page_id = $(this).attr("id");
load_page_details(page_id);
});
});
JS;
$this->registerJs($script)
?>
This is my SiteController and the action :
public function actionFetch(){
if (Yii::$app->request->isAjax) {
// fetch the $_POST["id"]
$data = Yii::$app->request->post('id');
if(isset($data))
{
$query= Cabang::find()->where(['id_dpd'=> $data])
->joinWith('idDpd')
->all();
$output = '';
foreach($query as $model)
{
$output .= '
<div role="tabpanel" class="col-lg-4 tab-pane fade show active" >
<div class="col-md-12">
<h4>'.$model->kota.'</h4>
<p>'.$model->alamat.'</p>
<p>'.$model->telp.'</p>
<p>'.$model->email.'</p>
<p>'.$model->jadwal.'</p>
</div>
</div>
';
}
/* echo $output;*/
// return Json
return \yii\helpers\Json::encode($output);
}
}
}
The error caught in my console in chorome dev tool : jquery.js:9175 POST http://localhost/%3C?=Url::to([%27/site/fetch%27])%20?%3E 403 (Forbidden)
I tried to make the fetch function to a new php file and link the URL in my Ajax to that file (not to a controller or SiteController in my case) like : url: url:"site/fetch.php",but it returned jquery.js:9175 POST http://localhost/site/fetch.php 404 (Not Found)
What am I doing wrong? I have spent two days without solution. Thanks for the help!
Your PHP is not correct - you cannot use <?= /* ... */ ?> inside of heredoc. You need to use temporary variable:
$url = Url::to(['/site/fetch']);
$script = <<<JS
$(document).ready(function () {
function load_page_details(id) {
$.ajax({
url: "$url",
method: "POST",
data: {id: id}, //pass the 'id' of Load_page_details function parameter to the targeted URL
success: function (data) {
$('#page_details').html(data);
}
});
}
$('.nav li').click(function () {
var page_id = $(this).attr("id");
load_page_details(page_id);
});
});
JS;
$this->registerJs($script);

Why the if condition does not filtering the results?

I want to create advance search filtering staff data according to certain criteria chosed by users. This application developed using laravel 5. I am querying the data using ajax function and if statement to filter the criteria. The results appear but it does not filter any condition in the if statement.
The controller of the filtering condition is this:
public function kakitangan(Request $request)
{
$query = DB::table('itemregistrations')
->select('itemregistrations.ItemRegistrationID','itemregistrations.name', 'itemregistrations.Nobadan');
if ($request->section != ""){
$query->where('SectionID', $request->section);
}
$newitem = $query->get();
return response::json($newitem);
}
I also have tried this:
$query = DB::table('itemregistrations')
->select('itemregistrations.ItemRegistrationID','itemregistrations.name', 'itemregistrations.Nobadan');
if(request('section')) {
$query->where('SectionID', request('section'));
}
$newitem = $query->get();
return response::json($newitem);
But the result is the same..all data in itemregistrations appear in the output page. Although I select another section criteria.
This is the view page code for selection:
<div class="row">
<div class="col-lg-2">
{{ Form::label('Seksyen', 'Seksyen') }}
</div>
<div class="col-lg-2">
{{ Form::select('section', $sections, '', ['class' => 'form-control select2', 'placeholder' => '--pilih--']) }}
</div>
</div>
</div>
The selection id is from controller function:
$sections = Section::pluck('sectionname', 'SectionID');
//sent to html view
return view('carian.index', compact('sections'));
Button to call ajax function to get the query:
<button class="btn btn-primary btn-md" id="cari">Cari</button>
The code for results appear:
<script type="text/javascript">
$( "#cari" ).click(function() {
var seksyen = $("#section").val();
$.ajax({
url: '{{ url('kakitangan') }}',
data: {'section': seksyen},
dataType: 'json',
success: function (data) {
console.log(data);
$('#datatable tr').not(':first').not(':last').remove();
var html = '';
for(var i = 0; i < data.length; i++){
html += '<tr>'+
'<td>' + data[i].name + '</td>' +
'</tr>';
}
$('#datatable tr').first().after(html);
},
error: function (data) {
}
});
});
</script>
Should be when the user select a section, only staffs of the section appear. But now all staffs appear when select any section.
I just tried to test whether the section value is correctly passed to the controller using this in controller:
$try=$request->input('section');
return response::json($try);
It results empty array..no value passed? Is it the section value is not passed correctly? How to correct this problem?
You are passing the section as a post param while you performing a GET request.
Using jQuery you can send this as a query string using:
var seksyen = $("#section").val();
$.ajax({
url: '{{ url('kakitangan') }}?' + $.param({'section': seksyen}),
dataType: 'json',
...
In your controller you can also explicitly check if a request contains a query string using the has method on a request
if(request()->has('section')) {
$query->where('SectionID', request('section'));
}
EDIT:
using the laravel collective Form helpers you can specific the field id using the following (note the fourth argument id)
{{ Form::select('section', $sections, '', ['id' => 'section', 'class' => 'form-control select2', 'placeholder' => '--pilih--']) }}

Symfony ajax form need reload page to show results

I have a product page where users can write comments, this works fine but i would like to implement ajax form with no page refresh.
The code call ajax and persist, but need press f5 to show new comment.
what am I doing wrong?
Thanks, and sorry for my english.
In product view, render a controller that call the form:
<div class="comments">
{{ render(controller('AppBundle:Comment:newComment',{'media': selected.id})) }}
</div>
Controller:
class CommentController extends Controller
{
/**
* #Route("/media/{media}/", name="create_comment", options={"expose"=true})
* #Method("POST")
* #ParamConverter("media", class="AppBundle:Media")
*/
public function newCommentAction(Request $request, $media)
{
$comment = new Comment();
$form = $this->createForm(CommentType::class, $comment);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$data = $form->getData();
$data->setUser($this->getUser());
$data->setMedia($media);
$em = $this->getDoctrine()->getManager();
$em->persist($data);
$em->flush();
return new JsonResponse('Success!');
}
return $this->render('comment/newComment.html.twig', array(
'media' => $media,
'form' => $form->createView()
));
}
}
newComment.html.twig
<form method="POST" id="commentForm" action="{{path('create_comment', {'media': media.id})}}">
{{ form_row(form.comment) }}
<button type="submit" id="submitButton" class="btn btn-xs btn-danger">{{ 'btn.send' |trans }}</button>
app.js
$('body').on('click','#submitButton', function(e){
e.preventDefault();
var $form = $('#commentForm');
$.ajax({
type: "POST",
dataType: "json",
url: 'http://demo/app_dev.php/media/16/',
data: $form.serialize(),
cache: false,
success: function(response){
$(".ajaxResponse").html(response);
console.log(response);
},
error: function (response) {
console.log(response);
}
});
});
This should work for you to reload the element with class="comments" after your POST:
$('#submitButton').on('click', function (e) {
e.preventDefault();
var $form = $('#commentForm');
$.ajax({
type: "POST",
dataType: "json",
url: 'http://demo/app_dev.php/media/16/',
data: $form.serialize(),
cache: false,
success: function (response) {
$('.comments').load(window.location + ' .comments > *');
console.log(response);
},
error: function (response) {
console.log(response);
}
});
});
Edit:
As far as your second question regarding $request->isXmlHttpRequest() -- this method just looks for the X-Requested-With header with value of XMLHttpRequest. Are you testing for it on the first request or on the second request or on both requests? Can you take a look in Firebug or Chrome Tools and see if the header is on both requests?

Resources