I am fairly new to Laravel and now i need to implement ajax functionality to my project. I got it how to display article and create it via ajax, problem occurs when i need to list them. And that has two sub-problems.
Display paginated articles which i did
and second one which is changing to next page with new set of articles.
I know how to do this with laravel's pagination, but in this case, pagination also should be done with ajax.
I got some data that i take from ArticlesController which sends json response which looks like this:
{
status: "success", msg: "Hello!", articles: {…}, request: {…}}
articles:
current_page: 1
data: Array(1)
0: {id: 3, title: "Post1", body: "<p><strong>Lorem ipsum</strong> dolor sit amet, co…ctum. Duis feugiat facilisis lectus a cursus.</p>", created_at: "2019-06-18 00:23:25", updated_at: "2019-06-18 18:33:52", …}
length: 1
__proto__: Array(0)
first_page_url: "http://articleapp.test/postajax?page=1"
from: 1
last_page: 3
last_page_url: "http://articleapp.test/postajax?page=3"
next_page_url: "http://articleapp.test/postajax?page=2"
path: "http://articleapp.test/postajax"
per_page: 1
prev_page_url: null
to: 1
total: 3
__proto__: Object
msg: "Hello!"
request: {_token: "T31VK2FBVbIBG6IIOK4X4Q0r7WPTlzc7haXCwJrM", message: "bravo"}
status: "success"
__proto__: Object
}
Controller method which after received call from ajax function, gathers data and sends it back as json response. One part of that data is paginated records of Articles table:
public function ajaks(Request $request){
if($request->ajax()){
$articles = Article::with('user')->paginate(1);
$response = array(
'status' => 'success',
'msg' => "Hello!",
"articles" => $articles,
"request" => $request->all(),
);
return response()->json($response);
}
}
Ajax function it send request through predetermined route alongside csrf token and in turn receive response. From that response, it constructs html which is afterwards appended to particular div in my layouts blade. Her is ajax function:
function ajaks(/*par*/){
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
console.log("hit");
$.ajax({
url: '/postajax',
type: 'POST',
data: {_token: token , message: "bravo"},
dataType: 'JSON',
success: (response) => {
console.log("success");
console.log(response);
let body = "";
let html = "<div class='container'>";
let len = response.articles.data.length;
for(let i=0;i<len;i++){
html += "<div class='row' style='background-color: whitesmoke;'><div class='col-md-4 col-sm-4'><a href='/articles/"+response.articles.data[i].id+"'><img class='postCover postCoverIndex' src='/storage/images/"+response.articles.data[i].image+"'></a></div><div class='col-md-8 col-sm-8'><br>";
if(response.articles.data[i].body.length > 400){
body = response.articles.data[i].body.substring(0, 400)+"<a href='/articles/"+response.articles.data[i].id+"'>...Read more</a>";
}
else{
body = response.articles.data[i].body;
}
html += "<p>"+body+"</p>";
html += "<small class='timestamp'>Written on "+response.articles.data[i].created_at+" by "+response.articles.data[i].user.name+"</small></div></div><hr class='hrStyle'>";
}
let pagination = "<div class='container'><ul class='pagination justify-content-center'><li class='page-item'><a class='page-link' href='#'>Previous</a></li>";
for(let i=0;i<response.articles.last_page;i++){
pagination += "<li class='page-item'><a class='page-link' href='#'>"+(i+1)+"</a></li>";
}
pagination += "<li class='page-item'><a class='page-link' href='#'>Next</a></li></ul></div>";
//console.log(pagination);
html += "</div>"+"<form id='pagForm'>"+pagination+"</form>";
if(document.getElementById("maine")){
document.getElementById("maine").innerHTML = html;
}
},
error: (response) => {
console.log("error");
console.log(response);
}
});
}
And with this, i'm checking for ajax route and getting first set of articles:
<?php
if(Route::getFacadeRoot()->current()->uri()=="ajax"){
?>
<script>
$(document).ready(function(){
ajaks();
});
</script>
<?php
}
?>
it is in my layouts blade. Also pagination links are just plain bootstrap, it just helps me visualize.
My question is how i can use this for pagination? What is the correct approach for using ajax since i can't rely on Laravel's built-in pagination for this. Should i attach another ajax function onto pagination links which then would call controller method again? And when controller method receives such via request, how to use that on pagination in controller method?
You can actually use Laravel's built in pagination via ajax pretty easily, you just need to pass the page in the request. The paginate function will detect the requested page and handle the results automatically.
function ajaks(p){
p = typeof p === 'number' && p > 0 ? p : 1;
let token = document.querySelector("meta[name='csrf-token']").getAttribute("content");
console.log("hit");
$.ajax({
url: '/postajax',
type: 'POST',
data: {_token: token , message: "bravo", page: p},
...
As you pointed out, you will also need to capture clicks on the pagination links, stop the regular click event from propigating and redirect it to your function like this ...
$(document).on('click', '.pagination a', function(e){
e.preventDefault();
var p = $(this).attr('href').split('page=')[1];
ajaks(p);
});
This assumes standard laravel pagination links that have page=x as a query param. You could pretty easily add this to your existing pagination routine or my trick is usually to render the html in my controller and pass that back in my ajax response, like this ...
$articles = Article::with('user')->paginate(1);
$response = array(
'status' => 'success',
'msg' => "Hello!",
"articles" => $articles,
"request" => $request->all(),
'pagination' => (string)$articles->links()
);
And then render it in the browser ...
$('#pagination').html(response.pagination);
Related
I'm having this trouble with the ajax request. This code works on other pages, only on this not working.
I want to call ajax (from different controller - CalendarController) on "show" page from controller ClientController - (http://.../client/35) maybe is that wrong
Client.js
$(document).ready(function() {
$('#events-list').on('click', '.event-popup', function () {
var getEventId = $(this).data('id'); //this line is okay, return dynamic id as i want
$.ajax({
type: "GET",
url: "getEvent/" + getEventId,
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
dataType: 'json',
})
.done(function (data) {
console.log(data); //if i remove dataType: 'json' whole page will print in log instead data
})
.fail(function(data,jqXHR, textStatus, errorThrown) {
toastr.error("error");
console.log(data,jqXHR, textStatus, errorThrown);
})
});
});
Error message from ajax
parsererror" SyntaxError: Unexpected token < in JSON at position
...
responseText: "<!DOCTYPE html><html lang="sr"><head>... - WHOLE PAGE
web.php
Route::get('/getEvent/{id}', 'CalendarController#getEventData');
CalendarController
public function getEventData($id)
{
$event = Event::findOrFail($id);
return Response::json($event);
}
I added how to Controller looks but does not return data, this ajax call does not come to the controller
I think the problem is somewhere in the URL or because I want to add data with another controller to the show page, but I can't figure
Thanks in advance
EDIT
Ajax request is redirected for some reason
Instead of findOrFail() (it returns HTML if the object doesn't exist), use find() method. Then you can check if the object exists or not and return json as per the condition.
Example:
public function getEventData($id)
{
$event = Event::find($id);
if(!$event) {
return response()->json([
'success' => false,
'message' => 'Not Found'
], 404);
}
return response()->json($event);
}
i am typing text in text area
<input placeholder="DISCOUNT COUPON" type="text" id="coupon">
Sending that text to controller using ajax;
$.ajax({
type: "POST",
url: "applyCoupon",
data:{
coupon: $('#coupon').val(),
course_id: {{$course->id}},
_token: {{ csrf_token() }},
},
success: function(dataResult){
alert("success");} // why i am not GETTING this alert?
Controller:
public function applyCoupon(Request $request)
{
$result=new \stdClass();
$coupons = Coupons::select('discount_percentage')->where('coupon_code',$request->get('coupon'))
->where('course_id',$request->get('course_id'))
->get();
$course = Course::findOrFail($request->get('course_id'));
$discounted_price= ($course->price) - (($course->price)*($coupons[0]->discount_percentage)/100);
$result->val = $discounted_price;
$result->statusCode = 200;
return json_encode($result);
}
Web.php:
Route::post('course/applyCoupon', ['uses' => 'CoursesController#applyCoupon', 'as' => 'courses.applyCoupon']);
everything seems fine, but why success function is not running?
You should be using routes/api.php instead of routes/web.phpin the first place.
Also, log error by adding
...
error: function (request, error) {
console.log(error);
alert("Error");
},
That should give you a clue. Could be anything depending on your setup.
You're not using the full URL you setup in your routes/web.php
Change
url: "applyCoupon",
to
url: "course/applyCoupon",
or even better would be to use the route name you provided
url: "{{route('courses.applyCoupon')}}",
Give correct route to your ajax call
Pass this in your ajax url.
url: "{{ route('courses.applyCoupon' }}"
if still not working, then Check your network tab in inspect tool
Click on the ajax call and it will show you the detail on your right side.
post here what you are getting there.
You need to give the response in return of ajax call:-
use Response;
return response()->json(['message' => 'error', 'data' => $data]);
I'm trying to send some data from my view to my controller via ajax. How do I retrieve this data in my action?
I've tried jQuery's $.ajax and $.post methods, providing the url and data, but using $this->data, $this->request->data, $_POST, $_GET or $_REQUEST doesn't work (all return as empty arrays).
$.ajax({
url: "<?php echo Router::url( array("controller" => "Progression", "action" => "submit", $user['User']['id']) ); ?>",
type: 'post',
data: { name: "John" }
}).done( function(data) {
console.log(data);
});
function submit() {
$this->request->allowMethod('ajax');
$this->autoRender = false;
$data = array();
$data['answer'] = $this->request->data; // or any of $_POST, $_GET, etc.
return json_encode($data);
}
My console always keeps printing {"answer":[]}. I checked the network tab of my devtools and the data is successfully listed under Form data, yet I can't seem to get hold of the data in the action.
EDIT:
Thanks to Greg Schmidt I found out that my request indeed got redirected: first it gives me a 302, then it makes a new request without the post data and returns a 200. I just can't find what the critical difference is between the two requests (URLs look the same, no case difference or anything). Can anybody help me with that?
First request:
Second request:
I have a form, when submitted, invokes an AJAX request. This ajax request performs back-end validation on the inputs. If an error is detected, it displays the error messages. So if the user fills out 30 fields, and one is not valid, I would like to return all those inputs with an error message.
My Laravel Code:
Route::post('/roa', function() {
$m = Request::except('_token');
$name = "form1_sections/" . $m['nextTab'] . "_form";//next view name
$name2 = "form1_sections/" . $m['currentTab'] . "_form";//current view name
$var= parse_str($m['inputs'], $output);//data from ajax is a string
if ($m['currentTab']=='section2'){//i'm only doing validation on one section right now
//to simplify the code.
$rules = [
'TB1_course.*' => 'required'
];
$validator=Validator::make($output, $rules);
if ($validator->passes()){//if no error, return the next view
return ["view" => view("$name")-> render(), "value"=>1, "inputs"=>$output];
}
return ["view" => view("$name2")->withInput($output)->withErrors($validator) -> render(), "value"=>1, "inputs"=>$output];
}
return ["view" => view("$name") -> render()];
});
My Ajax request:
$('#form').on('submit', function (e) {
var formData = $('#form').serialize();
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'POST',
url: '/roa',
dataType: 'json',
data: {inputs: formData, nextTab: relatedTabID, currentTab: tabID},
success: function(data){
$('#tabShow').html((data.view));
},
error: function () {
alert('error');
}
});
});
I am successfully able to receive all the error messages, but the withInput($output) for some reason is not working. Thank you for all your help.
'view' => view('template')->withInput()?
I have a system implemented in CodeIgniter, I am trying to send some data in a text area of Rsform component via POST to the url referring to my CodeIgniter system, I have tried usign AJAX request to send the post data using the following code
<script>
alert("jsc");
var data;
data='test from joomla!';
$.ajax({
type: "POST",
url : 'http://localhost/cii/index.php/login/getNews/',
data: {news:data},
cache: false,
success: function(html){
alert(html);
}
});
getNews controller:
function getNews() {
//print_r($this->session->userdata);
header('Access-Control-Allow-Origin: *');
echo "news is ".$news=$_POST['news'];
$data = array ( 'username' => "null", 'is_logged_in' => false, 'news'=>$news);
$this->session->set_userdata($data); //var_dump($_POST); //
print_r($this->session->userdata); session_start(); echo session_id();
}
but it failed, is there any other options ?
Use something like Firebug in mozilla firefox to observe what data is being posted to the app to check if your ajax call is working.
Then in your codeigniter controller method, simply put this code to see if the data is getting to it.
function getNews()
{
foreach($_POST as $key => $val)
{
$options[$key] = $this->input->post($key);
}
var_dump($options);
}