Shared elements provide an opportunity to create "reusable code", with its traditional benefits of greater efficiency and single instance maintenance, in Logi reports. This topic discusses shared elements.
About Shared Elements
Developers often find that they're using the same elements, or groups of elements, repeatedly in multiple report definitions. Report headers and footers are good examples. However, rather than adding these elements or groups of elements repeatedly into numerous report definitions, and being faced with the challenge of maintaining them, developers can instead use shared elements.
A "shared element" is a container for one or more elements, identified by the shared element ID. It's referenced with a kind of placeholder element in a definition. At runtime, the Logi Server Engine replaces the placeholder with the actual elements from the shared element container, before the report HTML is generated.
Any changes made to a shared element "ripples through" to every definition that uses it, which makes maintenance easy. For example, you may wish to add a copyright message in your pages; by making it a shared element, you'll only have to change the year in one location each January.
A shared element also provides a level of abstraction similar to that found in object-oriented programming: a shared element can produce different results in different report definitions based on the data or variables fed to it. So it's not only reusable but its results and behavior can be dynamic based on external factors, including tokens, definition modifiers, stylesheets, etc. that reside in the definition that uses the shared element. This is a powerful feature that developers can leverage to make themselves more efficient and their reports more reliable.
The examples below are from the Template Modifier Files sample application. Please read this topic carefully as the words "shared" and "element" appear many times in many ways and can be confusing.
A Master Report is a special report definition that includes elements that are to be included in other reports. It's frequently used to provide a template-like frame, often defined with a header, a menu, and a footer, for integration with other reports. You may find this to be an useful alternative to building the same thing using shared elements. For more information, see Intro to Master Reports.
The Shared Element Params element allows you to pass values into a shared element. These values are applied before the shared element is inserted into the calling report definition, making the shared element itself dynamic. The Passed Shared Element element even allows you to pass and include groups of elements, from the calling definition, into a shared element. These elements are discussed in more detail in later sections.
The Include Shared Element element has a Condition attribute, allowing you to dynamically employ shared elements.
Shared elements can be defined in any report definition but the recommended practice is to create one or more separate report definitions in Logi Studio just to hold shared elements:
In the example shown above, a separate definition named "sharedElements" has been created to hold the shared elements. This approach has several benefits, including the possibility of copying the definition file itself to other Logi applications, extending the reusability concept and enforcing consistency.
If you're creating a shared elements definition for a Mobile Reporting application, be sure to place the definition within the Mobile Reports folder.
In the sharedElements definition, as shown above, a shared element definition is started by adding a Shared Element element. This is the basic container for one or more elements that you want to share. Be sure to give this element the required unique ID. This definition doesn't need any of the standard elements usually found in a report definition, such as Style, Report Header, Body, and Report Footer.
A definition file can hold many Shared Element elements, each containing one or more elements to be shared.
As shown above, a variety of elements can be added beneath the Shared Element element. These can include any element available for report definitions. In the example, elements have been added to create a common header for several reports.
Your shared elements are now available to any report definition in your application.
Using your shared elements in a report definition is very easy. Here's how to use a shared report header:
- Add an Include Shared Element element to your report definition, as shown above, in this case beneath the Report Header element.
- Set its Definition File attribute value by selecting the sharedElements definition from the drop-down list of definitions.
- Set its Shared Element ID attribute value by selecting the SharedHeader definition from the drop-down list of shared elements in the previously selected definition.
Include Shared Element elements can be added anywhere in your report definition, and the same shared element can even be used multiple times in the same definition, if necessary.
As soon as you select the shared element in the Attributes panel, its contents will be displayed, in read-only mode, in the Element Tree, as shown above. Any modifications to it must be made in the definition that contains the shared element.
Now you can copy the configured Include Shared Element element into the Report Header of every report definition in an application. This will result in the same header appearing on every report.
Shared elements can also be used to include common but non-visual code in definitions, such as shim scripts, meta tags, and more.
Shared elements can be made dynamic by passing them parameters. The passed values are then applied to the shared elements before they're included in the report definition. Here's an example:
Imagine that we want to make use of shared report header code, but we want to change the location displayed with the logo (highlighted above), depending on some variable. Shared element parameters are perfect for this situation.
In the example code above, in our Default report definition, we added an Include Shared Element element ("sharedHeader") beneath the Report Header element. As usual, the code from the shared element appears in Read-Only mode beneath it ("Rows").
Next, we added a child Shared Element Params element and created a single parameter, "OfficeLocation", and gave it a value. The value can be literal or derived from tokens, as shown. This parameter will tell the shared code which location text to use in the header.
In the shared element definition, shown above, we can see how the passed parameter is used. The @Shared token provides access to the passed parameter. In our example, it's used in a Condition attribute to control which column is displayed in the header.
If tokens are used for parameter values, note that they are passed as intact tokens, not as the token values. The tokens will not be resolved in the shared element definition - instead, they'll be inserted with the shared elements into the calling report definition and will be resolved when the report definition is rendered.
myParam1="Welcome to McLean"
To further clarify how they're used, the XML source code for some examples of Shared Element Parameters is shown above.
<SharedElement ID="mySharedElement" >
<Label Caption="@Shared.myParam1~" />
<Label Caption="@Shared.myParam2~" />
<Label Caption="@Shared.myParamReq~" />
<Label Caption="@Shared.myParamSes~" />
<Label Caption="@Shared.myParamData~" />
<Label Caption="@Shared.myParamProc~" />
<Label Caption="@Data.@Shared.myParamColName~~" />
The XML source code above shows a Shared Element element and the passed parameters being used in Label elements via @Shared tokens. This is similar to the way you'd use @Request tokens to access the values of Link Params in a Process Task.
Note that the last Label element above uses a nested token - when the calling report definition is rendered, the inner token (@Shared) will be resolved first, providing the literal column name, then outer token (@Data) will be resolved. For more information, see the "Nesting" Tokens section of Token Reference.
<Label Caption="Welcome to McLean" />
<Label Caption="7900" />
<Label Caption="@Request.myVal~" />
<Label Caption="@Session.myVal~" />
<Label Caption="@Data.myColumnVal~" />
<Label Caption="@Procedure.myVal~" />
<Label Caption="@Data.myColumnName~" />
When the calling report definition is processed and the shared element is inserted into it, the source code for the inserted Label elements would look like the examples above. Note how the Caption attributes relate to the original shared element parameters.
There may be situations where it's desirable to pass entire elements into a shared element. The passed element is then added to the shared element before it's applied to the calling report.
Imagine that you provide a report with a footer that includes a logo image and standard menu links, like the one shown above. Depending on the consumer, you need to show a different logo and the images are different sizes and types. Passing a configured Image element to the shared element is a good solution.
This time we'll start our example, shown above, in the sharedElements report definition and construct our footer. Where the logo image will appear, we added an Include Shared Element element. When configuring it, we used the special identifier "PassedSharedElement" for the Definition File attribute (it appears at the very top of the pull-down list of options), and the ID that we'll give later to the Passed Shared Element element in the calling definition.
In our Default definition, shown above, we added an Include Shared Element element in the footer. Beneath it, we added a Passed Shared Element element and set it ID attribute to match the one we used in the sharedElement definition. Then we added child elements beneath it, including the Image element we're passing.
Using Division elements as containers for the image allows us to make the choice of image conditional, based on the Divs' Condition attributes.
This is a very powerful feature. Another interesting possible implementation would be to use a Passed Shared Element to pass a datalayer to a visualization, allowing it to work with data from different data sources.
- The insertion of the shared XML source code in a shared element into a report at runtime is done without dynamic review of the "parent-child" element relationship rules, so it's possible to include shared elements where they don't belong. Therefore, as the developer it's your responsibility to ensure that the "element rules" are being followed. To do this, we recommend that you create shared elements by first, using all the elements to be shared right where they belong,
directly in a report, then successfully testing them, then copying them out to the shared element definition, and finally replacing them with the Include Shared Element element.
- Multiple Shared Element elements can be placed in the same definition:
- Stylesheets apply to shared elements in several ways. If the shared elements do not include a style sheet of their own then the style sheet of the definition using the shared elements is applied. If a style sheet is included in one of the shared elements, then any style classes with the same name in both it and the report definition's style sheet will cascade.
- Both the Definition File and Shared Element ID attribute values of the Include Shared Element element can be specified using tokens.
- If a shared element definition file becomes very large, it may be useful and may improve performance to create multiple shared element definition files. Some developers group their shared elements into different definition files based on their function or purpose.
- Action.ShowElement cannot be used to show/hide an Include Shared Element element, although use of Division elements can achieve conditional inclusion of shared elements.
- Shared elements are inserted into a report definition when the report runs, so any Request parameters that are passed to the report can be used in the shared elements. Similarly, shared elements can work with data from a datalayer in a parent report definition, but they must be in scope; i.e. inserted beneath the chart or table that's the parent of the datalayer. The exception to this is data from LocalData, which can be used throughout the report and shared elements.
- You may also include shared elements in Process definitions.