We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 50441
    • 13 Posts
    Having worked my way painfully through this, I thought I would post a quick example / tutorial as it how this may be done.

    MIGXdb.

    Create Custom Manager Page(s) for two linked tables (one to many)

    Requirements

    1. Install MigX (if not already done)
    2. Create a new Package and schema-file
    3. The Schema
    4. Parse Schema
    5. Create Table(s)
    6. Create the Configuration
    7. Add a Menu Item
    8. Add records to the tables

    This Example was built using ModX 2.5.0 pl and MigX 2.9.6

    1. Install MigX (if not already done)

    First of all, install MIGX using standard package-management, and do the basic configuration.

    Go to Components->MIGX->Tab 'Set-up/Upgrade', and under the 'Setup' tab click 'Setup'.

    2. Create a new Package and schema-file

    Go to Components->MIGX->Tab 'Package Manager'.

    Add a name for the new package using the field 'packageName:'. For this example use 'yourpackagename'.

    Click 'Create Package' This should create a directory under the core-path with an empty schema-file in its correct place.

    Still having 'yourpackagename' in the field 'packageName', now fill the textarea-field 'Schema' under the tab 'Xml Schema' using the data below.

    3. The Schema
    <?xml version="1.0" encoding="UTF-8"?>
    <model package="yourpackagename" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
    <!-- 
    I suggest that  you use a package name derived prefix for your tables to help to separate your tables
    from ModX tables or tables created by other packages - I have used 'ypn'
    -->
        <object class="table1Class" table="ypn_table1" extends="xPDOSimpleObject">
            <field key="table1_key" dbtype="varchar" precision="3" phptype="string" null="false" default=""/>
            <field key="table1_field1" dbtype="text" phptype="string" null="false" default=""/>
    <!-- Used by MigX -->        
            <field key="deleted" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
            <field key="published" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> 
    <!-- Good Practice for tracking -->       
            <field key="createdon" dbtype="datetime" phptype="datetime" null="true"/>
            <field key="createdby" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" />
            <field key="editedon" dbtype="datetime" phptype="datetime" null="true"/>
            <field key="editedby" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" />
    <!-- This is !IMPORTANT it links the two tables, base table to subordinate table NB 'id' is created automatically -->
            <composite alias="linktable1totable2" class="table2Class" local="id" foreign="table2_table1_id" cardinality="many" owner="local" /> 
            
            <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign"/>
            <aggregate alias="EditedBy" class="modUser" local="editedby" foreign="id" cardinality="one" owner="foreign"/>
        </object>
    
        <object class="table2Class" table="ypn_table2" extends="xPDOSimpleObject">
            <field key="table2_table1_id" dbtype="int" precision="11" phptype="integer" null="false" default=""/>
            <field key="table2_key" dbtype="varchar" precision="3" phptype="string" null="false" default=""/>
            <field key="table2_field1" dbtype="text" phptype="string" null="false" default=""/>
    <!-- Used by MigX -->         
            <field key="deleted" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
            <field key="published" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" /> 
    <!-- Good Practice for tracking -->         
            <field key="createdon" dbtype="datetime" phptype="datetime" null="true"/>
            <field key="createdby" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" />
            <field key="editedon" dbtype="datetime" phptype="datetime" null="true"/>
            <field key="editedby" dbtype="int" precision="10" attributes="unsigned" phptype="integer" null="false" default="0" />
    <!-- This is !IMPORTANT it links the two tables, subordinate table back to the base table NB 'id' is created automatically -->
            <aggregate alias="linktable2totable1" class="table1Class" local="table2_table1_id" foreign="id" cardinality="one" owner="foreign" /> 
            
            <aggregate alias="CreatedBy" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign"/>
            <aggregate alias="EditedBy" class="modUser" local="editedby" foreign="id" cardinality="one" owner="foreign"/>
        </object>
    </model>
    

    by clicking 'Save schema' the schema-file should have been created. Test this by clicking 'Load schema'.

    4. Parse Schema

    Create xpdo-classes and maps from the schema by clicking 'parse Schema' under the tab 'parse Schema'.

    5. Create Table(s)

    Create tables from the schema by clicking 'create Tables' on the tab 'create Tables'. This should create the tables.

    6. Create the Configuration

    Go to the main-tab 'MIGX'

    There should be an empty grid with some buttons.

    Click 'Add Item'

    In the opening window add:

    Name: migxtable1

    Click 'Done'

    The newly new created record should now appear in the grid.

    It is possible to edit this record and add grid-columns, tabs, and many other things by right-clicking on migxtable1 and choosing 'edit', but in this case it will be much quicker to import our example-configuration.

    Right-Click migxtable1 and choose 'Export/Import'

    Using cut-and-paste, replace the code in the field 'Json' with the following :
    {
      "formtabs":[
        {
          "MIGX_id":1,
          "caption":"Table 1",
          "print_before_tabs":"0",
          "fields":[
            {
              "MIGX_id":1,
              "field":"id",
              "caption":"Id",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"none",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":1
            },
            {
              "MIGX_id":2,
              "field":"table1_key",
              "caption":"Table 1 Key",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":2
            },
            {
              "MIGX_id":3,
              "field":"table1_field1",
              "caption":"Table 1 Field 1",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":3
            },
            {
              "MIGX_id":4,
              "field":"linktable1totable2",
              "caption":"Linked Items",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"migxdb",
              "validation":"",
              "configs":"migxtable2",
              "restrictive_condition":"[[migxIsNewObject]]",
              "display":"",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":4
            }
          ],
          "pos":1
        }
      ],
      "contextmenus":"update||duplicate||remove",
      "actionbuttons":"addItem",
      "columnbuttons":"",
      "filters":"",
      "extended":{
        "migx_add":"Add Table 1 Entries",
        "disable_add_item":"",
        "add_items_directly":"",
        "formcaption":"",
        "update_win_title":"",
        "win_id":"table1Unique",
        "maxRecords":"",
        "addNewItemAt":"bottom",
        "multiple_formtabs":"",
        "multiple_formtabs_label":"",
        "multiple_formtabs_field":"",
        "multiple_formtabs_optionstext":"",
        "multiple_formtabs_optionsvalue":"",
        "actionbuttonsperrow":4,
        "winbuttonslist":"",
        "extrahandlers":"",
        "filtersperrow":4,
        "packageName":"yourpackagename",
        "classname":"table1Class",
        "task":"migxtable1",
        "getlistsort":"",
        "getlistsortdir":"",
        "sortconfig":"",
        "gridpagesize":"",
        "use_custom_prefix":"0",
        "prefix":"",
        "grid":"",
        "gridload_mode":1,
        "check_resid":1,
        "check_resid_TV":"",
        "join_alias":"linktable1totable2",
        "has_jointable":"yes",
        "getlistwhere":"",
        "joins":"",
        "hooksnippets":"",
        "cmpmaincaption":"MigX Example - two linked tables",
        "cmptabcaption":"Table 1",
        "cmptabdescription":"Add\/edit Table 1 Items",
        "cmptabcontroller":"",
        "winbuttons":"",
        "onsubmitsuccess":"",
        "submitparams":""
      },
      "columns":[
        {
          "MIGX_id":1,
          "header":"Id",
          "dataIndex":"id",
          "width":"",
          "sortable":"false",
          "show_in_grid":"0",
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        },
        {
          "MIGX_id":2,
          "header":"Table 1 Key",
          "dataIndex":"table1_key",
          "width":"",
          "sortable":1,
          "show_in_grid":1,
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        },
        {
          "MIGX_id":3,
          "header":"Table 1 Field 1",
          "dataIndex":"table1_field1",
          "width":"",
          "sortable":1,
          "show_in_grid":1,
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        },
        {
          "MIGX_id":4,
          "header":"Linked Items",
          "dataIndex":"linktable1totable2",
          "width":"",
          "sortable":"false",
          "show_in_grid":1,
          "customrenderer":"",
          "renderer":"this.renderChunk",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"[[migxLoopCollection?\n&packageName=`yourpackagename`\n&classname=`table2Class`\n&where=`{\"table2_table1_id\":\"[[+id]]\"}`\n&selectfields=`table2_key`\n&tpl=`@CODE:[[+table2_key]]`\n&outputSeparator=`, `\n]]",
          "renderoptions":"",
          "editor":""
        }
      ]
    }
    

    Click 'Done'.

    Check that this step has completed successfully by right-clicking on migxtable1 and choosing 'edit'. The content just loaded should now appear in the correct places under the appropriate tabs.

    Now repeat the process for the second config entry, migxtable2.

    Click 'Add Item'

    In the opening window add:

    Name: migxtable2

    Click 'Done'

    The newly new created record should now appear in the grid.

    Right-Click migxtable2 and choose 'Export/Import'

    Using cut-and-paste, replace the code in the field 'Json' with the following :
    {
      "formtabs":[
        {
          "MIGX_id":2,
          "caption":"Table 2",
          "print_before_tabs":"0",
          "fields":[
            {
              "MIGX_id":1,
              "field":"id",
              "caption":"id",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"none",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":1
            },
            {
              "MIGX_id":2,
              "field":"table2_key",
              "caption":"Table 2 Key",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":2
            },
            {
              "MIGX_id":3,
              "field":"table2_field1",
              "caption":"Table 2 Field 1",
              "description":"",
              "description_is_code":"0",
              "inputTV":"",
              "inputTVtype":"",
              "validation":"",
              "configs":"",
              "restrictive_condition":"",
              "display":"",
              "sourceFrom":"config",
              "sources":"",
              "inputOptionValues":"",
              "default":"",
              "useDefaultIfEmpty":"0",
              "pos":3
            }
          ],
          "pos":1
        }
      ],
      "contextmenus":"update||duplicate||remove",
      "actionbuttons":"addItem",
      "columnbuttons":"",
      "filters":"",
      "extended":{
        "migx_add":"Add Table 2 Items",
        "disable_add_item":"",
        "add_items_directly":"",
        "formcaption":"",
        "update_win_title":"",
        "win_id":"table2Unique",
        "maxRecords":"",
        "addNewItemAt":"bottom",
        "multiple_formtabs":"",
        "multiple_formtabs_label":"",
        "multiple_formtabs_field":"",
        "multiple_formtabs_optionstext":"",
        "multiple_formtabs_optionsvalue":"",
        "actionbuttonsperrow":4,
        "winbuttonslist":"",
        "extrahandlers":"",
        "filtersperrow":4,
        "packageName":"yourpackagename",
        "classname":"table2Class",
        "task":"migxtable2",
        "getlistsort":"",
        "getlistsortdir":"",
        "sortconfig":"",
        "gridpagesize":"",
        "use_custom_prefix":"0",
        "prefix":"",
        "grid":"",
        "gridload_mode":1,
        "check_resid":1,
        "check_resid_TV":"",
        "join_alias":"linktable2totable1",
        "has_jointable":"yes",
        "getlistwhere":"",
        "joins":"",
        "hooksnippets":"",
        "cmpmaincaption":"",
        "cmptabcaption":"",
        "cmptabdescription":"",
        "cmptabcontroller":"",
        "winbuttons":"",
        "onsubmitsuccess":"",
        "submitparams":""
      },
      "columns":[
        {
          "MIGX_id":1,
          "header":"id",
          "dataIndex":"id",
          "width":"",
          "sortable":"false",
          "show_in_grid":"0",
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        },
        {
          "MIGX_id":2,
          "header":"Table 2 Key",
          "dataIndex":"table2_key",
          "width":"",
          "sortable":"false",
          "show_in_grid":1,
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        },
        {
          "MIGX_id":3,
          "header":"Table 2 Field 1",
          "dataIndex":"table2_field1",
          "width":"",
          "sortable":"false",
          "show_in_grid":1,
          "customrenderer":"",
          "renderer":"",
          "clickaction":"",
          "selectorconfig":"",
          "renderchunktpl":"",
          "renderoptions":"",
          "editor":""
        }
      ]
    }
    

    Click 'Done'.

    Check that this step has completed successfully by right-clicking on migxtable2 and choosing 'edit'. The content just loaded should now appear in the correct places under the appropriate tabs.

    7. Add a Menu Item

    Go to Tools (gear icon)->Menus->
    Click the 'Create Menu' button
    Parent: choose where you would like the menu to appear
    Lexicon-key: Migx linked tables
    Action: index
    Parameters: &configs=yourpackagename
    Namespace: migx

    Refresh the display, and the menu item you have just created should appear.

    8. Add records to the tables

    Click on 'Add Table 1 Entries'
    Enter what you need and click 'Done'
    The new record now appears in the grid.

    Right-click on this record and choose 'Edit'.
    You can now change the information that you have just entered, and click 'Done' OR at the bottom under 'Linked Items' you could click on 'Load Grid' This will load the grid of subordinate items.

    To add items to this second table, click on 'Add Table 2 Items', enter the information and hit 'Done'. The new item appears in the subordinate grid.
    Press 'Done' again will return you to the top level - note that the key that you just entered now appears under 'Linked Items'.

    Cool !