How to make Ajax-dependent lists

This example shows the ability to create a dependent drop-down lists in the form of a directory search.

Attention!
An example is applicable to a small data set. If you plan a great list of dependent values ​​(say, more than 100), it is better to use a different solution.

Consider the example we set by using the demo data, namely the example of "Paper Zoo".

Suppose that we needed to divide the animals habitat countries. Because a large number of countries, it would be logical to them as a group in order to facilitate the end user to find the right country. Grouping in this case will serve as continents.

Add to catalog new characteristic of type "select" and make the data. As a result, we get the following:

Continent

Add the same characteristics for the countries.

The dependence of the characteristics will be stored in an additional field of the table {shop_param_select}, which contains all the values of drop-down lists. Read more about the structure of the table can be found in the section of the database structure DIAFAN.CMS.

Run the following SQL-query, such as phpMyAdmin:

Example:

ALTER TABLE `diafan_shop_param_select ` ADD `parent_param_id` INT(11) NOT NULL

Now open the file modules/shop/admin/shop.admin.param.php, which is responsible for the detailed description of the output characteristics in the administrative part.

It will take us a method edit_variable_param_select(), in charge of the editing features.

We find in the method of the following lines:

if (in_array($this->diafan->values("type"), array('select', 'multiple')))
{

and after adding:

Example:

if($this->diafan->id == 12)
{
    
$mainland = array();
    
$rows = DB::query_fetch_all("SELECT id, [name] FROM {shop_param_select} WHERE param_id=%d", 11);
    foreach(
$rows as $row)
    {
        
$mainland[$row['id']] = $row['name'];
    }
}

Here we check that is currently open the desired feature. Is necessary in this case, "Country" with ID, equal to 12.

Attention!
In your case ID can have any value. To learn feature ID, just move the mouse cursor on it in the list of features in the administrative part.

Next, from the table {shop_param_select} selects all the values of the fateures are the same values drop-down list with an ID of 11, ie, continents. The data are written to the array $mainland in the form value_id => value_name.

Now we derive the array in a drop-down list.

In this same test, a cycle beginning with

foreach ($value as $row)
{

after the line

<input type="text" name="param_rewrite[]" size="20" value="'.$row["rewrite"].'">

write

Example:

';
if($this->diafan->id == 12)
{
     $selected = DB::query_result("SELECT parent_param_id FROM {shop_param_select} WHERE id=%d AND param_id=%d", $row["id"], 12);
     echo '
<select name="mainland'.$row["id"].'">';                            
     foreach($mainland as $key=>$value)
     {
         echo '
<option value="'.$key.'" '
         .($selected == $key ? '
selected' : '')
         .'
>'.$value.'</option>';
     }
         echo '
</select>';
     }
echo '

Here again, we check that we are in a desired feature, and then form a cycle drop-down list on the basis of solid obtained earlier $mainland.

Note the name of the list "mainland".$row["id"]. Here $row["id"] is this value of drop-down list "Country" for current item. "mainland".$row["id"]$row["id"]

At each iteration, value of new field parent_param_id, which is stored in $selected do comparison with , which is stored in $selected, a $key.

Now, feature "Country" will look like this.

Country

We have made a list of the output of the continents, but did not keep them. For preservation of the features responsible method save_variable_param_select(). Slightly modify it. Before

$ids[] = $id;

add

Example:

if(! empty($_POST['mainland'.$id]))
{
    
DB::query("UPDATE {shop_param_select} SET parent_param_id=%d WHERE id=%d AND param_id=%d", $_POST['mainland'.$id], $id, 12);
}

In this code, there is nothing difficult — checks for variable mainland and updates the new field parent_param_id.

The administrative part is now fully functional and comfortable.

We turn to the public part.

For starters derive characteristics of the "Continent" and "Country" in the search form in a drop-down list.

Attention!
By default, all drop-down lists are displayed as checkboxes to allow the user to select multiple values.

For this in the file modules/shop/views/shop.view.show_search.php code

Example:

case 'select':
case
'multiple':
echo
'<span class="infofield">'.$row["name"].':</span>';
foreach (
$row["select_array"] as $key => $value)
{
    echo
'<input type="checkbox" name="p'.$row["id"].'[]" value="'.$key.'"'.(in_array($key, $row["value"]) ? " checked" : '').' class="inpcheckbox"> '.$value.'<br>';
}

replace to

Example:

case 'select':
case
'multiple':
if(
$row['id'] == 11 || $row['id'] == 12)
{
    echo
'<span '.($row['id'] == 12 ? 'style="display: none;" class="country"' : 'class="mainland"').'>
    <span class="infofield">'
.$row["name"].':</span>
    <select name="p'
.$row["id"].'[]">';
    echo
'<option value="0">-</option>';
    foreach (
$row["select_array"] as $key => $value)
    {
        echo
'<option value="'.$key.'"'.(in_array($key, $row["value"]) ? " selected" : '').'>'.$value.'</option>';
    }
    echo
'</select></span>';
}
else
{
    echo
'<span class="infofield">'.$row["name"].':</span>';
    foreach (
$row["select_array"] as $key => $value)
    {
        echo
'<input type="checkbox" name="p'.$row["id"].'[]" value="'.$key.'"'.(in_array($key, $row["value"]) ? " checked" : '').' class="inpcheckbox"> '.$value.'<br>';
    }
}

In this part of the code checked ID features. If it is necessary to us 11 or 12, form the drop-down list, otherwise the default output feature, ie, checkboxes.

This feature "Country" do hidden.

The next step is to create a method of sending a POST request if you select the feature "Continent".

Open the file modules/shop/js/shop.show_search.js and add to the end

Example:

$(".mainland select").change(function(){
    var
selected = $(".mainland select option:selected").val();
    $(
'.country select option').remove();
    $.
ajax({
        
type: "POST",
        
url: "",
        
data: "module=shop&action=change_country&mainland=" + selected,
        
success: function (response, textStatus)
        {
            $(
".country select").append($(response));
            $(
".country").show();
        }
    });
});

About the method ajax of jQuerylibraries written a lot of articles, so search for it will not be difficult. We focus on the variables that are passed to the control system.

module=shop — announces that we call the file modules/shop/shop.action.php.

action=change_country — here in any form indicate the name of the method that will handle the request (we will create it later).

mainland= + selected — the current value of a drop-down list.

We proceed to write the handler.

First, in the file modules/shop/shop.php to a method action() after

Example:

switch ($_POST['action'])
{

add

Example:

case 'change_country':
return
$this->action->change_country();

Now modules/shop/shop.action.php add a new method:

Example:

public function change_country()
{
    
$text = '<option value="0">-</option>';
    
$rows = DB::query_fetch_all("SELECT id, [name] FROM {shop_param_select} WHERE parent_param_id=%d", $_POST['mainland']);
    foreach(
$rows as $row)
    {
        
$text .= '<option value="'.$row['id'].'">'.$row['name'].'</option>';
    }
    echo
$text;
}

In this method, there is a sample of elements drop-down list on the basis of the received ID values of the continent, which is stored in $_POST['mainland'].

Next formed dropdown list and is its conclusion.

List