
There’s a few different ways to show and hide elements on a page at runtime in bpm’online. First and foremost, if you’re just hiding fields on the screen, whether that is based on a value or not, your first stop should be to add this using the business rules on the page. In the page editor, you’ll see a tab for Business Rules. There you can click Add and in the “THEN” section, select “Show field on the screen”. The “IF” part can use a value on the page as the condition for showing and hiding the field. Pretty easy, but this method doesn’t work for all cases.
If you need to show/hide the field based on the result of an EntitySchemaQuery, for example, this method won’t work since the ESQ result is asynchronous and you also don’t have that value as a condition for the rule. Also, what if what you want to hide is more than just a single field, such as an entire Field Group or Detail? In that case, you can easily hide the field group, detail, or other element using some simple code. Let’s review the steps:
To show or hide any element on the page, you’ll use these steps:
- Add an attribute to the page. This will be a virtual field (not a database field) that is a boolean value
- You’ll bind the visible property of the element in the diff to this attribute
- To show or hide the element, you’ll use code to set the attribute you created in step 1 as true or false using this.set("MyAttributeName, false) just like any field on the page.
The nice thing about doing things this way, is that it doesn’t matter if you’re showing/hiding the element from the result of an ESQ and in an asynchronous callback since all you’re doing is setting the attribute value whenever you want. Note, there are a lot of other ways to show/hide an element, such as binding the visible property of the element in the diff to a function that returns a true/false, however, that method won’t work for an asynchronous result.
In this example, we’ll be using this method to show or hide a field group on the page. Let’s take a look at how simple the code looks to do this. First, we’ll add the attribute:
attributes: { "IsFieldGroupVisible": { dataValueType: Terrasoft.DataValueType.BOOLEAN, type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN, value: true } }
Here’s what we’ve done for that attribute. First, we’ve made the data type of the attribute as a boolean and as a virtual attribute that only lives on this page. We’ve also initialized this attribute as true (in this case meaning it is visible). The reason for defaulting this to true is that if you bind this attribute to a page element, and it’s initial value is false, it will also be hidden in the page designer as well, which can make it difficult to work with.
Once we have our attribute, we’ll want to bind it to the visible property of the field group in the diff. Finding this can be tricky since the page designer doesn’t name it in some obvious way. Here’s how you can find the control group in the diff.
- Pick a field that you’ve added to that control group and get it’s property/column name
- Do a CTRL+F in the page code to locate that control in the diff. You’ll find it with "bindTo": "UsrMyFieldName"
- For that control, look at it’s parentName property, then copy that and find it using a CTRL+F to locate it with something like "name": "Tab84fb2bb2TabLabelGridLayout7a77f4ac"
- When you find that, get that element’s parentName and find that using CTRL+F again, this is your control group. The page designer will add “TabLabelGroup” in the control group name value and the “itemType” will be either 15 or “Terrasoft.ViewItemType.CONTROL_GROUP”, just so you’re sure you’ve found the correct element.
Basically, a control is two levels down from the control group it’s in. Now that you have found the control group element, you can bind it’s visible property to the attribute you created earlier. In the control group in the diff, add the following in the “values” section.
"visible": { "bindTo": "IsFieldGroupVisible" }
The complete control group element in the diff will look something like this:
{ "operation": "insert", "name": "Tab84fb2bb2TabLabelGroup34515867", "values": { "caption": { "bindTo": "Resources.Strings.Tab84fb2bb2TabLabelGroup34515867GroupCaption" }, "itemType": 15, "markerValue": "added-group", "items": [], "visible": { "bindTo": "IsFieldGroupVisible" } }, "parentName": "Tab84fb2bb2TabLabel", "propertyName": "items", "index": 0 }
Now you can show or hide the control group by just setting the IsFieldGroupVisible attribute to true or false. Something like this:
onEntityInitialized: function() { this.callParent(arguments); if (this.get("UsrSomeField") === "Some value") { this.set("IsFieldGroupVisible", false); } else { this.set("IsFieldGroupVisible", true); } // etc }
As I mentioned before, this method of using an attribute to show or hide the field is always the way to go. If we wired up the visible property to a function, which you can do, we don’t have any guarantee that the value we want to check will be available. Also, if we’re doing an ESQ to get some value from another object to determine if we want to show or hide the element, using a function to set visibility won’t work since the result is asynchronous. Using an attribute will always work since the property is bound to the attribute and will change as the attribute changes. There’s several different ways to how/hide anything at all on the page (such as using the rules section in the page code), however, I find this method the cleanest/easiest. Note, this method doesn’t work for tabs. To show and hide tabs check out my article on showing and hiding tabs.
To use this method for showing or hiding a detail, the steps are the same, but finding the detail element is easier. Just go to the details section, find your detail (by looking for the detail’s object name), then use it’s name property to locate it in the diff and add the same code (adding the “visible” property to the detail’s “values” section).
Note: As of Creatio version 7.16.3, you can now also show or hide control groups and tabs using business rules on the page as well. However, if you need to do it programmatically, the method outlined in this article will also still work.
…we don’t have any guarantee that the value we want to check will be available.
Thank You! – In my case I had a panel and a header label which I needed to hide based on whether a .repx file was called as an invoice or a quote (DevExpress embedded in an ERP). I simply made a hidden label and bound it to a column value I knew would distinguish the two types of the report I needed to generate. However, the label I needed to show/hide was only working on page 2 and subsequent pages.
The original panel I added was in the footer, so was my hidden field/label. So it wasn’t available until the footer was generated, and thereafter. Moved my bound label to the header and it works swimmingly. No question yours is a better solution, but I appreciate the dissection as it helped me to remember something that probably should have been obvious. Thanks again!