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.
Related
I am trying to submit a form using ajax in Laravel 5.5
The problem is the page is refreshing and not submitting data in the database. I need to store data in the database without refreshing the page.
Here is my code:
Controller
public function new_timing_table(Request $request)
{
if (Request::ajax()) {
$timing_tables = new Timing_Table;
$timing_tables->timing_tables_name = $request->timing_tables_name;
$timing_tables->save();
$msg = "yes";
} else {
$msg = "yes";
}
return ['msg'=> $msg];
}
View
<form id="timeForm" class="form-horizontal form-material" >
<div class="form-group">
{{ csrf_field() }}
<div class="col-md-12 m-b-20">
<label> Table Name</label>
<input type="text" id="timing_tables_name" class="form-control"
name="timing_tables_name" />
</div>
<div class="modal-footer">
<input type="button" value="Replace Message" id='btnSelector'>
</div>
</div>
</form>
Ajax script
const xCsrfToken = "{{ csrf_token() }}";
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': xCsrfToken
}
});
jQuery(document).ready(function() {
jQuery('#btnSelector').click(function(e) {
event.preventDefault();
getMessage();
});
});
var getMessage = function() {
var timing_tables_name = $("input[name=timing_tables_name]").val();
$.ajax({
type: 'post',
url: '/new_timing_table',
dataType: 'json', //Make sure your returning data type dffine as json
data: timing_tables_name,
//data:'_token = <php echo csrf_token() ?>',
success: function(data) {
console.log(data); //Please share cosnole data
if (data.msg) //Check the data.msg isset?
{
$("#msg").html(data.msg);
}
}
});
}
Router
Route::post('/new_timing_table','Timing_TableControoler#new_timing_table');
You got a typo or a mistake in your script.
jQuery('#btnSelector').click(function(e){
// An error here - it should be e.preventDefault();
event.preventDefault();
getMessage();
});
My code is working now after adding beforeSend: function (request) in Ajax script
var getMessage = function(){
var timing_tables_name = $("#timing_tables_name").val();
console.log(timing_tables_name);
$.ajax({
type:'GET',
url:'/new_timing_table', //Make sure your URL is correct
dataType: 'json', //Make sure your returning data type dffine as json
data:
{
timing_tables_name
},
beforeSend: function (request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='csrf-
token']").attr('content'));
},
success:function(data){
console.log(data); //Please share cosnole data
if(data.msg) //Check the data.msg isset?
{
$("#msg").html(data.msg); //replace html by data.msg
}
}
});
}
and editing the controller to be simple as this one
public function new_timing_table(Request $request){
$timing_tables = new Timing_Table;
$timing_tables->timing_tables_name = $request->timing_tables_name;
$timing_tables->save();
$msg = "This is a simple message.";
return ['msg'=> $msg];
}
Thank you all for your help
I have a big problem with Ajax-request via Laravel. I can't understand why it is not Ajax. All resources here.
It is my Ajax-request.
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
var nickname = "<?php echo $name_user; ?>";
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('.subscribe').click(function() {
jQuery.ajax({
type: 'post',
url: "{{ route('postSubscribe', '<?php echo $name_user; ?>') }}", //Путь к обработчик
data: {'user_name': nickname},
response: 'text',
success: function(data) {
console.log(data['result']);
},
error: alert('Error');
})
})
</script>
It is my web-routes.
Route::group(['middleware' => 'auth'], function() {
Route::get('/', 'AccountController#redirectToAccountPage');
Route::get('/account', 'AccountController#showAccount')->name('account');
Route::get('/account/settings', 'AccountController#showSettings')->name('settings');
Route::post('/account/settings', 'AccountController#sendSetting');
Route::get('/account/subscribe', 'AccountController#showSubscriberForm')->name('subscriber');
Route::post('/account/subscribe', 'AccountController#findUser')->name('postFindUser');
Route::get('/account/load_image', 'AccountController#showLoadImage')->name('load_image');
Route::post('/account/load_image', 'Photos\LoadPhotoController#loadPhoto');
Route::post('/account/logout', 'AccountController#logout')->name('logout');
Route::post('/user/{user_name}/', 'AccountController#subscribe')->name('postSubscribe');
Route::get('/admin', 'AccountController#showAdminPanel');
});
It's my main request.
public function subscribe(Request $request, $name_user) {
if($request->ajax()) {
$query = 'SELECT id FROM subscriptions WHERE id_subscriber = ? AND id_subscribtion = ?';
$queryFindAnother = 'SELECT id From new_users WHERE nickname = ?';
$idAnotherUser = DB::select($queryFindAnother, [$name_user]);
if(!DB::select($query, [Auth::user()->id, $idAnotherUser[0]->id])) {
$query = 'INSERT INTO subscriptions (id_subscriber, id_subscribtion) VALUES (?, ?)';
dd('Я здесь');
//id_subscriber - тот, кто подписался.
//id_subscribtion - на кого подписан.
DB::insert($query, [Auth::user()->id, $idAnotherUser[0]->id]);
return response()->json([
'result' => '1', //всё прошло успешно, я подписан
]);
}
return back();
}
dd("It's not ajax");
return back();
}
As a result I got the message "It's not Ajax". Help me please!
I think the problem is in your form
Please update your form
<form>
{!! csrf_field() !!}
<button class="subscribe" name="user" type="button">Подписаться.</button>
</form>
Here, you don't need any action or method also does not need any form
because you passing the form data as ajax
and add the type of your button as button, by default its a submit type, so its submitting the form as normally.
Make sure you have imported the Request Facade on top
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 tried to receive Ajax response but the response is null.
My HTML Looks like this
<form method="post" action="<?php $_SERVER['PHP_SELF'] ?>">
<select class="form-control" class="form-control" id="choose_country">
<option value="">Select a prefered language</option>
<option value="en">EN</option>
<option value="fr">FR</option>
<option value="de">DE</option>
<option value="nl">NL</option>
</select>
</form>
<div id="table_load"></div> <!-- loads search table -->
My Javascript looks like this
<script>
$('#table_load').load('<?php echo base_url(); ?>admin/manage_article/search');
$("#choose_country").change(function(){
var choose_country = $("#choose_country").val();
$.ajax({
url: "<?php echo base_url(); ?>admin/manage_article/search",
type: "post",
data: {choose_country: choose_country},
dataType: 'json',
async: false,
success: function (response) {
if(response.success == true){
alert('success');
$('#table_load').load('<?php echo base_url(); ?>admin/manage_article/search');
}else{
alert('fail');
}
},
});
});
</script>
My controller looks like this
public function search(){
$choose_language = $this->input->post('choose_country');
$this->load->view('admin/manage_article/search');
}
}
I want to pass the value of select box to the controller and return back the selected value in the page $this->load->view('admin/manage_article/search');
I have tried the above code but the response alerts "fail".
I am new to ajax so pardon me if there are any mistakes in coding.
Try this, in your controller
public function search() {
$choose_language = $this->input->post('choose_country');
$result = ($choose_language) ? true : false;
$this->output->set_content_type('application/json')->set_output(json_encode(array('choose_country' => $choose_language, 'result' => $result)));
}
your jquery will be as below
<script type="text/javascript">
$(document).ready(function() {
$("#choose_country").change(function() {
var choose_country = $("#choose_country").val();
$.ajax({
url: "<?php echo base_url(); ?>admin/manage_article/search",
type: "post",
data: {
choose_country: choose_country
},
dataType: 'json',
async: false,
success: function(response) {
if (response.result) {
alert('success');
$('#table_load').html(response.choose_country);
} else {
alert('fail');
}
},
});
});
});
</script>
I dont know why you are using the ajax, you might have business logic in controller, which you have not shown. If not then you can simply load the value of choose_country in table_load, as below.
<script type="text/javascript">
$(document).ready(function() {
$("#choose_country").change(function() {
var choose_country = $("#choose_country").val();
$('#table_load').text(choose_country);
});
});
</script>
There is no reason to make two calls to the server - once for the ajax call and then again to load html.
To return and load html into the browser via AJAX do this in your javascript.
$("#choose_country").change(function () {
var choose_country = $("#choose_country").val();
$.ajax({
url: "<?php echo base_url('admin/manage_article/search'); ?>",
type: "post",
data: {choose_country: choose_country},
dataType: 'html',
// Forcing synchronous strongly discouraged,
// as it can cause the browser to become unresponsive.
//async: false,
success: function (response) {
$('#table_load').html(response);
},
error: function(xhr, textStatus, errorThrown){
console.log(textStatus, errorThrown);
}
});
});
Your controller will work the way you show it in the question except I don't see where the posted var is used, so you may not receive the language specific html what you want (If that is what you're trying to do).
If you really feel the need to have the return contain a property called result that you can check using if (response.result) {... then you will need a variation on parth's answer to your question. You can add the html to the returned json with this in your controller.
public function search()
{
//What do you do with this?
//You don't show how this is used so I'm mostly going to ignore it.
$choose_language = $this->input->post('choose_country');
$result = !empty($choose_language) ? true : false;
///get the view file as a string of html markup
$html = $this->load->view('admin/manage_article/search', NULL, TRUE);
$out = array('result' => $result, 'html' => $html);
$this->output
->set_content_type('application/json')
->set_status_header('200')
->set_output(json_encode($out));
}
Then your success function would be like this
success: function(response) {
if (response.result === true) {
alert('success');
$('#table_load').html(response.html);
} else {
alert('fail');
AJAX:
$(document).ready(function () {
$('.my_button').click(function () {
var data = $(this).val();
//alert(BASE_URL);
$.ajax({
type: "POST",
ContentType: 'application/json',
data: data,
url: BASE_URL + 'index.php?deo/dashboard',
error: function () {
alert("An error occoured!");
},
success: function (msg) {
alert('result from controller');
}
});
alert(data);
});
});
CONTROLLER:
public function dashboard() {
$data = $this->input->post('data');
$data = json_decode($data);
echo "<script>alert('count ".$data."');</script>";
}
Am trying to send value from my jquery, ajax to controller, am able to get value from my view page to jquery page and able to print that. But unable to send the value from ajax page to controller page, after sending the data i got the success data. but unable to get and print the data in my controller page. Thanks in advance
If your using firefox a good thing to use is firebug add on and then you can use the console to check for errors on there. To see if the ajax has any errors while sending.
Remove question mark after index.php? and I think your base url is not working correct try just.
Url
// With index.php
url: 'index.php/deo/dashboard',
// Or without index.php
url: 'deo/dashboard',
Or
// With index.php
url: <?php echo site_url('index.php/deo/dashboard');?>,
// Or without index.php
url: <?php echo site_url('deo/dashboard');?>,
Script
$(document).ready(function () {
$('.my_button').click(function () {
var data = $(this).val();
$.ajax({
type: "POST",
data: data,
url: 'index.php/deo/dashboard',
// url: <?php echo site_url('index.php/deo/dashboard');?>,
success: function (msg) {
alert('result from controller');
},
error: function () {
alert("An error occoured!");
}
});
alert(data);
});
});
Controller
public function dashboard() {
$data = $this->input->post('data');
echo "<script>alert('count ".$data."');</script>";
}