Controller Ajax request Codeigniter 4 - php

Hi guys I'm new to CodeIgniter I'm still figuring out things here. So I have a problem about the ajax request it seem that the controller is not accepting the ajax request. I`m using CodeIgniter 4.0 by the way. I have search a lot of material in the internet and YouTube but still nothing works.
So here's the code in the view folder named layout.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="{csrf_header}" content="{csrf_hash}">
<title>Ajax test</title>
</head>
<body>
<!-- <form method="post" action="ajaxtest"> -->
<div>
<button type="submit" id="test">test Ajax</button>
</div>
<!-- </form> -->
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script type='text/javascript'>
$(document).ready(function() {
//var tokenName = $('#token').attr("name");
//var tokenVal = $("#token").val();
// alert(tokenName)
// alert(tokenVal)
$('#test').on('click', function() {
// alert('ok');
$.ajax({
url: "<?php echo base_url(); ?>/ajaxtest",
data: {
[tokenName]: tokenVal
},
method: "post",
success: function(response) {
alert('ok')
},
error: function(xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
});
});
</script>
</body>
</html>
And heres the code in controller
<?php
namespace App\Controllers;
// defined('BASEPATH') or exit('No direct script access allowed');
class AjaxController extends BaseController
{
public function index()
{
if ($this->request->getMethod() == 'post') {
echo 'post request done, ';
if ($this->request->isAJAX()) {
return 'the request is ajax';
} else {
return 'the request is not ajax';
}
}
echo view('layout');
}
}
Here`s the code inside the routes.php
<?php
namespace Config;
// Create a new instance of our RouteCollection class.
$routes = Services::routes();
// Load the system's routing file first, so that the app and ENVIRONMENT
// can override as needed.
if (is_file(SYSTEMPATH . 'Config/Routes.php')) {
require SYSTEMPATH . 'Config/Routes.php';
}
/*
* --------------------------------------------------------------------
* Router Setup
* --------------------------------------------------------------------
*/
$routes->setDefaultNamespace('App\Controllers');
$routes->setDefaultController('Home');
$routes->setDefaultMethod('index');
$routes->setTranslateURIDashes(false);
$routes->set404Override();
// $routes->setAutoRoute(true);
// The Auto Routing (Legacy) is very dangerous. It is easy to create vulnerable apps
// where controller filters or CSRF protection are bypassed.
// If you don't want to define all routes, please use the Auto Routing (Improved).
// Set `$autoRoutesImproved` to true in `app/Config/Feature.php` and set the following to true.
//$routes->setAutoRoute(false);
/*
* --------------------------------------------------------------------
* Route Definitions
* --------------------------------------------------------------------
*/
// We get a performance increase by specifying the default
// route since we don't have to scan directories.
$routes->get('/', 'Home::index');
$routes->match(['get', 'post'], 'ajaxtest', 'AjaxController::index');
// $routes->get('ajaxtest', 'AjaxController::index');
// $routes->post('ajaxtest/success', 'AjaxController::success');
/*
* --------------------------------------------------------------------
* Additional Routing
* --------------------------------------------------------------------
*
* There will often be times that you need additional routing and you
* need it to be able to override any defaults in this file. Environment
* based routes is one such time. require() additional route files here
* to make that happen.
*
* You will have access to the $routes object within that file without
* needing to reload it.
*/
if (is_file(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) {
require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php';
}
Now what Im doing here is just trying to test if ajax works and return something. If I uncomment the form tag in the layout file the request works fine but I need the request given by ajax not in the form tag so I wont use it but if I use the ajax it wont respond anything and there is no error like in ci4 and the jquery. But the weird thing is that when I use post man and send ajax request it works perfectly fine. Can someone point out what Im missing here?

Here is the solution.
Some change in your ajax function.
var value1 = 1;
var value2 = "val2";
$.ajax({
url: "<?php echo base_url(); ?>/ajaxtest",
data: {
"key1": value1,
"key2": value2
}, // data will be set as key value pair
method: "post",
success: function (response) {
consol.log(response); // to view your response from controller in webbrowser's console
alert(response.message); // alret response message
// alert('ok');
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
Some change in your controller function
public function index() {
$this->load->view('layout');
}
public function ajax()
{
$data = [];
if($this->input->post()){
$data['message'] = 'the request is ajax post';
$data['data'] = $this->input->post(); // get data from ajax function's data object
}else{
$data['message'] = 'the request is not ajax post';
}
return response()->json($data);
}
Some change in your routes.php
// $routes->match(['get', 'post'], 'ajaxtest', 'AjaxController::index');
$routes->get('ajaxtest', 'AjaxController::index');
$routes->post('ajaxtest', 'AjaxController::ajax');

Related

CodeIgniter ajax link not found

I'm having an issue with getting data from Controller, I have tried all the solutions here but it's the same..
when I click on the button it says 404 not found, if I change the URL to completed URL included the controller class name + function name, it says 403
Here is my view code :
<h2>Quiz</h2>
<script type="text/javascript">
$(document).ready(function(){
var BASE_URL = '<?php echo base_url(); ?>';
$('#show').click(function(e){
console.log(BASE_URL);
$.ajax({
url: BASE_URL + "Quiz/get_item",
dataType:'text',
type:"POST",
success: function(result){
var obj = $.parseJSON(result);
console.log(obj);
}
})
})
});
</script>
<button id="show">Show Cutomers</button>
<div id="customers-list"></div>
<p>Our first multi-page CodeIgniter application! Each page has its own controller and view!</p>
Here is my Controller code :
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Quiz extends CI_Controller {
var $TPL;
public function __construct()
{
parent::__construct();
$this->load->model('Quiz_data');
// Your own constructor code
}
function show_customers()
{
$query = $this->db-> query("SELECT * FROM quiz ORDER BY id;");
$this->TPL['listing'] = $query->result_array();
$this->template->show('quiz', $this->TPL);
}
public function index()
{
$this->template->show('quiz', $this->TPL);
}
public function get_item(){
$data = $this ->Quiz_data->get_data();
echo json_encode($data);
}
}
Here is my Model code :
<?php
class Quiz_data extends CI_Model {
public function get_data()
{
$query = $this->db->get('quiz');
return $query -> result_array();
}
}
What is the output of
console.log(BASE_URL);
Didnt mess with CI for quite a while, but it used to need /index.php/ in the URL. Try:
url: BASE_URL + "/index.php/quiz/get_item",
Although the controller-name needs to start with a capital, it doesnt need to be called that way in the URL.
Make sure url: BASE_URL + "Quiz/get_item" provides the correct URL.
var BASE_URL = '<?php echo base_url(); ?>'; May not provide trailing slash and you won't get correct url.
Try updating your call with following:
url: BASE_URL + "/Quiz/get_item",

AJAX POST request in Laravel [duplicate]

This question already has answers here:
jQuery add CSRF token to all $.post() requests' data
(7 answers)
Closed 4 years ago.
I have an AJAX request which is a GET request.
/**
* AJAX Like function
*/
$(".like").click(function (e) {
e.preventDefault(); // you dont want your anchor to redirect so prevent it
$.ajax({
type: "GET",
// blade.php already loaded with contents we need, so we just need to
// select the anchor attribute href with js.
url: $('.like').attr('href'),
success: function () {
if ($('.like').hasClass('liked')) {
$(".like").removeClass("liked");
$(".like").addClass("unliked");
$('.like').attr('title', 'Like this');
} else {
$(".like").removeClass("unliked");
$(".like").addClass("liked");
$('.like').attr('title', 'Unlike this');
}
}
});
});
Where the URL is: http://127.0.0.1:8000/like/article/145
And is grabbed via the href attribute of .like, the markup of which looks like this:
<div class="interaction-item">
#if($article->isLiked)
<a href="{{ action('LikeController#likeArticle', $article->id) }}" class="interactor like liked" role="button" tabindex="0" title="Unlike this">
#else
<a href="{{ action('LikeController#likeArticle', $article->id) }}" class="interactor like unliked" role="button" tabindex="0" title="Like this">
#endif
<div class="icon-block">
<i class="fas fa-heart"></i>
</div>
</a>
</div>
The LikeController looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Like;
use App\Article;
use App\Event;
use Illuminate\Support\Facades\Auth;
class LikeController extends Controller
{
/**
* Display all liked content for this user
*/
public function index()
{
$user = Auth::user();
$articles = $user->likedArticles()->get();
$articleCount = count($articles);
$events = $user->likedEvents()->get();
$eventCount = count($events);
return view('pages.likes.index', compact('articles', 'articleCount', 'events', 'eventCount'));
}
/**
* Handle the liking of an Article
*
* #param int $id
* #return void
*/
public function likeArticle($id)
{
// here you can check if product exists or is valid or whatever
$this->handleLike(Article::class, $id);
return redirect()->back();
}
/**
* Handle the liking of an Event
*
* #param int $id
* #return void
*/
public function likeEvent($id)
{
// here you can check if product exists or is valid or whatever
$this->handleLike(Event::class, $id);
return redirect()->back();
}
/**
* Handle a Like
* First we check the existing Likes as well as the currently soft deleted likes.
* If this Like doesn't exist, we create it using the given fields
*
*
* #param [type] $type
* #param [type] $id
* #return void
*/
public function handleLike($type, $id)
{
$existingLike = Like::withTrashed()
->whereLikeableType($type)
->whereLikeableId($id)
->whereUserUsername(Auth::user()->username)
->first();
if (is_null($existingLike)) {
// This user hasn't liked this thing so we add it
Like::create([
'user_username' => Auth::user()->username,
'likeable_id' => $id,
'likeable_type' => $type,
]);
} else {
// As existingLike was not null we need to effectively un-like this thing
if (is_null($existingLike->deleted_at)) {
$existingLike->delete();
} else {
$existingLike->restore();
}
}
}
}
I think it's extremely bad practice to update a database via a GET request
So, I changed the Route to use POST and updated the AJAX call to:
/**
* AJAX Like function
*/
$(".like").click(function (e) {
e.preventDefault(); // you dont want your anchor to redirect so prevent it
$.ajax({
type: "POST",
// blade.php already loaded with contents we need, so we just need to
// select the anchor attribute href with js.
url: $('.like').attr('href'),
data: {
_token: '{{ csrf_token() }}'
},
success: function () {
if ($('.like').hasClass('liked')) {
$(".like").removeClass("liked");
$(".like").addClass("unliked");
$('.like').attr('title', 'Like this');
} else {
$(".like").removeClass("unliked");
$(".like").addClass("liked");
$('.like').attr('title', 'Unlike this');
}
}
});
});
As you can see, I've changed the method and added in the CSRF token, however, I get an error:
POST http://127.0.0.1:8000/like/article/145 419 (unknown status)
send # app.js:14492
ajax # app.js:14098
(anonymous) # app.js:27608
dispatch # app.js:10075
elemData.handle # app.js:9883
app.js:14492 XHR failed loading: POST "http://127.0.0.1:8000/watch/article/145".
What is the best way to debug what's going on?
Update
By adding: <meta name="csrf-token" content="{{ csrf_token() }}"> would it interfer with my normal use of `#csrf' in my forms?
Also, I added a fail callback to the request
}).fail(function (jqXHR, textStatus, error) {
// Handle error here
console.log(jqXHR.responseText);
});
Another update
As you have all kindly pointed out, in the documentation here, it does indeed say, set the meta CSRF attribute, I even had an error in my console saying this wasn't defined, but I misinterpreted the error.
Why though, in some tutorials, do people add the CSRF token to the data array?
Look at this. You can't use {{ csrf_token() }} in your JS.
Try this in your html :
<meta name="csrf-token" content="{{ csrf_token() }}">
And this in your JS :
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
If you have multiple ajax call in single file then you can do via this. The following code will working for all your AJAX requests.
Try this in your html :
<meta name="csrf-token" content="{{ csrf_token() }}">
And this in your JS :
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});

Display id using ajax to controller

Hello I am new in ci and i want to pass is from view to controller in codeigniter using ajax. if i add dataType : 'json', then my ajax can not work and i want to echo data from controller
<script type="text/javascript">
$(document).ready(function() {
$(".cart").click(function(){
var subid=$(this).attr('data-index');
alert(subid);
$.ajax({
url: '<?php echo site_url(); ?>/Home/add_to_cart',
type: "POST",
data: {
subid: subid
},
dataType:'json',
success: function(data) {
window.location.href = '<?php echo base_url(); ?>index.php/Home/add_to_cart';
alert(data);
},
error: function(xhr, status, error) {
var error=xhr.responseText;
// alert(error);
}
});
});
});
</script>
Controller
I want to echo the category id when the ajax can send the request
$category_id = $this->input->post('subid');
echo json_encode($category_id);
Well here is all information what Freshers need to handle in CodeIgniter :)
First remove 'index.php' from CodeIgniter url via .htaccess. Create .htaccess file where CodeIgniter 'index.php' exist.
.htaccess (Using windows, just rename any blank text file as .htaccess. to create a .htaccess file, So easy ...)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [PT,L]
</IfModule>
How to enable mode_rewrite in WAMP
How to enable mode_rewrite in WAMP manualy
1 - Open apache’s configuration file using your favorite text editor.
2 - The configuration file generally locates at:{apache_dir}/conf/httpd.conf
3 - If you are using XAMPP or WAMP package then you will find the file
at:{xampp_dir}/bin/apache/apache-xxx/conf/httpd.conf or {wamp_dir}/bin/apache/apache-xxx/conf/httpd.conf
4 - Search for the following string:#LoadModule rewrite_module modules/mod_rewrite.so and uncomment it (remove the ‘#’ sign).
5 - Now search for another string AllowOverride None and replace it by AllowOverride All
6 - Finally Save the changes, close your text editor and Restart your apache server.
Set 'base_url' automatically
/*
|--------------------------------------------------------------------------
| Dynamic Base Url
|--------------------------------------------------------------------------
| Put below code in 'index.php' on top
|
*/
define('APP_URL', ($_SERVER['SERVER_PORT'] == 443 ? 'https' : 'http') . "://{$_SERVER['SERVER_NAME']}".str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']));
Config Settings
/*
|--------------------------------------------------------------------------
| Base Site URL
|--------------------------------------------------------------------------
|
| URL to your CodeIgniter root. Typically this will be your base URL,
| WITH a trailing slash:
|
| http://example.com/
|
| If this is not set then CodeIgniter will guess the protocol, domain and
| path to your installation.
|
*/
$config['base_url'] = APP_URL;
/*
|--------------------------------------------------------------------------
| Index File
|--------------------------------------------------------------------------
|
| Typically this will be your index.php file, unless you've renamed it to
| something else. If you are using mod_rewrite to remove the page set this
| variable so that it is blank.
|
*/
$config['index_page'] = '';
Config CSRF Settings (If you are not passing CSRF token in form, or not using CodeIgniter Form Helper. Otherwise you will not able to POST param or call Controller Method via ajax or Form POST)
$config['csrf_protection'] = FALSE;
Now, Questions Answer :(
JavaScript
<script type="text/javascript">
$(document).ready(function() {
// define base url
var _CI_BASE_URL_ = "<?php echo site_url(); ?>";
/**
* ---------------------------
* Example -1 with Url Params
* ---------------------------
*/
// on click cart button call ajax
$(".cart").click(function(e){
// stop default button behaviour
e.preventDefault();
// get subid from button attr
var subid = $(this).data('index');
// ajax function
$.ajax(
{
// *Notice: just send 'subid' with ajax url and CodeIgniter will take it from url
url: _CI_BASE_URL_ + 'home/add_to_cart/' + subid,
// method
type: "POST",
// data type
dataType:'json',
// success callback
success: function(data) {
// why server response, we already have subid in JavaScript vars
// we can user that same to redirect in url
window.location.href = _CI_BASE_URL_ + 'home/add_to_cart/' + subid;
},
// ohh! we got error
error: function(xhr, status, error) {
// get ajax error
var error = xhr.responseText;
alert('Request made some error: ' + error);
}
});
});
/**
* ---------------------------
* Example -2 with POST Params
* ---------------------------
*/
// on click cart button call ajax
$(".cart").click(function(e){
// stop default button behaviour
e.preventDefault();
// get subid from button attr
var subid = $(this).data('index');
// ajax function
$.ajax(
{
// just send subid with url and CodeIgniter will take from url
url: _CI_BASE_URL_ + 'home/add_to_cart_another',
// method
type: "POST",
// POST params
data: {subid: subid},
// data type
dataType:'json',
// success callback
success: function(data) {
// if got the JSON with key cat_id
if(data.cat_id){
// if you want to alert, first alert then redirect
alert('CodeIginter retuned Cat ID: ' + data.cat_id);
// redirect user now..
window.location.href = _CI_BASE_URL_ + 'home/add_to_cart_another/' + data.cat_id;
}else{
alert('Category ID not return or null...');
}
},
// ohh! we got error
error: function(xhr, status, error) {
// get ajax error
var error = xhr.responseText;
alert('Request made some error: ' + error);
}
});
});
});
</script>
Now CodeIgniter Controller :( :(
<?php
// Security First Matters...
(defined('BASEPATH') or exit('No direct script access allowed'));
/**
* Class Home CI Controller
*/
class Home extends CI_Controller
{
/**
* Default run method
* #return [type] [description]
*/
public function index()
{
$this->load->view('home');
}
/**
* [add_to_cart description]
* #param [type] $cat_id [description]
*/
public function add_to_cart($cat_id)
{
/**
* Codeigniter is enough smart to take parameters if passed in url
* if url is 'http://localhost/CodeIgniter/home/add_to_cart/100'
* '100' will be assign to $cat_id by CodeIgniter
*
* intval to make sure only integer
*/
// echo response for ajax call as JSON
echo json_encode(array('cat_id' => intval($cat_id)));
}
/**
* [add_to_cart description]
* #param [type] $cat_id [description]
*/
public function add_to_cart_another()
{
/**
* get cat id from post and sanitize by passing 2nd param as true for XSS Clean,
* Security always matters...
*
* intval to make sure only integer
*/
$cat_id = $this->input->post('subid', true);
// echo response for ajax call as JSON
echo json_encode(array('cat_id' => intval($cat_id)));
}
}
/* End of file home.php */
/* Location: ./application/controllers/home.php */
Now, I am going to sleep.. :D Tada!! ....
It is very simple, In your Controller funtion add_to_cart just do it like this:
$category_id = $this->input->post('subid');
echo $category_id;
Just dont add json_encode() of it.
Then if you want to return to your ajax request just do it like this
success: function(data) {
alert(data);
},
That should be work.
just comment if it is not work.
Thanks,
In Controller echo with header like this
php :
header("Content-Type: application/json", true);
echo json_encode(array('id'=>$category_id));
Ajax : change your success function code order
success: function(data) {
console.log(data);
temp = JSON.parse(data);
alert(temp.id);
//window.location.href = '<?php echo base_url(); ?>index.php/Home/add_to_cart';
},
Try this
$.ajax({
type:'POST',
url:'<?php echo base_url();?>.'/Home/add_to_cart',
data:{'subid':subid},
success:function(data){
//location.reload();
}
});

how to get an array field value from a PHP file using jquery/Ajax in Symfony2?

I am developing a social network web site using Symfony2. In fact, I would like to know how I can get an array field value from a PHP file using jquery/Ajax in Symfony2. Among the files that I have in my project folder there are two files: test.html.twig and moslem1.php. The code of each of that two files is below:
The code of test.html.twig:
<html>
<head>
</head>
<body>
<script src="{{asset('bundles/moslemtest/src/jquery.min.js')}}" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
url: '{{asset('bundles/moslemtest/phptest/moslem1.php')}}',
type: 'POST',
dataType: 'JSON',
success: function(data1) {
var id=data1.id;
document.write(id);
}
});
});
</script>
</body>
</html>
The code of moslem1.php:
<?php
$con=mysqli_connect("localhost","root","","test");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM jqcalendar ORDER BY id DESC LIMIT 0, 1");
while($row = mysqli_fetch_array($result)) {
$notification = array('id'=>$row['Id'],'subject'=>$row['Subject'],'location'=>$row['Location'],'description'=>$row['Description'],'starttime'=>$row['StartTime'],'endtime'=>$row['EndTime']);
}
echo json_encode($notification);
mysqli_close($con);
?>
The issue is whenever I run the file test.html.twig it displays the out below:
undefined
What is strange is that it works when I put the code of the file test.html.twig in a html file. in fact I created two other files (not in Symfony2) which are t1.html and moslem1.php. their codes are as below:
The code of t1.html:
<html>
<head>
</head>
<body>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
url: 'moslem1.php',
type: 'POST',
dataType: 'JSON',
success: function(data1) {
var id=data1.id;
document.write(id);
}
});
});
</script>
</body>
</html>
The code of moslem1.php:
<?php
$con=mysqli_connect("localhost","root","","test");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM jqcalendar ORDER BY id DESC LIMIT 0, 1");
while($row = mysqli_fetch_array($result)) {
$notification = array('id'=>$row['Id'],'subject'=>$row['Subject'],'location'=>$row['Location'],'description'=>$row['Description'],'starttime'=>$row['StartTime'],'endtime'=>$row['EndTime']);
}
echo json_encode($notification);
mysqli_close($con);
?>
As I said above, it works when I deal with a HTML file, but as I work on Symfony2 I have to use files with "html.twig" extension for view(output). So my question is what shall I do to make it works correctly with my twig file?
Thanks in advance.
It's a very bad idea to put the php file into the bundles folder, it's a huge security issue. If you want an AJAX response then put it into the Controller.
Create a new action in the Controller as you normally do. Write the AJAX action and give back a JSONResponse as a response.
/**
* Return an ajax response
*/
public function ajaxAction(){
// do the controller logic
// $response is an array()
return new JSONResponse($response);
}
Then in jQuery ajax set the url like this:
$.ajax({
url: 'url/to/your/controller', // If you use the FOSJsRoutingBundle then it will be Routing.generate('route_name')
type: 'POST',
dataType: 'JSON',
success: function(data1) {
var id=data1.id;
document.write(id);
}
});
In the new action you can use the EntityManager to access your database.
Here is a good article about this issue: http://symfony2forum.org/threads/5-Using-Symfony2-jQuery-and-Ajax
You should also consider to use the FOSJsRoutingBundle for javascript routing.
It's a very great bundle that allows you to generate routes in javascript files as you can do it in twig with the path('path_name') command.
Here is the GitHub project for this bundle: https://github.com/FriendsOfSymfony/FOSJsRoutingBundle
Try to understand the Symfony Request -> Response process, because if you don't follow it, it will cause serious problems for you.
http://symfony.com/doc/current/book/http_fundamentals.html
http://symfony.com/doc/current/book/page_creation.html

Using AJAX in a backoffice PrestaShop module

I'm creating a module for the shopping cart PrestaShop so I have to follow a set framework of rules when creating a module that will work in their system, and I want to submit forms via AJAX without reloading the page.
Here is a trimmed version of the module page which builds and determines what is displayed:
<?php
class mymodule extends Module
{
private $_html = '';
// Module information
function __construct()
{
// Get shop version
$versionMask = explode('.', _PS_VERSION_, 3);
$versionTest = $versionMask[0] > 0 && $versionMask[1] > 3;
// Module info
$this->name = 'MyModule';
$this->tab = $versionTest ? 'administration' : 'Administration';
if ($versionTest) { $this->author = 'JD'; }
$this->version = '0';
parent::__construct();
$this->displayName = $this->l('MyModule');
$this->description = $this->l('Description...');
}
// Display content
public function getContent()
{
$this->_displayForm();
return $this->_html;
}
// Build the display
private function _displayForm()
{
$this->_html .= '<script src="../modules/mymodule/scripts.js" type="text/javascript"></script>
<form name="formName" id="formName" method="get">
<input type="submit" name="submitModule" value="Continue" />
</form>';
}
}
?>
Normally there is a private _postProcess function which processes form data which then calls the function getContent on page reload where you can then check to see if it should show the form or the results etc.
But since I want to do this with AJAX, I've removed the _postProcess function as it's not needed, linked to my scripts.js which has the following:
$(document).ready(function() {
$('#formName').submit(function(e)
{
e.preventDefault();
$.ajax({
url: "ajax.php",
type: "GET",
dataType: "json",
success: function(data)
{
if (data.response == 1)
{
alert('true');
}
else
{
alert('false');
}
}
});
});
});
And the ajax.php file itself which I've really trimmed down so it's forced to show a result:
<?php
$json['response'] = 1;
echo json_encode($json);
exit();
?>
But I always get the error Uncaught TypeError: Cannot read property 'response' of null, which is obviously telling me the data.response isn't being sent through properly as it doesn't know what response is.
If I test the pages manually, everything works fine, so it leads me to believe either it has something to with the fact it could be in a class perhaps? And that I have to do something different to usual to get it to send the data through?
Or PrestaShop doesn't allow modules to run via AJAX, yet the only thing I can find on their site which relates to this is someone asking the same question in their forum and it has no replies/fixes.
I'd also like to note the AJAX is working to an extent, that if in the success function I put alert("hello"); the alert popup is shown.
Does anyone have any ideas where I might be going wrong?
Uncaught TypeError: Cannot read property 'response' of null scripts.js:132
$.ajax.success scripts.js:132
o jquery-1.7.2.min.js:2
p.fireWith jquery-1.7.2.min.js:2
w jquery-1.7.2.min.js:4
d
scripts.js:132 refers to the line: if (data.response == 1)
Also I've taken it out of the class and put it on a normal page/seperate directory and have the same code, just not inside the class/functions:
index.php
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="scripts.js" type="text/javascript"></script>
<form name="formName" id="formName" method="get">
<input type="submit" name="submitModule" value="Continue" />
</form>
scripts.js
$(document).ready(function() {
$('#formName').submit(function(e)
{
e.preventDefault();
$.ajax({
url: "ajax.php",
type: "GET",
dataType: "json",
success: function(data)
{
if (data.response == 1)
{
alert('true');
}
else
{
alert('false');
}
}
});
});
});
ajax.php
<?php
$json['response'] = 1;
echo json_encode($json);
exit();
?>
And when I submit the page I get the alert true and if I view ajax.php I get {"response":1}. So that code itself is ok, it's just integrating it with their class/functions.
It appears the path to the ajax.php file in the scripts.js file was causing the problem.
It's to do with the structure of the folders in prestashop, all modules are placed in /prestashop/modules/ directory but the modules are viewed from /prestashop/admin/. So changing them to the full paths fixed the problem.
Thanks to the guys that helped on here though, it's still appreciated!
I think your result is being sent ok, but not interpreted as JSON, a bit of the jquerys fault - I dare to say.
header('Content-Type: text/javascript; charset=utf8');
Putting this in the PHP script should do the trick and force the correct interpretation of the json the data.
If the previous suggestion didn't get you anywhere also try using $.parseJson(); as in jQuery docs:
var obj = jQuery.parseJSON('{"name":"John"}');
alert( obj.name === "John" );

Categories