Adding controls at run-time in your form? Your controls might not work as expected, if you haven't considered this already

  


Imagine a situation where you need to add controls to a form, on run time. You have a dynamic source, (example, a booking app, where user would keep on adding newer choices, and you need to bring them to your form as checkboxes -- there is no prefixed set of choices beforehand: it would vary), and you need to add controls to your form by looping through your datasource.
A cool way of doing this is to use: Form build controls. For example, for the above situation, you can add FormBuildCheckBoxControl. Or if you need to fill in into a combobox control, you might use FormBuildComboBoxControl. 
 
So what are FormBuild controls actually? For example, the FormBuildComboBoxControl class lets you create, read, update, and delete X++ code and metadata. It behaves as if you are still in designing the UI and can keep on changing the metdata of various controls, while actually you are running the code.
How to add a FormBuild control:
The following code shows that you are adding a formBuildComboBoxControl to a control group:

formBuildComboBoxCtrl = controlProdAttributeGroups.addControl(FormControlType::ComboBox, strrem(ecoResProductTranslation.Name, ' '));

Where controlProdAttributeGroups is actually the parent group, under which the combo box should appear.
You can give a label to it: formBuildComboBoxCtrl.label(ecoResAttributeType.Name);
You can add items to it:
while select TextValue from prodContextValue
                            where prodContextValue.Value  == ecoResProduct.RecId
{
                            i++;

                            formBuildComboBoxCtrl.item(i);
                            formBuildComboBoxCtrl.text(prodContextValue.TextValue);
}

Alright -- up till here, everything looks good.
Now I would like to make the controls be made visible/invisble on certain situation. Now here is the catch: suppose you have written the above code in the init, aftersuper (meaning after all your form controls got initated), then you can easily do this by saying:
FormBuildControl childControl = _parentControl.controlNum(i);
childControl.visible(false);
Where parent control is the group control under which you have added your control, programtically.
But if you want to do this before init, you have to do this by:

            int controlId = _childControl.Id();
            if (controlId)
            {
                FormControl cnt  = element.design().control(controlId);
                if (cnt)
                {
                    cnt.visible(_visible);
                }
            }
This is because 'element.design' gets initated only after init. 
Please note: if you want to say chindControl.visible(false) after super of init, it won't simply work. Why? 
FormBuildControls are like compiled/built-up controls. Once after 'init' they cannot be accessed to make changes to their metadata. Hence they have to typecasted as FormControl and then their metadata could be manipulated. 
                                   

Comments

Popular posts from this blog

X++ : mistakes which developers commit the most

Make your menu items visible on main menu, conditionally,, using this cool feature of D365FO

Speed up your execution performance by using SysGlobalCaches