3.10.2. Extending Screens
The platform supports creating new XML descriptors by inheriting them from the existing ones.
XML inheritance is implemented by specifying the parent descriptor path in the extends
attribute of the root window
element.
XML screen elements overriding rules:
-
If the extending descriptor has a certain element, the corresponding element will be searched for in the parent descriptor using the following algorithm:
-
If the overriding element has the
id
attribute, the corresponding element with the sameid
will be searched for. -
If the search is successful, the found element is overridden.
-
Otherwise, the platform determines how many elements with the provided path and name are contained in the parent descriptor. If there is only one element, it is overridden.
-
If the search yields no result and there is either zero or more than one element with the given path and name in the parent descriptor, a new element is added.
-
-
The text for the overridden or added element is copied from the extending element.
-
All attributes from the extending element are copied to the overridden or added element. If attribute names match, the value is taken from the extending element.
-
By default, the new element is added to the end of the list of adjacent elements. In order to add a new element to the beginning or with an arbitrary index, you can do the following:
-
Define an additional namespace in the extending descriptor:
xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd"
. -
Add the
ext:index
attribute with a desired index, for example:ext:index="0"
to the extending element.
-
In order to debug the descriptor conversion, you can output the resulting XML to the server log by specifying the TRACE
level for the com.haulmont.cuba.gui.xml.XmlInheritanceProcessor
logger in the Logback configuration file.
- Extending Legacy Screens
-
The framework contains a number of screens implemented with legacy API for backward compatibility. Below are examples of extending screens of the
User
entity from the security subsystem.First, consider a browser screen of the
ExtUser
entity:ext-user-browse.xml<?xml version="1.0" encoding="UTF-8" standalone="no"?> <window xmlns="http://schemas.haulmont.com/cuba/window.xsd" xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd" extends="/com/haulmont/cuba/gui/app/security/user/browse/user-browse.xml"> <layout> <groupTable id="usersTable"> <columns> <column ext:index="2" id="address"/> </columns> </groupTable> </layout> </window>
In this example, the descriptor is inherited from the standard
User
entities browser of the framework. Theaddress
column is added to the table with index2
, so it is displayed afterlogin
andname
.If you register a new screen in screens.xml with the same identifiers that were used for the parent screen, the new screen will be invoked everywhere instead of the old one.
<screen id="sec$User.browse" template="com/sample/sales/gui/extuser/extuser-browse.xml"/> <screen id="sec$User.lookup" template="com/sample/sales/gui/extuser/extuser-browse.xml"/>
Similarly, let’s create an edit screen:
ext-user-edit.xml<?xml version="1.0" encoding="UTF-8" standalone="no"?> <window xmlns="http://schemas.haulmont.com/cuba/window.xsd" xmlns:ext="http://schemas.haulmont.com/cuba/window-ext.xsd" extends="/com/haulmont/cuba/gui/app/security/user/edit/user-edit.xml"> <layout> <groupBox id="propertiesBox"> <grid id="propertiesGrid"> <rows> <row id="propertiesRow"> <fieldGroup id="fieldGroupLeft"> <column> <field ext:index="3" id="address" property="address"/> </column> </fieldGroup> </row> </rows> </grid> </groupBox> </layout> </window>
Register it in
screens.xml
with the identifier of the parent screen:<screen id="sec$User.edit" template="com/sample/sales/gui/extuser/extuser-edit.xml"/>
Once all the above-mentioned actions are completed, the application will use
ExtUser
with the corresponding screens instead of the standardUser
entity of the platform.Screen controller can be extended by creating a new class that is inherited from the base screen controller. The class name is specified in the
class
attribute of the root element of the extending XML descriptor; the usual rules of inheriting XML described above will apply. - Extending screens using CUBA Studio
-
In this example, we will add an
Excel
button to the customer browser table by extending the screen for theCustomer
entity from the Customer Management component described in Example of Application Component.-
Create a new project in Studio and add the Customer Management component.
-
Select Generic UI in the project tree and click New > Screen in the context menu. Then select the Extend an existing screen on the Screen Templates tab. In the Extend Screen list, select
customer-browse.xml
. The newext-customer-browse.xml
andExtCustomerBrowse.java
files will be created in the web module. -
Open the
ext-customer-browse.xml
and switch to the Designer tab. The components of the parent screen are displayed in the designer workspace. -
Select the
customersTable
and add a newexcel
action. -
Add a button to the
buttonsPanel
linked to thecustomersTable.excel
action.
As a result, the
ext-customer-browse.xml
code on the Text tab will look as follows:ext-customer-browse.xml<?xml version="1.0" encoding="UTF-8" standalone="no"?> <window xmlns="http://schemas.haulmont.com/cuba/screen/window.xsd" messagesPack="com.company.sales2.web" extends="com/company/customers/web/customer/customer-browse.xml"> <layout> <groupTable id="customersTable"> <actions> <action id="excel" type="excel"/> </actions> <buttonsPanel id="buttonsPanel"> <button id="excelButton" action="customersTable.excel"/> </buttonsPanel> </groupTable> </layout> </window>
Consider the
ExtCustomerBrowse
screen controller.ExtCustomerBrowse.java@UiController("customers_Customer.browse") @UiDescriptor("ext-customer-browse.xml") public class ExtCustomerBrowse extends CustomerBrowse { }
As the screen identifier
customers_Customer.browse
matches the identifier of a base screen, the new screen will be invoked everywhere instead of the old. -