Implement Master-Detail relationships in rodakino

0. Download and install the new rodakino version

You find the new version here: rodakino_0_2_0.tgz

Also look here for  rodakino RAD download and installation . Be sure to install rodakino_0_2_0.tgz, not an older version !!!

 

Goal: Developers should be able to implement a master/detail GUI frontend for two (or more) Postgres tables.

 

1. We need two database tables

Both tables already exist and are used for the rodakino menu system:

$> psql -U node node

node=# \d                  -- display all tables in schema node

              List of relations
 Schema |        Name        | Type  | Owner
--------+--------------------+-------+-------
 public | countries          | table | node
 public | menu_profile_items | table | node
 public | menu_profiles      | table | node
 public | roda_menus         | table | node
 public | roda_users         | table | node
 public | users              | table | node
 public | zipcodes           | table | node
 public | zipcodes_adv       | table | node
(8 rows)

 

node=# \d MENU_PROFILES

            Table "public.menu_profiles"
    Column    |           Type           | Modifiers
--------------+--------------------------+-----------
 menu_profile | character varying(50)    | not null
 description  | character varying(100)   |
 insuser      | character varying(20)    |
 upduser      | character varying(20)    |
 ins_ts       | timestamp with time zone |
 upd_ts       | timestamp with time zone |
Indexes:
    "pk_menu_profiles" PRIMARY KEY, btree (menu_profile)
Referenced by:
    TABLE "roda_users" CONSTRAINT "fk01_roda_users" FOREIGN KEY (menu_profile) REFERENCES menu_profiles(menu_profile)
Triggers:
    ins_menu_profiles BEFORE INSERT ON menu_profiles FOR EACH ROW EXECUTE PROCEDURE ins_user_tz()
    upd_menu_profiles BEFORE UPDATE ON menu_profiles FOR EACH ROW EXECUTE PROCEDURE upd_user_tz()

 

node=# \d MENU_PROFILE_ITEMS

          Table "public.menu_profile_items"
    Column    |           Type           | Modifiers
--------------+--------------------------+-----------
 menu_profile | character varying(50)    | not null
 menuid       | character varying(50)    | not null
 readonly     | character(1)             |
 insuser      | character varying(20)    |
 upduser      | character varying(20)    |
 ins_ts       | timestamp with time zone |
 upd_ts       | timestamp with time zone |
Indexes:
    "pk_menu_profile_items" PRIMARY KEY, btree (menu_profile, menuid)
    "x1_menu_profile_items" btree (menuid)
Foreign-key constraints:
    "fk01_menu_profile_items" FOREIGN KEY (menuid) REFERENCES roda_menus(menuid)
Triggers:
    ins_menu_profile_items BEFORE INSERT ON menu_profile_items FOR EACH ROW EXECUTE PROCEDURE ins_user_tz()
    upd_menu_profile_items BEFORE UPDATE ON menu_profile_items FOR EACH ROW EXECUTE PROCEDURE upd_user_tz()

 

2. The rodakino window rw_md_menu_profiles.hbs

This window exists and is already working and can be called from the rodakino menu.

You find it in the usual place in folder

.../rodakino/app/roda_windows/rw_md_menu_profiles.

 

It is "Benutzerprofile MD" (sorry for the german name, this means "User profiles master/detail") :

rw md menu profiles

The rodakino database windows also already exist.

You find them in the usual place, which is:

.../rodakino/app/roda_dbwindows/rdbw_md_menu_profiles.hbs

.../rodakino/app/roda_dbwindows/rdbw_md_menu_profiles_css.hbs

.../rodakino/app/roda_dbwindows/rdbw_md_menu_profile_items.hbs

.../rodakino/app/roda_dbwindows/rdbw_md_menu_profile_items_css.hbs

Nothing new here, exactly the same as in the older tutorials.

 

3. So, how does the link between master and detail work?

Look at .../rodakino/app/roda_windows/rw_md_menu_profiles/rw_md_menu_profiles.hbs in function onDivLoad(myName):

function onDivLoad(myName) {
    // function is called on ajax success after load
    console.log('rw_md_menu_profiles.onDivLoad.1 myName: '+ myName);

    // i am the active roda_window. !! necessary for roda_menubar to work !!
    act_roda_window = myName;

    // resize the dialog
    $("#"+myName).roda_window("option","height",825);
    $("#"+myName).roda_window("option","width",795);

    // link master and detail rdbws
    var rw = $("#"+myName).roda_window();
    console.log('rw_md_menu_profiles.onDivLoad.2 rdbwLink: '+ rw.roda_window("getOptions").rdbwLink);
    rw.roda_window("getOptions").rdbwLink =
      [ [ { "rdbw_md_menu_profiles": "rdbw_md_menu_profile_items" },
          { "MENU_PROFILE": "MENU_PROFILE" } ] ];

    // set master roda_dbwindow
    $("#"+myName).roda_window("option","rdbw_master","rdbw_md_menu_profiles");
    // call retrieve for master roda_dbwindow
    rdbw_master.roda_dbwindow("retrieve",true);
  }

 

That's all. The master/detail link is established by the object rdbwLink, which is an instance var of the roda_window.

 

The first line { "rdbw_md_menu_profiles": "rdbw_md_menu_profile_items" } defines the master rdbw on the left and the detail rdbw on the right.

 

The second line { "MENU_PROFILE": "MENU_PROFILE" } defines the link field on master side left and on detail side right.

If you have more than one link field, just add it like this: { "MENU_PROFILE": "MENU_PROFILE", "SECOND_FIELD_IN_MASTER": "SECOND_FIELD_IN_DETAIL", ... }

 

4. If you need a master with two detail rdbw's at the same level then write:

[ [ { "rdbw_md_menu_profiles": "rdbw_md_menu_profile_items" },
          { "MENU_PROFILE": "MENU_PROFILE" } ],

[ { "rdbw_md_menu_profiles": "rdbw_second_detail" },
          { "MASTER_LINK_FIELD": "DETAIL_LINK_FIELD" } ]

];

 

5. If you need a master - detail - detail, you can define it like this:

[ [ { "rdbw_md_menu_profiles": "rdbw_md_menu_profile_items" },
          { "MENU_PROFILE": "MENU_PROFILE" } ],

[ { "rdbw_md_menu_profiles_items": "rdbw_second_level_detail" },
          { "DETAIL_LINK_FIELD": "DETDET_LINK_FIELD" } ]

];

 

I have'nt tried detail rdbw's in tab-pages yet (they are on the agenda), but that should work in a similar fashion too.