Subform
Note: Not to be confused with Substitute Form. A Subform is a regular Form that is nested onto another Form. A Substitute Form replaces a baseline form with a custom version of that form.
Subforms allow you to create a form that can be reused on other forms and also allows for dynamically switching between different forms based on data entered by the user.
Subforms are a powerful way to display similar groupings of controls on multiple forms, and maintaining this all on a single form instead of copying the same sets of controls over and over.
Subforms are also a great way to simply forms that grow overly complex, especially when you have overlapping controls that display conditionally based on other data. Rather than dealing with multiple overlapping controls, move these onto subforms and simply slide in the appropriate subform for the circumstance.
Adding a Subform
Adding a subform is similar to adding a regular form, the only difference is a new checkbox to indicate that the form is a subform. This checkbox allows the form to be linked to lookup values for dynamic form display.
Implementation
A subform is designed just like any other form, but the following rules must be observed:
- Fields on the subform must exist in the parent form, although they do not have to be based on the same object - For example, a subform based on address can be used on a parent form based on individual because the fields overlap. However, a payment subform cannot be used on a form based on individual.
- Fields may only be displayed once between the parent and the subform - For example, a field present on the parent form cannot also be present on the subform or an error will be thrown.
Once the subform is designed, it can also be related to lookup data using the subform lookup value childform. Records in this child form will relate the subform to a value in a lookup table to allow for dynamically switching to this form when the user selects this value on the parent form. Values in fields which have the "enable for subform lookup flag" checked are eligible to be linked to.
To place the subform on a designed form there is a new Avectra Control named DesignedSubForm. This control is a div representing the area on the form where the subform will display. This should be made roughly the same size as the designed subform to ensure it displays well. This control expects several values in the URL\Image Path\Data:
- DefaultFormKey[*form key*] - The *form key* (FormKey) is the key of the form to display by default. Not required, as long as you also use the Lookup Value to drive the selection of the sub form. If omitted, then no subform will appear until one is triggered to appear by the lookupcolumn/lookupvalue/lookupcode.
- [alwaysupdatepanel] - This should always be present to ensure the form refreshes correctly.
- lookupcolumn[*field name*] - Required. The field name. Used to filter Lookup Values.
- lookupvalue[{*field name*}] - If this is present, the subform will dynamically try to find a form other than the default to display. This logic will take parse the value of the field and try to find a subform which has been related to that value. If no form is found, the default will be used.
- lookupcode[*value*] - If this is present, when searching for a related subform, only those with a matching lookupcode will be considered. This is used only to help segregate sections of subforms.
- SubFormPrefix[*prefix*] - This prefix will be prepended to all controls on the subform. This is for use when the subform is being used to correspond to a data object in the parent form which has a non-standard prefix (for example, ad2).
Subform Lookup Value
If the section containing the subform can switch from one subform to another depending on other data on the form, then you need to handle the switching with Subform Lookup Values.
You can manage these from the Form that has the Subform on it.
- Table Name - start by choosing a Table Name. Only tables with columns that have the enable for subform lookup? checkbox selected will be in this dropdownlist.
- Lookup Column - choose the column from the Table. Aligns with the lookupcolumn[] tag.
- Lookup Value - in this dropdownlist will be a list of every possible data value contained for the chosen lookup column. Choose the value. Aligns with the lookupvalue[] tag.
- Lookup Code - the optional additional value that can further filter the selection of a Subform. Aligns with lookupcode[] tag.
Virtual Field as a Lookup Column
The Lookup Column only works for actual database columns contained in the md_column table.
If you need to switch subforms based on the value of a virtual field, then do the following:
- Go to the Column page of the primary key column of the Form's Object's main table and enable it to be a subform lookup column.
- When you add a Sub Form Lookup, choose the column. The Lookup Value will be the actual word Virtual.
- You must also employ the lookupcode[] tag and a value for more precision in choosing the subform; remember you have only 5 characters to work with.
- In the URL/Image Path/Data, use lookupcolumn[zzz_key] where zzz_key is the primary key column, use lookupvalue[Virtual] and also use a lookupcode[] tag which might be the value of a parsed value. Note that you're limited to only five characters so you might need a "translating" virtual field that will never be more than five characters long.
Managing Subforms
On the Form profile page, use Subforms tab to view related forms and subforms from one place. If the form you're on has subforms, you can view those subforms from this page. If the form you're on is a subform, then you can view the "main" forms that this subform could appear on (depending on the conditions). Depending on whether you are on a "main" form or a subform, you'll see different information.
Subform Lookup Values
If the form is a subform, you can manage the lookup values from this child form. This child form is also on the Primary tab. This child form will be visible only if the sub form checkbox is checked.
Subforms of this Form
If the form you're on contains subforms, then you can view those subforms on this child form.
Some subforms are associated with the main form by way of the DefaultFormKey, and others are associated by way of the Lookup Code or Lookup Value tags. If you hover over the Reference column, you can view the Data tags of the control. If you edit the record, you can edit the form control directly to adjust the pixel coordinates or Data tags. If you edit the size of the control, be sure to design the overall form to ensure it looks right. The Go To icon takes you to the Form.
Forms that reference this Subform
If the form you're on is a subform, then you can view any forms that reference it from this child form, either by the DefaultFormKey tag or the Lookup Code or Lookup Value tags.
Much like the Subforms of this Form child form, you can edit the form controls on the main forms that reference this subform if you need to make pixel or tag adjustments, but do so with care. If you change height/width, be sure to Design the Form to ensure the overall fit is right. If you hover over the Reference column, you can view the Data tags of the control.
This child form will be visible only if the subform checkbox is checked.
Subform Controls and Design Area
Also on this page you can view the height/width pixel coordinates of the Design Area of the subform itself, as well as of the form control height/width pixel coordinates of the control that references the subform. If the form control height/width is smaller than the design area of the subform itself, then form will contain scroll bars in the div so that the whole subform can be accessed. From this tab, you can click the goto arrow to navigate back and forth from the main forms to the subforms to get the sizing right.
In the example above, we are viewing this information from the Subform. The lower child form indicates that the overall size of the subform is 350px by 140px. In the upper child form, we see that this subform is referenced on another form ("Individual Add - Sub Form"). The Form Control on that form is sized at 358px x 194px (width x height). Since the subform is narrower and shorter than the control that is containing the subform, the subform will fit. In fact, the form control on the main form could be made smaller.
When you're on a parent form, you can see the reverse view which is the form controls of the main form that reference the subform. In the example below, the height and width of form control on the bottom child form can be compared size of the overall form shown in the top child form.
From the subform controls and design area child form, you can edit the size of the form controls directly from the child form. After that, you should go that form and design it to refine the overall form layout.
You cannot edit the size of the Design Area of the subform from this child form. If you need to do that, just design the form and change it from the Form Designer. If you do this, make sure that that any form controls referencing the subform are still sized appropriately.
FAQ
Error on Loading Subform
If you get an error on a form with a Subform, make certain you do not have the same control on both the main form and the sub form.
Error Source: System.Web
Error Number: 500
Error Message: Exception of type 'System.Web.HttpUnhandledException' was thrown.; Unable to find control id 'XXXXXXXX' referenced by the 'ControlToValidate' property of 'XXXXXXXX_Validator'.
Lookups
If there is a control on the subform that is bound to a Lookup, then the Lookup definition must be on the main form, not on the sub form.
Form Extensions
Nested Sub Forms
A subform may be nested within another subform.
Tab order
Getting the tab order right on a form with subforms is simple once you understand how it works.
Imagine you have a main form with a subform on it. Suppose the subform has three controls, and on the subform, the tab order of the three controls is 1, 2 and 3.
When the subform is placed on the main form, the form control representing the subform will have its own tab order. When that subform's controls are added to the main form at rendering time, their tab order will be their original tab order plus the tab order of the subform control itself.
For example, observe the form and subform (superimposed with a purple border) below, which is shown in the Tab Ordering view of the Form Designer. Control 30 is the placeholder for the Address sub form - United States that has a purple border. The first control on that subform is address line 1, and its tab order is 1. When this subform is rendered onto the main form, the tab order for address line 1 will be 31, which is 1 + 30 (the tab order of the subform control plus the tab order of the form control on the subform). What this means is that after the user tabs out of the country field (#29), then the mouse focus will go to the next highest control (#31), which is address line 1 on the subform. (There will be no control with #30, because that control is really just a placeholder for the subform; this means that tab spot #30 essentially is vacant.)
You need to ensure that you don't have criss-crossing in your tab ordering numbers between the controls on the main form and the subform. As shown in the example above, the 9 controls on the address subform will claim spots 31 - 39. Therefore, whichever control you want the user to go to after the province field, made that control 40 (or higher).
Also, make sure that you don't assign any of tab spots 31-39 to controls on the main form. If you do, then that will cause the focus to jump back and forth between the controls on the main form and the subform. On the illustrated form, the entire 40s range is skipped, and the next highest control on the form is #49 (Validate Address button). This means that when the user tabs out of province on the subform then the focus will go to Validate Address, and then Home Information - Set As Primary? (#50).
Putting it altogether, given the tab ordering above, here's the order the user will go on the actual form, starting from the e-mail field, going into and then out of the subform, and ending at exclude from social?. Note that, by design, the tab order jumps from address type down to country, then back up to Address Line 1. This is by design, so the user can first choose a county, and then enter the rest of the address. Since the country dropdownlist directs which subform to display, we need the user to go their first.
Best Practices
- Generally, order the controls on the subform to start with 1 and then go up in order (1, 2, 3, etc.)
- When you order the main form, order the subform control normally. For example, if you have 10 controls above the subform, then order the subform 11.
- If you have controls after the subform, then be sure to start with a tab order that is higher than the sum of the subform control + the highest tab order on the subform's own controls. For example, if you have 5 controls on the subform, and the subform control will take spot 11, then you might want to make the next highest control on the main form be 20. Although you could get by with 17 (as the last control on the subform will be 16), jumping up to 20 will give you room to grow if you should add a couple more fields onto the subform. If you want to be safer, just jump all the way up to 30.
- The same principles apply if you have more than one subform on a form, or if you have nested subforms.