Editable Tables

In document Openrg Programmer Guide 5.5 LATEST (Page 139-142)

Other Methods for Passing Parameters

10.4 Editable Tables

10.4 Editable Tables

Editable table handling in the WBM is considered quite a complicated task for beginners, since it involves more than one page (assuming that editing/adding a single entry is done in a separate page). The requirements are:

1. When clicking the "New" button of an entry, the user should be redirected to a new entry editing page. After filling this page and submitting it, the new entry should appear in the table.

2. When clicking the "Edit" button of an entry, the user should be redirected to the entry's editing page. After updating the information and submitting it, the updated entry should appear in the table.

3. When clicking the "Remove" button of an entry, the page should refresh and the entry must disappear.

The requirements imply that:

1. When clicking the "New" button of an entry, the next page (the single entry edit page) must be signalled to create a new entry.

2. When clicking the "Edit" button of an entry, the entry's unique identifier must be passed to the next page (the single entry edit page).

3. When clicking the "Remove" button of an entry, the page's scan function must be informed of the entry's unique identifier, in order to remove it from the database.

The most complicated point here is to convey data from the first page (the table's page) to the second page (the single entry edit page). The situation can be even more complicated if you need to convey extra data except for the entry's unique identifier. The following example illustrates what happens when you also need to convey a device identifier. Suppose you want to implement a table of all PVC (VPI.VCI) pairs of a given ATM device. You will need to add two new pages:

1. One displaying the table entries.

Figure 10.4 VPI.VCI Pair Table

2. The other for editing/adding a single entry.

Figure 10.5 Single Entry Settings

Since the second page (the single entry edit page) must know which device to manipulate, you need a way to pass not only the entry's unique identifier, but also the device's identifier.

To do so, overload the buffer g_request->button_value with these two pieces of information in the following format: "device name/entry number" (it is safe to use "/" as a delimiter between the two fields, because device name cannot contain "/"). The second page will parse g_request->button_value and retrieve the device and the relevant entry. The first page print and scan function will be as follows:

void p_scr_pvc_table(html_t **handle) {

html_t **cells[2];

set_t **pvc;

...

/* Print table header. The table will have two columns: PVC and action */

p_multi_cell_line(table, CELLS_HEADER, 2, cells, NULL);

multi_cell_line_fill(cells, Tpvc, Taction, NULL);

/* Traverse device's PVC pairs */

for (pvc=NULL; (pvc=dev_if_pvc_get(dev, pvc, 0)); ) {

char val[MAX_VAR_NAME];

/* Create a row with two columns */

p_multi_cell_line(table, CELLS_LINE_DATA, 2, cells, NULL);

/* Print the PVC pair into the first column (cells[0]) */

p_pvc(cells[0], pvc);

/* Print the edit/remove buttons into the second column (cells[1]).

* Here is one of the key points: we associate the button value of * the edit/remove button with "device name/entry number". When the * edit/remove button will be pressed, the scan function will be * invoked and g_request->button value will be equal to

* "device name/entry number"

*/

snprintf(val, sizeof(val), "

p_buttons(cells[1], val, g_btn_pvc_edit, g_btn_pvc_remove, 0);

}

/* Print the add button. When the add button will be pressed, the scan * function will be invoked and g_request->button value will be equal to * the device name

*/

p_add_entry_row(table, 2, cells, NULL, g_btn_pvc_add, 1, dev->name);

}

void s_scr_pvc_table(void) {

char dev_name[MAX_VAR_NAME], *idx;

dev_if_t *dev;

int btn = button_num();

if (btn == g_btn_pvc_add || btn == g_btn_pvc_edit) {

/* Redirect to a single entry edit page */

active_page_set(PAGE_PVC_SETTINGS);

}

else if (btn == g_btn_pvc_remove) {

dev_button_value_read(dev_name, &idx);

/* Retrieve the device struct given its name */

dev = dev_if_get(dev_name);

/* Remove the PVC pair from the database and reconf. Pay attention that * as long as we don't set the active page, we will stay at the current * page (as if the page is refreshed) */

set_free(set_get(dev_if_set(dev), set_path_create(Satm, Spvc, idx, NULL)));

openrg_reconf(FLASH_DELAYED_TOP_PRIORITY);

} }

/* dev_button_value_read() parses 'g_request->button_value'. After calling * it, dev_name will contain the device identifier to manipulate, and idx will * contain the entry's identifier. If idx is NULL, it means that it is a new * entry (add mode) */

void dev_button_value_read(char *dev_name, char **idx) {

strcpy(dev_name, g_request->button_value);

*idx = strchr(dev_name, '/');

The second page print and scan functions will be as follows:

void p_scr_pvc_entry(html_t **handle) {

char dev_name[MAX_VAR_NAME], *idx;

int vpi = 0, vci = 0;

set_t **set = NULL;

...

dev_button_value_read(dev_name, &idx);

if (idx) {

/* idx is not NULL -> we are in edit mode. Retrieve the PVC entry to * manipulate from the given device. The VPI.VCI pair will be printed * according to this entry */

set = set_get(dev_if_set(dev_if_get(dev_name)), set_path_create(Satm, Spvc, idx, NULL));

vpi = set_get_path_int(set, Svpi);

vci = set_get_path_int(set, Svci);

}

/* Print the PVC pair (VPI.VCI). If we are adding a new entry, vpi and vci * will be set to 0 */

p_atm_vpi_vci(table, vpi, vci, SYM_VPI, SYM_VCI, 0);

...

}

void s_scr_pvc_entry(void) {

int vpi, vci;

char dev_name[MAX_VAR_NAME], *idx;

set_t **set = NULL;

dev_if_t *dev;

/* dev_button_value_read() parses 'g_request->button_value'. After calling * it, dev_name will contain the device identifier (dev_name) to manipulate, * and idx will contain the entry's identifier. If idx is NULL, it means

* that it is a new entry (add mode) */

dev_button_value_read(dev_name, &idx);

dev = dev_if_get(dev_name);

/* Extract the VPI.VCI pair from the request */

s_atm_vpi_vci(&vpi, &vci, SYM_VPI, SYM_VCI);

if (g_request->errors) goto Exit;

if (idx) {

/* idx is not NULL -> we are in edit mode. Retrieve the PVC entry to * manipulate from the given device. We will write VPI.VCI pair into * this entry */

set = set_get(dev_if_set(dev), set_path_create(Satm, Spvc, idx, NULL));

} else {

/* idx is NULL -> we are in add mode. Create a new PVC entry for the * given device. We will write VPI.VCI pair into this entry */

set = set_set(dev_if_set(dev), Satm "/" Spvc);

set = set_index_add(set, SET_IDX_ADD_AUTO);

}

/* Write the VPI.VCI pair into the appropriate entry */

set_set_path_int(set, Svpi, vpi);

set_set_path_int(set, Svci, vci);

/* Return to the "parent" page and reconf */

active_page_set(navigator_pop());

openrg_reconf(FLASH_DELAYED_TOP_PRIORITY);

Exit:

p_page(NULL);

}

In document Openrg Programmer Guide 5.5 LATEST (Page 139-142)

Related documents