Extend screen.xml components with custom components

Hi,

i’ve a general question about the extensibility of the screen XML definitions. I read your blog post about how to integrate external UI components which is great.
Nevertheless i thought of another probably more tighter integration into the application, especially into the screens XML definition.

Let’s take Yuiry’s example about vaadin-wizard-example which uses the corresponding vaadin addon. The integration is slightly easy because it’s already a vaadin add-on.
But what i thought of is the following. Let’s assume i want to be able to write in my XML editor screen definition like this:


<wizard id="myWizard">
<step id="myId">
  <fieldGroup id="fieldGroupWithFirstFiveAttributes">
</step>
<step>
  <fieldGroup id="fieldGroupWithSecondFiveAttributes">
</step>
</wizard>

because i want to provide the same ease of use or the same programming model to my application as i already have with other CUBA components.
My general solution to this problem would be to ask here if this can be added to the platform. This is fine, but probably will not always a success. Therefore my question is, if it is at all (with a reasonable amount of time) possible to extend the screen.xml definition?

I don’t even talk about studio integration of these extensions but more of how i get another completely new component into the application? I saw window.xsd as a starting point, but it would be great to illustrate a walk through the different building blocks on how to achieve something like this.

Bye
Mario

Hi,

thanks for your answers. I’ll dig into this a little further, but the examples look exactly like the things i want to do.

Your examples created a whole new XML tag. Is the solution also suitable (and the most preferred solution) in term that i want to change an existing XML attribute and add different default values?
One example of this would be that for the filter tag i always want to be defaultMode=“fts” in case nothing is set in the XML.

Another example would be if i want to create a XML tag that itself is just a wrapper to an already existing XML tag? An example would be


<myTable columns="a,b,c" / >

which should translate into


<filter id="filter"
                applyTo="collectionTable"
                datasource="collectionDs">
            <properties include=".*"/>
        </filter>
        <table id="collectionTable"
               width="100%">
            <actions>
                <action id="create"
                        openType="DIALOG"/>
                <action id="edit"
                        openType="DIALOG"/>
                <action id="remove"/>
            </actions>
            <columns>
                <column id="a"/>
                <column id="b"/>
                <column id="c"/>
            </columns>
            <rows datasource="collectionDs"/>
            <rowsCount/>
            <buttonsPanel id="buttonsPanel">
               <!-- ... -->
            </buttonsPanel>
        </table>

Or are there other approaches to achieve this in another more preferable way?

Bye
Mario

Hi Mario,

Screen XSD files are extensible and you can create and use your own XSD definitions to enable IDE auto-complete and XML highlighting. For example, charts uses such a separate XSD file: http://schemas.haulmont.com/charts/6.3/charts.xsd

Note that CUBA runtime does not depend on XSD schemas, no need to register your XSDs in application configuration files.

CUBA runtime uses separate classes called loaders, e.g. com.haulmont.cuba.gui.xml.layout.loaders.LabelLoader and you can load component properties from a really custom XML structure if you implement this logic in your XML loader.

You can read more about integrating Vaadin add-on into CUBA generic UI here: https://doc.cuba-platform.com/manual-6.3/vaadin_addon_sample_gui.html There we show how to implement custom XML loader and how to create XSD file in a project for custom components.

Hi Mario,

Have a look at the example on my github. XSD extension is defined here and component loaders are implemented here.

Regards,

Aleksey

Yes, you can parse very complex XML structures (see com.haulmont.cuba.gui.xml.layout.loaders.AbstractTableLoader), but XML transformations are not supported and you will have to create all the nested components inside your Loader code. So, there is no simple way of implementing wrappers right now.

Hi Yuiry,

so just to recap what you said about the wrapping functionality. Let’s take the wizard example from above:


<wizard id="myWizard">
<step id="step1">
  <fieldGroup id="fieldGroupWithFirstFiveAttributes">
</step>
<step id="step2">
  <fieldGroup id="fieldGroupWithSecondFiveAttributes">
</step>
</wizard>

If i want to implement that and not use the wizard vaadin addon, but instead just want to make this as some kind of a domain specific language for other CUBA components, this is hardly possible - correct?

Lets assume it should create a UI that looks like this (that does not mean that it has to do XML transformations, but it just means that it should transform into something that looks like this if i would have created it manually through studio):


<hbox id="myWizard">
<vbox id="buttonVBox">
<buttonPanel><button id="btn1"/><button id="btn1"/></buttonPanel>
</vbox>
<vbox id="step1">
  <fieldGroup id="fieldGroupWithFirstFiveAttributes">
</vbox>
<vbox id="step2">
  <fieldGroup id="fieldGroupWithSecondFiveAttributes">
</vbox>
</hbox>

The reason that i might want this encapsulation of the CUBA components is that i want to define a standard way of creating certain UI screen parts (like a wizard).

The second question is that even if this is possible to create, if it is possible to let Studio (especially the UI screen designer view) know about the semantics of my “wizard” tag. So in this case it would be, that studio will know that the steps are just vboxes basically, so it is able to show the content in the designer and not just create white element named “wizard”. Because then i would loose the whole screen designer feature.

Basically it would be that i would then trade ease of use (with the UI designer) for code reuse (with the encapsulation of the tag).

Bye
Mario

In that case I’d recommend that you create a reusable component instead of generating component structure in Loader because you cannot provide additional API for your component structure.

Of course it is possible to write such a loader that will create complex components tree, but now it is impossible to add support for it to Studio. Also there is no support for composite components in Studio, so you cannot create your custom Layout component - only simple components are supported.

If you are interested in simple component structures generated by loader see my sample project:
https://github.com/cuba-labs/composite-panel-loader See loader code here

There I create composite panel with the following XML structure:


<demo:compositePanel id="demoPanel">
    <demo:page caption="On-line"></demo:page>
    <demo:page caption="Cart"></demo:page>
    <demo:page caption="Demo"></demo:page>
</demo:compositePanel>

Composite panel loader produces CssLayout with inner TabSheet and tabs:

composite-panel-loader