Hi i'm new with prestashop 1.6 and i use jquery's $.ajax to call a PHP script . what i wan,t is to create new form when i click on button and this is my code :
in the catproduct.php :
public function clickme(){
$html = 'Click me
<div id="myFormm"></div>
<script type="text/javascript">
$( ".displayForm" ).click(function() {
$.ajax({
url: "'._MODULE_DIR_.$this->name.'/ajax.php",
context: document.body,
})
.done(function(data) {
$( "#myFormm" ).html( data );
alert( "Load was performed." );
});
})
</script>';
return $html;
}
public function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Add new category'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'text',
'label' => $this->l('FCI'),
'name' => 'FCI',
),
),
'submit' => array(
'title' => $this->l('Save')
)
),
);
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$this->fields_form = array();
$helper->identifier = $this->identifier;
$helper->submit_action = 'submitCatForm';
$helper->fields_value['FCI'] = 'ddddd';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='
.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
return $helper->generateForm(array($fields_form));
}
the ajax.php file (the ajax file call the renderForm() function to create new form):
require_once(dirname(__FILE__).'../../../config/config.inc.php');
require_once(dirname(__FILE__).'../../../init.php');
include_once('catproduct.php');
$module = new catproduct();
echo $module->renderForm();
the done function return nothing . please help me i spend two days searching for solution
Example of ajax call in Prestashop (front-office) :
$( document ).ready(function() {
var form = $('.MyForm');
form.submit(function(e) {
$.ajax({
type: 'POST',
url: '../modules/MyModule/controllers/front/MyFrontController.php',
data: $(this).serialize(),
dataType: 'json',
success: function(jsonData) {
console.log(jsonData);
}
});
e.preventDefault();
});
});
Console shows results. If not, there is a problem with php file.
Here is a sample of PHP file :
<?php
include(dirname(__FILE__).'/../../../../config/config.inc.php');
include(dirname(__FILE__).'/../../../../init.php');
include(dirname(__FILE__).'/../../classes/MyUsefulModuleClass.php');
if (Tools::getIsset('my_useful_id')) {
echo Tools::jsonEncode('Ajax return fine')); }?>
Check if config.inc.php and init.php are called. Always console.log() your results while working on it.
Then try to separate form creation, you can use only HTML, not sure if you can create forms using helpers, and show it using Ajax. I think that most of modules use HTML only
Related
I'm trying to add jQuery to the javascript.js file for a child of woodmart theme, but I keep getting "javascript.js:131 Uncaught ReferenceError: jQuery is not defined".
javascript.js
(function($){
jQuery(document).ready(function($) {
//cart_actions parent container
//for POST requests when user saves a cart
clickparent = document.querySelector(".cart-actions");
clickparent.addEventListener("click", function(e) { // e = event object
let carts = JSON.parse(window.localStorage.getItem('yithPOS_carts'));
if (e.target && (e.target.className == "cart-action cart-action--suspend-and-save-cart cart-action--with-icon") || e.target.className == "cart-action__icon yith-pos-icon-saved-cart") {
// Use ajax to do something...
var postData = {
action: 'wpa_49691',
my_var: 'carts',
}
$.ajax({
type: "POST",
data: postData,
dataType:"json",
url: youruniquejs_vars.ajaxurl,
//This fires when the ajax 'comes back' and it is valid json
success: function (response) {
console.log("Cart saved to database.");
}
//This fires when the ajax 'comes back' and it isn't valid json
}).fail(function (data) {
console.log(data);
});
}
});
//pos_current_Cart_buttons parent container
//for GET requests when user views saved carts
viewcartparent = document.querySelector(".yith-pos-cart__buttons");
viewcartparent.addEventListener("click", function(e) { // e = event object
if (e.target && (e.target.className == "yith-pos-cart__buttons-saved-carts")) {
// Use ajax to do something...
var getData = {
action: 'wpa_49692',
my_var: 'my_data',
}
$.ajax({
type: "GET",
data: getData,
dataType:"json",
url: youruniquejs_vars.ajaxurl,
//This fires when the ajax 'comes back' and it is valid json
success: function (response) {
let total;
for(item in response){
total += item[lineTotal];
}
$(".yith-pos-cart__savedcarts").append('</div><i class="yith-pos-cart__savedcart"></i><div class="cart-saved__name"><div class="cart-saved__name__id">' + response['id'] + '</div><div class="cart-saved__name__customer">' + response['cartitems']['names'] + '</div></div><div class="cart-saved__num_of_items">' + response['cartitems'].size + '</div><div class="cart-saved__status">Pending Payment</div><div class="cart-saved__total">'+ total + '</div><button class="btn btn-primary"><i class="yith-pos-icon-refresh"></i> load</button></div>');
}
//This fires when the ajax 'comes back' and it isn't valid json
}).fail(function (data) {
console.log(data);
});
}
});
// Handler for .ready() called.
});
})(jQuery);
I've also tried enqueuing jquery with wp_enqueue_script and passing jquery in an array to the javascript file, neither changed anything.
functions.php:
wp_enqueue_script('jquery');
//First enqueue your javascript in WordPress
function save_cart_enqueue_scripts(){
//Enqueue your Javascript (this assumes your javascript file is located in your plugin in an "includes/js" directory)
wp_enqueue_script( 'javascript.js', plugins_url('https://cigarchiefstg.wpengine.com/wp-content/themes/woodmart-child/yith-pos-additions/javascript.js', dirname(__FILE__) ), array( 'jQuery' ));
//Here we create a javascript object variable called "youruniquejs_vars". We can access any variable in the array using youruniquejs_vars.name_of_sub_variable
wp_localize_script( 'javascript', 'javascript_vars',
array(
//To use this variable in javascript use "youruniquejs_vars.ajaxurl"
'ajaxurl' => admin_url( 'javascript_vars.ajaxurl' ),
)
);
}
add_action( 'wp_enqueue_scripts', 'save_cart_enqueue_scripts' );
//This is your Ajax callback function
function cart_save_callback_function(){
//Get the post data
$my_var = $_POST["my_var"];
//Do your stuff here - maybe an update_option as you mentioned...
update_option('saved_carts', $my_var);
//Create the array we send back to javascript here
$return_array = array();
//Make sure to json encode the output because that's what it is expecting
echo json_encode( $return_array );
//Make sure you die when finished doing ajax output.
die();
}
add_action( 'wp_ajax_' . 'wpa_49691', 'cart_save_callback_function' );
add_action( 'wp_ajax_nopriv_' . 'wpa_49691', 'cart_save_callback_function' );
function cart_view_callback_function(){
//Get the post data
$my_var = $_POST["my_var"];
//Do your stuff here - maybe an update_option as you mentioned...
//Create the array we send back to javascript here
$carts = get_option('saved_carts');
//Make sure to json encode the output because that's what it is expecting
echo json_encode( $carts );
//Make sure you die when finished doing ajax output.
die();
}
add_action( 'wp_ajax_' . 'wpa_49692', 'cart_view_callback_function' );
add_action( 'wp_ajax_nopriv_' . 'wpa_49692', 'cart_view_callback_function' );
Edit: Issues with POS items:
first check if jquery is correctly loaded on you wp website.
I suggest using this syntax for jQuery:
(function($){
$(document).ready(function(){
//your code
})(jQuery);
I'm trying to get result and alert it if the solicitude was successful or not on the PHP file, it worked (because changed the results) but the AJAX didn't show alerts (No error and no "true")
js:
function addentrys() {
var nwentry = {};
el = document.getElementById('addname').value;
eldmn = document.getElementById('adddomain').value;
nwentry.name = el;
nwentry.domain = eldmn;
$.ajax({
type: 'POST',
url: 'api/domain',
dataType: 'json',
data: nwentry
}).done(function(data) {
alert(data);
});
}
php:
$app->post('/domain', function () {
$jsonContents = file_get_contents('data/data.json');
$name = $_POST['name'];
$domain = $_POST['domain'];
$data = json_decode($jsonContents, true);
$last_item = end($data);
$last_item_id = $last_item['id'];
$data[] = array(
'name' => $name,
'domain' => $domain,
'id' => $last_item_id+1
);
$json = json_encode($data);
file_put_contents('data/data.json', $json);
return true;
});
The result is probably not in JSON format, so when jQuery tries to parse it as such, it fails. You can catch the error with error: callback function.
You don't seem to need JSON in that function anyways, so you can also take out the dataType: 'json' row.
So, recently I have been dabbling a bit in cakephp but I have run into an issue I just can't seem to solve. I suspect it's something simple I'm missing (as most cases).
The premise of what I'm trying to do is somewhat self-explanatory in the title: I have a view (my add.ctp) within this add I have a form created with the form helper.
I have multiple selects, the first select is a list of companies. Once the company has been selected, I now want to update the next select based on the selected value using jquery and ajax sending a get request to the controller.
The AJAX request completes successfully however, I cannot seem to access the desirable returned data (a list of projects that belong to the selected company).
To be clear I'm trying to return an array in the success callback
I have read a lot and searched around, but I feel that maybe examples are lacking for v3 cakephp.
Some of my code :
Controller
$projectphase = $this->Projectphases->newEntity();
$data = ['content' => 'hi', 'error' => 'nothing found'];
$projects = array('0' => 'Select something');
if($this->request->is('ajax')){
$company_id = $this->request->data('company_id');
$projects = $this->Projectphases->Projects->find('list', ['limit' => 2, 'conditions' => ['company_id' => $company_id]]);
$arr = array();
$arr = $this->chainedProjects($company_id);
$data = ['content' => 'hello', 'error' => ''];
$this->set(compact('projects', 'data'));
$this->set('_serialize', ['projects', 'data']);
}elseif($this->request->is('post')){
debug("hit post");
die();
}
Public function chainedProjects
$projects = $this->Projectphases->Projects->find('list', ['limit' => 2, 'conditions' => ['company_id' => $id]]);
$projs = $projects->toArray();
$values = array();
$x = 0;
foreach ($projs as $key => $value) {
$values[$x] = "<option value='$key'>$value</option>";
$x++;
}
return $values;
Javascript [jquery ajax]
$(document).ready(function(){
$('#company').change(function () {
$company_id = $('#company').val();
var data = {
'type' : 'dropdown',
'company_id' : $company_id
};
$.ajax({
type : 'GET',
//url : 'delegate1/projectphases/add',
data : data,
encode : true,
beforeSend: function(xhr){
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
},
success: function(response){
console.log('success');
console.log(response.content);
console.log(response.message);
//console.log(data.response);
//console.log(result.content);
console.log(response);
}
}).done(function(){
console.log('done');
})
});
})
Jquery 2.1.3
Any help whatsoever will be appreciated!
Using jQuery to call an endpoint and populate the data on the frontend is a common task. After searching and using multiple solutions the below is my current blueprint for any ajax calls.
How can I improve the following to be faster and more efficient? I realize doing it in pure javascript will be faster but at this point I assume jQuery will be present.
Frontend - Javascript:
$(document).ready(function()
{
function callEndpoint( call_url, payload ){
return $.ajax({
url: call_url,
type: 'GET',
data: payload
});
}
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = callEndpoint( '/play/endpoint2.php', { 'type': sSelected } );
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Frontend - Html:
<body>
<button class="get-endpoint">Games</button>
<button class="get-endpoint">Books</button>
<button class="get-endpoint">Comics</button>
<div class="from-endpoint">Coming soon...</div>
</body>
Backend - PHP:
$aReturn[ 'text' ] = '';
if( !empty( $_GET ) )
{
if( $_GET[ 'type' ] == 'Games' )
{
$aReturn[ 'text' ] = 'Text for games';
}
else if( $_GET[ 'type' ] == 'Books' )
{
$aReturn[ 'text' ] = 'Text for books';
}
else if( $_GET[ 'type' ] == 'Comics' )
{
$aReturn[ 'text' ] = 'Text for comics';
}
}
$sJson = json_encode( $aReturn, 1 );
header( 'Content-Type: application/json' );
echo $sJson;
I don't think that this code can be more efficient in jQuery.
But you have some options left to give a more efficient feeling :
You can use pagination to get a portion of your data each time. The
less data to load, the quicker it get. And your application will be
more responsive to the user's actions. This solution is a trick for
the user, because it will take in reality more time than before to load all the data.
You can keep previous loaded data so when you click back on a button,
it won't load again the data. But, this can only be used if the data
won't change much between each click. The first time you will click
on a button, it will take the same time as before, but the next time,
it will be immediat.
Be aware that the more HTML code you load, the more it will take time to initiate JavaScript behavior on it.
Looks like your categories won't change often. You can save some bandwidth by using JavaScript localstorage or cookies to cache data. If you plan on connecting to a mysql database at somepoint you can use StoredProcedures which are variablized precompiled statements.
Since you are anyways going to use JSON and jQuery, I would suggest that you should check out the getJSON method of jQuery. I feel that it would reduce some lines of code, though I am not sure if it would help it become more efficient.
Anyways getJSON is just a shorthand of AJAX and I thought I should suggest this.
This could be a good approach for AJAX data transport browser->server->browser. Hope it suites your needs.
jQuery
$( function () {
function fetch( data ) {
var encoding = data.encoding,
url = data.url,
params = data.params,
type = ( data.type ) ? : 'GET',
cache = ( data.cache ) ? : 'false',
async = ( data.async ) ? : 'true';
return $.ajax({
url: url,
async: async,
cache: cache,
data: params,
dataType: encoding,
type: type
});
}
var options = {
url: 'controller.php',
params: {
param_one: value_one,
param_two: value_two,
param_n: value_n
},
encoding: 'json'
};
// Get the JSON feed from the server
$.when( fetch( options ) ).then( function ( response ) {
// Is there anything in the pool?
if ( response ) {
// Store the response and use it in your code
var data = response.data;
console.log( data.responseOne );
console.log( data.responseTwo );
}
});
});
PHP Controller
// Set header to application/json
header( 'Content-type: application/json' );
// Create the DB connection object
$dbc = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME );
// Initialize parameters array
$params = array();
// Store the query variables in an array
$query_type = ( $_GET ) ? : $_POST;
// Run foreach and store the values in an array
foreach ( $query_type as $key => $value ) {
$params[ $key ] = mysqli_real_escape_string( $dbc, $value );
}
// Now you can access passed parameters like $params['param_name']
// This would be the data obtained from DB or some server array processing, whatever
$response = array(
'data' => array(
'response_one' => 'some_value',
'response_two' => 'another_value'
)
);
// Encode the result
echo json_encode( $response );
If you don't want use pure javascript, you can improve your jQuery code with better selectors
For example, you can add an id in <div class="from-endpoint">
You can add tag in selector like this:
$('button.get-endpoint')
You can drop your getEndpoint method and just use the $.get method.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { 'type': sSelected });
oRequest.done(function( sJson ) {
aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
You can make your code lint compliant.
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
oRequest = $.get('/play/endpoint2.php', { type: sSelected });
oRequest.done(function( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
});
});
});
Use success instead of done & move the callback to it's own function
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.get(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( sJson ) {
var aData = JSON.parse( sJson );
$( '.from-endpoint' ).text( aData.text );
}
Use $.getJSON instead of $.get or $.ajax
$(document).ready(function()
{
$( '.get-endpoint' ).click( function() {
var sSelected = $( this ).text();
console.log( sSelected );
$.getJSON(
'/play/endpoint2.php',
{ type: sSelected },
insertData
);
});
});
function insertData( data ) {
$( '.from-endpoint' ).text( data.text );
}
in order to set two dependent drop downs i'm using jQuery.ajax, but i have some troubles and i think the url of the controller action i set on my $.ajax is not accessible.
this is my controller action code :
public function fillIncidentsAction()
{
$request = $this->getRequest();
if ($request->isPost())
{
$code_categ = (int) $request->getPost('code_categ',0);
$data = new JsonModel(array(
'success' => true,
'results' => $this->getTableInstance('TypeIncidentTable')
->getListTypeIncident($code_categ),
));
return $data;
}
}
and this is the main part of my js function
$('#'+source).change(function() {
if($('#'+source).val() != '')
{
$.ajax({
type: 'POST',
async: false,
url: url,
cache: true,
dataType: 'json',
data: { code_categ: $('#'+source).val() },
success: function(data){
alert(data.success);//<------ i added this to test if this function is executed or not
if(data.success)
{
$('#'+target).prop('disabled', true);
if(data.results != ""){
var options = new Array();
$.each(data.results, function(key, value){
options[((key) ? key : 0)] = '<option value="' + key + '">' + value + '</option>';
});
$("#"+target).html(options.join(''));
$('#'+target).prop('disabled', false);;
}
}
},
});
I don't know where i'm wrong. Any suggestions?
Thanks for help !
Sorry, this is how i set my url :
<script type="text/javascript">
$(document).ready(function() {
var url = "<?php echo $var =$this->url('gims/default', array('controller' => 'evenement', 'action' => 'fill_incidents')); ?>";
// initialize the js function
dependentDropDown('firstList','secondList',url);
});
</script>
Hope this will give you more details.
The problem was in my moodule.config.php, i haven't enabled the Json strategy.
'view_manager' => array(
//...
'strategies' => array(
'ViewJsonStrategy',
),
),