I am working on a Joomla 3.8 website on my localhost, hosted by MAMP 5.1. I am modifying the component J2Store, which is built on F0F. Please bear with me because I'm still learning a lot of these concepts.

We have a database containing car parts which have 4 properties: "manufacturer" (or "make"), "model", "year", and "engine". The website has four different select menus, one for each property, which must be selected in order. For example when the user selects a make then the model menu becomes available and displays only those models made by that manufacturer (and similarly for the other properties).

This functionality is already implemented by the previous developer on this project, but it has the inconvenient feature that each time a select menu changes it reloads the entire page, which takes some time and is annoying. I am trying to implement AJAX requests which refresh the menu contents without reloading the page. My approach is to send a request when a menu changes which queries the database for the appropriate options in the next menu, based on the current menu choices.

The difficulty I'm having is I don't know how to access the current menu options in the server-side code. The old code's logic is based on the $POST[] array, but when I log the contents of the post array during my callback functions it is either empty or doesn't contain what I expect/need.

The following file contains my server-side database calls:

/localhost/my_site/components/com_j2store/models/callback.php

class J2StoreModelCallback extends F0FModel {

    function runCallback($method) {
        switch ($method) {
            case 'getManufacturer':
                $this->getManufacturer();
                break;
            case 'getModel':
                $this->getModel();
                break;
            case 'getManufYear':
                $this->getManufYear();
                break;
            case 'getEngineSize':
                $this->getEngineSize();
                break;
        }
        ...
    }
    ...
    function getModel(){
        // Makes sql query based on the value of $_POST['sel-make']
        ...
    }
    ...
}

My code for a typical menu selection response looks like this:

/localhost/my_site/media/j2store/js/j2store.js

...

jQuery(document).ready(function() {

  jQuery('#sel-make').change(function() {

    // Reset Model, Year and Engine selects.
    disableSelectMenu('model');
    disableSelectMenu('year');
    disableSelectMenu('engine');

    var selection = jQuery('#sel-make').val();

    // If the user cleared their choice, don't do anything else.
    if (selection === '') {
      return;
    }

    var postData = "sel-make=" + selection;

    // Sends an AJAX request which retrieves the correct contents for the Model select.
    // It passes the response to a helper function.
    jQuery.ajax({
            url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel', 
            cache: false,
            type: "POST",
            contentType: "application/json",
            data: postData,
            success: function(response){ 
                // Enables the Model select and fills it with the returned array.
                enableSelectMenu('model', response);
            },
            error: function(xhr, textStatus, errorThrown) {
                console.log("error : " + textStatus);
            }
        });
  });
  ...
}
...

The ajax request reaches its destination, but it doesn't retain the information about the manufacturer selection. In the context of getModel the post array is empty, and in the context of the runCallback method it is

Array
(
    [option] => com_j2store
    [view] => callback
    [task] => callback
    [method] => getModel
    [Itemid] => 
)

which doesn't include the data parameter I put into my request. How can I push the menu selections to the model (via the controller) through the AJAX request? Is there a better way of accessing this content from the server-side code?

I don't know if I'm just not understanding how to properly send a post request, or if this kind of request is simply not allowed to be made in this scenario.

up vote 3 down vote accepted

First, since you want to send just an extra key+value, then you can include that in the url of the ajax call like the following:

url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel&Itemid=' + selection,

And I do not see why but if you want to send the chosen value with the key(sel-make), then:

url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel&sel-make=' + selection,

If you send the data included in the url, then you can just comment out // data: postData . This line is not needed actually in this case.

In your runCallback() function you will have the wanted data now and you can have that with, for example, the following:

function runCallback($method) {

        $app = JFactory::getApplication ();
        $rawDataPost = $app->input->getArray($_POST);
        // if you sent the value in ajax as Itemid:
        $Itemid = $rawDataPost['Itemid'];
        // if you sent it as sel-make:
        $selection = $rawDataPost['sel-make'];
        // then here all of your other things in this function...
}

This is just one simple way of how you can get this. (my site on my localhost has some encoding problem at the moment, so I cannot try the above, but i do not see any problem with sending the Itemid this way to that model via the controller)(update: now I tested that and it works).

And I've almost forgotten, that if you want to rather send the data as you originally formulated then you have to just change the formatting like this and it will get through:

var postData = {'Itemid' : selection};
  • Thanks again Zollie! Setting the url like you say puts the desired data in the request. But also I ran into some strange behaviour: the method call $app->input->getArray($_POST) returns an empty array, but $app->input->getArray($_GET) has the content I want! Even though my ajax request has type "POST", Joomla seems to be handling it as a GET request. The approach taken by the J2Store code is to just merge the $_GET and $_POST arrays together by default, so I think I will do that. – you Nov 26 at 18:16
  • Also I'm still not able to send data with the "data" parameter, which is strange. It might be related to the other weird behaviour I mentioned. – you Nov 26 at 18:21
  • 1
    @you -- I am not sure exactly why you do not get the data from $_POST, only from $_GET, I tried and I get it via $_POST too. I think you also do not need to define contentType in the ajax call, so just comment that out. If the contentType is off (so it is just default) then I get the data as Form Data, otherwise I get it in the 'request Payload' when I send it back to my console (it's not a big different though). – Zollie Nov 26 at 19:02
  • 1
    I commented out the contentType parameter and I am now getting the data from $_POST, thank you – you Nov 26 at 20:06

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.