Post 403 forbidden on Yii2 Ajax Call - ajax

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);

Related

Codeigniter: AJAX request don't have response data

I have a simple app in codeigniter. In my view I have ajax POST request to the controller, but I don't receive response data. I checked in the chrome dev tool in network tab the response and the message is: No response data available for this request :
My view:
<table class="table table-striped table-bordered">
<thead>
<tr>
<td>First</td>
<td>Sec</td>
<td>Th</td>
<td>Th</td>
</tr>
</thead>
<tbody>
<?php
if(isset($result))
{
foreach($result as $value)
{
echo "<tr><td>". $value->cai . "</td><td>". $value->partner ."</td><td>". $value->spot ."</td><td><button type='button' id='".$value->cai."' class='btn btn-danger delete'>Delete</button></td></tr>";
}
}
?>
</tbody>
</table>
<?php echo $this->pagination_bootstrap->render(); ?>
<script>
$('.table').on('click','.delete',function(){
var id=$(this).attr('id');
var confirm_box=confirm('Sure?');
if(confirm_box === true)
{
$.ajax({
url: '<?php echo site_url('Tires_Crud/deleteCai'); ?>',
type: 'POST',
data: {
key: id
},
dataType: 'json',
success: function(data) {
console.log(JSON.parse(data));
}
});
}
});
</script>
My controller:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Tires_Crud extends MY_Controller
{
public function deleteCai()
{
$status = array(
"STATUS" => "true"
);
return json_encode($status);
}
}
In my config file CSRF protection is DISABLED! Because when its enabled the ajax request is not working. Thanks for your help in advance!
Some issues with this code.
#1: The way you're forming the ajax request. Where you have type: 'POST' should be method: 'POST' - but more than a typo, it's important that you understand these are referred to as the HTTP method - same way you'd specify that in a <form method='post' tag. If you don't provide a method, it's assumed to be GET.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Also, because you specified dataType:'json' - jquery will deliver a ready to use parsed JSON object. No need for you to parse it yourself
$.ajax({
url: '<?php echo site_url('Tires_Crud/deleteCai'); ?>',
method: 'POST', // <-- change this from 'type' to 'method'
data: {
key: id
},
dataType: 'json',
success: function(data) {
// console.log(JSON.parse(data)); // <-- no need to parse - you have set dataType to be json, which means it will come to you already parsed
console.log(data);
})
#2 - In your PHP, you'd catch your key variable (you sent in ajax) with $_POST['key'] - though in codeigniter you get it like this:
// codeigniter 2.x and 3.x
$this->input->post('key');
// codeigniter 4
use CodeIgniter\HTTP\IncomingRequest;
$request = service('request');
$request->getPost('key');
#3 - With ajax, you actually echo the response, rather than return it:
public function deleteCai(){
$status = array(
"STATUS" => "true"
);
echo json_encode($status);
}

Ajax in Laravel Search function is not working

right now it is not showing any data;
console:finished loading: GET "http://todolist.local/teachers/search?text=a".
i am trying to show result in tbody, when user types something in search.
Ajax code:
<script>
$(document).ready(function(){
$('#searchname').on('keyup', function(){
var text = $('#searchname').val();
$.ajax({
type:"GET",
url: 'teachers/search',
data: {text: $('#searchname').val()},
success:function(data){
$('tbody').html(data);
}
});
});
});
</script>
web.php:
Route::get('/search', 'TeachersController#ajaxsearch');
Search Controller:
public function ajaxsearch(){
$searchname = Input::get ( 'searchname' );
if($searchname != ""){
$teacher = Teacher::where ( 'efirst', 'LIKE', '%' . $searchname . '%' )->paginate(10);
return response()->json($teacher);
}
}
view:
<div class="input-group stylish-input-group">
<input type="text" id="searchname" name="searchname" class="form-control" placeholder="Search..." >
<span class="input-group-addon">
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search">Search</span>
</button>
</span>
</div>
This should do the trick.
HTML:
<div id="datasearch"></div>
JS:
$(function(){
$('#searchname').on('keyup', function(){
$.get('/teachers/search/'+$(this).val(), function(response){
$('#datasearch').html(response);
});
});
});
Controller:
public function ajaxsearch(string $value = null){
return $value ? Teacher::whereRaw("UPPER(efirst) LIKE '%".strtoupper($value)."%'")->paginate(10) : [];
}
Route:
Route::get('/teachers/search/{value?}', 'TeachersController#ajaxsearch');
VERSION AFTER CHAT
HTML:
<ul id="datasearch"></ul>
JS:
$(function(){
var $datasearch=$('#datasearch');
$('#searchname').on('keyup', function(){
$.get('/teachers/search/'+$(this).val(), function(teachers){
$datasearch.empty();
for (var i=0; i<teachers.length; i++){
$datasearch.append('<li>'+teachers[i].efirst+' edit</li>');
}
});
});
});
Controller:
public function ajaxsearch(string $value = null){
return $value ? Teacher::select('id','efirst')->whereRaw("UPPER(efirst) LIKE '".strtoupper($value)."%'")->offset(0)->limit(10)->get() : [];
}
Route:
Route::get('/teachers/search/{value?}', 'TeachersController#ajaxsearch');
do you know about error function in jquery ajax?
$(document).ready(function(){
$('#searchname').on('keyup', function(){
var text = $('#searchname').val();
$.ajax({
type:"GET",
url: 'teachers/search',
data: {text: $('#searchname').val()},
success:function(data){$('tbody').html(data);},
error:function(jqXHR){alert(jqXHR.status);}
});
});
});
You can try this,it will show error if there is some and text should be in inverted commas as it is a key value pair.
In your search controller you are accessing wrong input name. It should be like this
public function ajaxsearch(){
$searchname = Input::get ( 'text' );
if($searchname != ""){
$teacher = Teacher::where ( 'efirst', 'LIKE', '%' . $searchname . '%' )->paginate(10);
return response()->json($teacher);
}
}
First of all, just go to the URL manually and enter parameters.
http://todolist.local/teachers/search?text=a
If you get any response. It's mean your PHP working good.
If you get an error, you are using the GET method. Please pass the variable argument in Route
Route::get('/search/{searchName}', 'TeachersController#ajaxsearch');
and please correct your controller
public function ajaxsearch($searchname){
if($searchname != ""){
$teacher = Teacher::where ( 'efirst', 'LIKE', '%' . $searchname.'%' )->paginate(10);
return response()->json($teacher);
}
}
Second, Please $.get method in Jquery for GET Method AJAX
<script>
$(document).ready(function(){
$('#searchname').on('keyup', function(){
var text = $('#searchname').val();
$.get(urlHere, function(response){
console.log(response);
});
});
});
</script>
See your console tab, If you get response

How to increment a model attribute count?

I'm trying to make a very simple blog using Laravel and Ajax, each blog post has likes so i want to increment the likes by clicking and updating the DB also in console there is no errors.
this is my schema :
Schema::create('blogs', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->longText('blogContent');
$table->timestamps();
$table->integer('likes')->default(8);
});
here's my blade template and script :
#section('content')
<div class="myFeedContainer col-lg-9 col-md-12 col-sm-12">
#foreach ($blogs as $blog)
<div class='blogContainer'>
<h5 class='blogTitle'>{{$blog->title}}</h5>
<h6 class='blogDate'>{{$blog->created_at}}</h6>
<p class='blogContent1' >{{$blog->blogContent}}</p>
<hr>
<h6 class='blogLikes' class="clickforlikes" data-id='{{$blog->id}}'>
{{$blog->likes}}
<ion-icon name="heart" ></ion-icon>
</h6>
<br>
</div>
#endforeach
<div id='pagina'>{{ $blogs->render() }}</div>
<script>
$('.clickforlikes').on("click", function(){
$.ajax({
url:'updateLikes',
type: 'POST',
data: {
blog_id: $(this).attr('data-id')
},
success: function (data){
console.log(data);
},
error: function(request, stqtus, error){
console.log('code: ' + request.status + '\n' + 'msg: '+request.responseText+'\n'+'error: ' + error);
}
});
});
</script>
</div>
#endsection
And this is the function from my controller
public function updateLikes()
{
$blog_Id = $_POST['blog_id'];
$blog = Blog::find($blog_Id)->increment('likes');
$blog->save();
}
This is the router :
Route::post('/updateLikes', 'BlogsController#updateLikes');
You are trying to accomplish this the PHP way. Since you are using a framework, you should take advantage of its cool features. In Laravel, you would have to do something like this:
Router:
Route::put('updateLikes/{id}', 'BlogsController#updateLikes');
Controller:
public function updateLikes($id) { $blog = Blog::find($id)->increment('likes'); $blog->save(); }
Ajax call:
<script> $('.clickforlikes').on("click", function(){ $.ajax({ url:'updateLikes/'+$(this).attr('data-id'), type: 'PUT', success: function (data){ console.log(data); }, error: function(request, stqtus, error){ console.log('code: ' + request.status + '\n' + 'msg: '+request.responseText+'\n'+'error: ' + error); } }); }); </script>
The HTTP method is different because a POST request is meant to be used to create a new resource in the database. On the other hand, PUT is used to update a resource. Your ajax request will call the route with the id of the blog appended to it, and the controller will get the id as a parameter and perform the update.
You are using POST method. You can receive these data by Request Service Container in updateLikes() method.
public function updateLikes(Request $request)
{
$blog_Id = $request->get('blog_id');
$blog = Blog::find($blog_Id)->increment('likes');
// other codes if needed
}

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