How to create dynamic listbox options based on other listbox option selection

I have two custom tables with these columns:

  • channels_lists
    -id
    -name
    -published

  • programs_lists
    -id
    -name
    -channel_id
    -published

I created the fromtabs with migxdb and I have two listboxes, one for channels and one for programs. But the list of programs should depending on listbox of channels. Now when i select channel is display all the programs. Can i do this?

Maybe the extra " DynamicDropdownTV" is what you’re looking for.

I use the latest modx version (2.8.3) and the DynamicDropdownTV is supported versions 2.2 - 2.3. I tried to upload the extra but when i used dynamic dropdown in the listbox I had this output error:

Capture

I’m sorry, but I don’t clearly understand what you are doing.

Maybe you can share the “Input Options” you set for your 2 TVs of type “dynamicdropdown” and maybe even provide the schema of your custom tables.

1 Like

This is the schema of the channels

-channels_lists

<?xml version="1.0" encoding="UTF-8"?>
<model package="channels_lists" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.0">
    <object class="Channel_List" table="channels_lists" extends="xPDOSimpleObject">
        <field key="name_gr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_en" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_tr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="medium_id" dbtype="int" precision="11" phptype="integer" null="false"/>
        <field key="document_type_id" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="published" dbtype="int" precision="1" phptype="integer" null="false" default="1" attributes="unsigned"/>             
    </object>
</model>

And this is the schema of the programs

-programs_lists

<?xml version="1.0" encoding="UTF-8"?>
<model package="programs_lists" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.0">
    <object class="Program_List" table="programs_lists" extends="xPDOSimpleObject">
        <field key="name_gr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_en" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_tr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="channel_id" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="published" dbtype="int" precision="1" phptype="integer" null="false" default="1" attributes="unsigned"/>             
    </object>
</model>

And I created two template variables (the names are channel and program) with input type “dynamicdropdown”.

The input types options of channel is:

@SELECT '' AS `channel` UNION ALL (@SELECT `name_gr` AS `channel`, id FROM `[[+PREFIX]]channels_lists` WHERE `published` = 1)

And the input types options of programis:

@SELECT '' AS `program` UNION ALL (SELECT `[[+PREFIX]]programs_lists`.`name_gr` AS `program`, `[[+PREFIX]]programs_lists`.`id` FROM `[[+PREFIX]]programs_lists` INNER JOIN `[[+PREFIX]]channels_lists` ON `[[+PREFIX]]channels_lists`.`id` = `[[+PREFIX]]programs_lists`.`channel_id` WHERE `[[+PREFIX]]programs_lists`.`published` = '1' AND `[[+PREFIX]]channels_lists`.`published` = '1' AND `[[+PREFIX]]channels_lists`.`id` = '[[+channel]]' ORDER BY `[[+PREFIX]]programs_lists`.`id` DESC)

Βut the options are not showing in the migx formtabs and every time I get this error “Processor not found: mgr//getelements.default”

Bruno17/DynamicDropdownTV (github.com)

Look at the example 4 and the example processors and create your own processors to get the list options dynamically

Don’t use a @SELECT sql query for “dynamicdropdown” TVs.
Instead fill the textfields under “XPDO Package Settings (for default processor)”. For example:

Channels:

  • Package Name: channels_lists
  • Class Name: Channel_List
  • Title Key: name_gr

Programs:

  • Package Name: programs_lists
  • Class Name: Program_List
  • Title Key: name_gr
  • Where Clause: {"channel_id":"[[+name_of_your_channel_dynamicdropdown_tv:default=`999999999999999`]]"}

And make sure you use the same “Dynamic Dropdown Group” for both TVs.


Btw: It is usually a better idea to put your objects (here “Channel_List” and “Program_List”) into the same package and not create a new package for every object.

1 Like

yeah. or like that. Then you don’t need custom processors, usually :smile:

As you use WHERE `published` = 1 in your SQL query, you have to set this in the “Where Clause:” settings as well:

Channel: {"published":1}
Programs: {"channel_id":"[[+name_of_your_channel_dynamicdropdown_tv:default=`999999999999999`]]", "published":1}

If you need the order to be the same as in your SQL query ORDER BY `programs_lists`.`id` DESC, then you indeed have to write a custom processor.

Hello again :grinning: The extra “dynamicdropdown” its working only for single listboxes. But for multiple listboxes is not working.

Capture

The scenario is this: When i select value from medium category field i want to show the the violation types based on medium selection. The medium category field its listbox-single and violation type field is listbox-multiple. So i try to do customize.

For the medium category field i have in the input options the below code and its ok:

@EVAL return $modx->runSnippet('migxLoopCollection',array('packageName'=>'medium_categories','classname'=>'Medium_Category','tpl'=>'@CODE:[[+name_gr]]==[[+id]]','outputSeparator'=>'||'));

For the violation type field i have in the input options the below code:

@EVAL return $modx->runSnippet('list-multiple-values', array('mediumid' => '[[+medium]]'));

The [[+medium]] is the field name. And this is my snippet list-multiple-values

$listBox = '';
$selectedoption = $_REQUEST["mediumid"];

$sql = "SELECT * FROM modx_violation_types_lists WHERE FIND_IN_SET('$selectedoption', REPLACE(medium_category_id, '||', ',')) ORDER BY id ASC";

foreach($modx->query($sql) as $row) {
    $listBox .= $row["name_gr"] . "==" . $row["id"] . "||";
}
return $listBox;

Basically I try to pass value of the medium field in the snippet but its not working. How to do this?

This is the schema of violation types:

<?xml version="1.0" encoding="UTF-8"?>
<model package="violation_types_lists" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.0">
    <object class="Violation_Type_List" table="violation_types_lists" extends="xPDOSimpleObject">
        <field key="name_gr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_en" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="name_tr" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="medium_category_id" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="document_type_id" dbtype="varchar" precision="255" phptype="string" null="false" default=""/>
        <field key="published" dbtype="int" precision="1" phptype="integer" null="false" default="1" attributes="unsigned"/>      
    </object>
</model>

The extra DynamicDropdownTV also has the Input Type “dynamicdropdown_multiple”. The problem is that it doesn’t work correctly in the current version of the extra.

Maybe you can check this pull request for the necessary changes.

I changed all the files and the dynamicdropdown_mlti is working but the values of the child field still not showing. Is this correct the option of ‘where clause’?

{"medium_category_id":"[[+medium_cat:default=`999999999999999`]]"}

*medium_cat is the name of template variable of parent field (medium categories)
*medium_category_id is the column name of violation types table

The ‘where clause’ looks correct.

  • Did you select the right value (medium_cat) for “Parent Dropdown”?
  • Do the two TVs have the same value for “Dynamic Dropdown Group”?
  • Make sure that in the section “Debug Information (readonly)” the children/parents relations are correct.

Maybe you also have to change this line

in the plugin DynamicDropdownTV inside MODx to this

if ($tvType == 'dynamicdropdown' || $tvType == 'dynamicdropdown_mlti') {

to account for the new type.