Jump to content
Deadpool

AJAX Request to Custom Admin Module Controller

Recommended Posts

Hi Guys,

I am using Prestashop 1.7 and I created custom admin module controller class. What is the proper way to call a method inside my controller using AJAX request?

For example:

class AdminFooBarController extends ModuleAdminController
{
    public function ajaxProcessGetBar()
    {
		return 'foo';
    }
}

 

and in the backoffice template I have:

$.ajax({
  type: 'POST',
  cache: false,
  dataType: 'json',
  url: 'ajax-tab.php', // not sure about this part
  data: {
    ajax: true,
    controller: 'AdminFooBar',
    action: 'GetBar',
    token: token
  },
  success: function (data) {
    // something magical 
  }
});

I can't seem to get it work.

Thanks

  • Like 1

Share this post


Link to post
Share on other sites

Hello:

Your controller code seems to be right. Try this with the JS:

$.ajax({
  type: 'POST',
  cache: false,
  dataType: 'json',
  url: 'index.php', // fix this
  data: {
    ajax: true,
    controller: 'AdminFooBar',
    action: 'getBar', // prestashop already set camel case before execute method
    token: token
  },
  success: function (data) {
    // something magical 
  }
});

Regards

  • Thanks 1

Share this post


Link to post
Share on other sites

try this,

$.ajax({
            type: 'POST',
            dataType: 'json',
            url: 'ajax-tab.php',
            data: {
                ajax: true,
                controller: 'AdminFooBar',
                action: 'youraction', // small letter case
                var1: your_variable, // if you want to send some var
                token: $('#your_DOM_identifier').attr('data-token'), // your token previously set in your DOM element
            },
        })
            .done(function (data) {
}

 

Share this post


Link to post
Share on other sites

Thanks for Your responses. Unfortunately both of propose solution didn't work. 

The payload looks as follows:

  • request url is {my_domain}/admin/index.php
  • form data: ajax=true&controller=AdminFooBar&action=getbar&token={token}

Although the response results in 200, no data is return back. Only security template "INVALID SECURITY TOKEN". 

Any ideas?

Share this post


Link to post
Share on other sites

How do you return your data from the php function ?

Instead of 

return $result;

you can try

 die(Tools::JsonEncode($result));

 

Edited by fanie (see edit history)

Share this post


Link to post
Share on other sites

Believe it or not, i think the only error was ajax: true instead of ajax: 1.

This worked FINALLY for me:

	var postdata = {
		ajax: 1,
		controller: 'AdminFooBar',
		action: 'getBar',
		token: token
	  };
	$.ajax({
	  type: 'POST',
	  url: 'index.php',
	  data: postdata,
	  success: function(r){
		//magic
	  }
	});

 

Share this post


Link to post
Share on other sites
On 2/15/2019 at 2:22 PM, fanie said:

How do you return your data from the php function ?

Instead of 


return $result;

you can try


 die(Tools::JsonEncode($result));

 

That's really bad solution.

In new PrestaShop you should use JsonResponse in your Symfony type controller.
 

use Symfony\Component\HttpFoundation\JsonResponse;

return new JsonResponse([
            "1" => [
                "ID" => "123-265",
                "ID eshop"=> "System Architect",
                "Kategorie"=> "$320,800",
                "Počet položek"=> "2011/04/25",
                "Kategorie"=> "Edinburgh",
                "Podkategorie_1"=> "5421",
                "Podkategorie_2"=> "5421",
                "Podkategorie_3"=> "5421",
                "Počet položek eshop"=> "5421"
                ]
            ]
        );

 

Share this post


Link to post
Share on other sites

I just ran into a massive problem that took me a long time to figure out. Documenting this here in case it'll be helpful for someone in the future:

 

My ajax calls had been running smoothly so far. But suddenly they stopped working.

 

Turns out there are 2 types of ajax methods:

 

public function ajaxProcessGetBar(){
	// this will be called in combination with postProcess()
	// on your ajax call, if you have submitted $_POST['action'] = 'getBar';  
	// then this will be called.
}

public function displayAjaxGetbar(){
	//this will be called even without the post process, as long as $_POST['ajax'] = 1;
	// on your ajax call, if you have submitted $_POST['action'] = 'getBar'; 
	// notice that you have to change the function name to all lower case.
}

 

So, here's what's important to consider:

class AdminFooBarController extends ModuleAdminController
{
    public function postProcess()
    {
        return parent::postProcess(); // IF YOU DON'T DO THIS FOR ANY REASON
    }

	public function ajaxProcessGetBar()
    {
		return 'foo'; //THIS WON'T BE FUNCTIONING PROPERLY
    }
}

 

Also a nifty little function I found while debugging this:

 

abstract class ControllerCore
{
     /**
     * Dies and echoes output value
     *
     * @param string|null $value
     * @param string|null $controller
     * @param string|null $method
     */
    protected function ajaxDie($value = null, $controller = null, $method = null)
    {
        if ($controller === null) {
            $controller = get_class($this);
        }

        if ($method === null) {
            $bt = debug_backtrace();
            $method = $bt[1]['function'];
        }

        Hook::exec('actionBeforeAjaxDie', array('controller' => $controller, 'method' => $method, 'value' => $value));
        Hook::exec('actionBeforeAjaxDie'.$controller.$method, array('value' => $value));

        die($value);
    }

}

So this function/method ajaxDie is located in the Controller (myshop\classes\controller\Controller.php)

You should be able to use it in your module controller to echo ajax values and exit the script, since they all inherit each other

(AdminFooBarController extends ModuleAdminController extends AdminControllerCore extends Controller)

So, what @haunter said... simply using die(); isn't necessary/or a "good" solution, because  there's a specific function made for that: ajaxDie(); and it will even execute the hook actionBeforeAjaxDie for you.

 

Hope this helps someone! 🙂

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More