Master-Detail using the ListAndForm control

Master-Detail using the ListAndForm control


This is a step-by-step guide of building a mster-detail form using the ListAndForm control.

For this example. we will use 2 connected lists : Customers and Contacts.

Customers list columns

Title, Address

Contacts list columns

Title (renamed to Full Name), LastName (single line of text, renamed to "Last Name"), FirstName (single line of text, renamed to "First Name"), Email (single line of text), Customer (lookup on the Customers list)

We first register PowerForms for both lists. Then we start customizing the contacts form.

This is what we should get as a default customization :

 

 

We do some minor customizations to our form :

Change the section columns to 4 and change control positioning:

 

Then we make the "Full Name" control ReadOnly and we apply a value formula to let its value be composed by the value of the LastName and FirstName controls :


Code


form.FieldValue("c_LastName") + " " + form.FieldValue("c_FirstName")




We change the Customer control type from a ComboBox to a LookupPicker (to enhance form loading since the customers list might get long).


Now we start customizing our Customer form. This is the default customization we get when opening the form :


We then add a few records in both lists to assist us during customization.

For our example, we added one Customer and 2 Contacts under that Customer record.

In our Customer form, we first define a ListQuery that will retrieve only the connected  contacts (for the current Customer). The field that connects the 2 list is : Customers.ID = Contacts.Customer, so our query will use criteria on the Customer field of the Contacts list.

 

And the criteria added is based on the control c_ID which contains the ID of the current Customer record.


Notice that we have cleared the "Ignore Blank" checkbox, since that would retrieve ALL contacts when we were inside a new customer record (ID would be blank in that case).

Moreover, we use a criteria type = "Lookup" since the "Customer" column for which we apply the criteria, is a lookup column and we provide the ID part of its value.

We also include the ID of the contact since it is required by the control to identify contact records when editing.

If we press the "Execute" button and we get the correct results, we are ready to add our ListAndForm control on the form.

We then create a separate tab to host our ListAndForm control called "Contacts".

We place a ListAndForm control there and set its value to be the ListQuery we have just defined.

We change the form size (from the options section) to fit our needs.

This is what we should get from that :


Since the ListAndForm control is actually a separate Form-inside-a-Form, the customization we have already defined for our Contacts form is automaticaly used.

Notice that selecting records from the datagrid, allows us to edit those records in the form below that grid.

Now to define the relationship between the 2 entities so that each time we add a new contact, the parent id is used inside the Customer column of the contact, we should edit the ListAndForm control properties and go to the Extra tab of the control properties and add a Default Value :


Code


{c_ID};#{c_Title}




The above value will replace the {c_ID} with the ID of the  current customer record and the {c_Title} with the title so the final value will be something like : 1;#BPC-Components.

If we selected a ComboBox instead of a LookupPicker, the {c_ID} would be sufficient for that value, but since we want the title of the customer to be shown inside our LookupPicker, we should provide it manually (since the LookupPicker does not load records during form loading).

So if we press the NEW button inside the Contacts form, this is what we will get :

 

The last thing to do is to disable the ListAndForm control when we are inserting a new Customer record (since the Customer is not saved and we have no ID to connect with our contacts list).

One way to do this is to apply a "Enabled Formula" in the ListAndForm control :


Code


form.FieldValue("c_ID") != ""




Another way to accomplish a similar result is to write a small script (javascript) inside the LoadCompleted event that would disable or hide the "Contacts" tab from the form if we are still in a new Customer record:

 


Code


var id = form.DataItem.ID;
if (pf.IsEmpty(id))
  form.HideTab(1);
else
  form.ShowTab(1);