Siebel Open UI: Format All the Lists - Part 2
In continuation of our mini-series, we will today explore an example solution for a generic physical renderer extension for list applets in Siebel Open UI.
As discussed in the previous part, the solution we want to achieve is that we can define a list of fields which should be conditionally formatted if they are exposed as columns on a list applet. The implementation uses custom applet user properties which are exposed to the physical renderer by a custom presentation model extension.
Today, the focus is on the physical renderer. Before we start, let me reiterate that many ways lead to Rome and the solution presented below is purely educational and should you intend to use it in any environment, including production environments, you do so at your own risk.
Implementing a Physical Renderer for Conditional Formatting
We start with the usual procedure of creating a physical renderer extension file and registering it with a test applet (e.g. the Opportunity List Applet). Remember that the Oracle class for list applet PRs is JQGridRenderer, so this is the correct call for SiebelJS.Extend():
SiebelJS.Extend(ConditionalFormatListPR, SiebelAppFacade.JQGridRenderer);
As the formatting takes place when the data is present in the applet, the BindData method is the one we must override, as this method populates the grid cells with the actual data and is called frequently enough (e.g. after a record is updated or during scrolling) for a first prototype.
The following shows the example implementation of the BindData method:
The code accomplishes the following:
As discussed in the previous part, the solution we want to achieve is that we can define a list of fields which should be conditionally formatted if they are exposed as columns on a list applet. The implementation uses custom applet user properties which are exposed to the physical renderer by a custom presentation model extension.
Today, the focus is on the physical renderer. Before we start, let me reiterate that many ways lead to Rome and the solution presented below is purely educational and should you intend to use it in any environment, including production environments, you do so at your own risk.
Implementing a Physical Renderer for Conditional Formatting
We start with the usual procedure of creating a physical renderer extension file and registering it with a test applet (e.g. the Opportunity List Applet). Remember that the Oracle class for list applet PRs is JQGridRenderer, so this is the correct call for SiebelJS.Extend():
SiebelJS.Extend(ConditionalFormatListPR, SiebelAppFacade.JQGridRenderer);
As the formatting takes place when the data is present in the applet, the BindData method is the one we must override, as this method populates the grid cells with the actual data and is called frequently enough (e.g. after a record is updated or during scrolling) for a first prototype.
The following shows the example implementation of the BindData method:
Click to enlarge. |
- Initialize variables with the values of the applet user properties by using the PM�s Get method.
- Verify that a list of fields is actually defined for the applet. If yes, the code continues. If not, the else block is reached and a console message is logged.
- Split the comma separated lists into arrays using the split function.
- Use the GetColMap method of the object returned by the GetColumnHelper method to get a list of columns and their respective business component field names. Note that the two methods used here are specific to physical renderers for list applets and are not documented.
- Iterate through the array of fields. For each field, a second loop iterates through the column list and tries to locate a column associated with that field. When a column is found, the ConditionalFormat method (to be implemented below) is invoked and the name of the column as well as the accompanying threshold value are passed as arguments.
Click to enlarge |
This part of the custom function does the following:
- Get the current record set from the GetRecordSet property, i.e. all records currently visible in the list applet.
- Get the applet placeholder which will be used to identify the applet and its child elements.
- Get the column map for the applet.
- Retrieve the business component field name for the current column from the column map.
- Access the column header using the jQuery $() function.
- Use the jQuery click() event handler to specify a function which is executed when the end user clicks the column header. This function uses the event object to determine whether the CTRL key has been pressed while clicking. If this is the case, the click event handler function uses the stopImmediatePropagation() method to prevent the click event from �bubbling�, i.e. attracting other event handlers.
- For demonstration purposes, a simple prompt() dialog is used to solicit the new target value from the end user. This could be replaced by a more comfortable jQuery dialog or similar in a real production setting. Finally, the click event handler function invokes the ConditionalFormat method (recursively) to refresh the formatting.
- By adding an img tag to the existing column header HTML code, the function effectively provides a visual cue to the end user that the column and its header have a special purpose. The example code also modifies the title attribute to produce a tooltip message.
Now that we have all variables initialized and the column header modified, we can implement a loop through the record set to take care of each cell's background color:
Click to enlarge. |
This final loop does the following:
- Retrieve the pseudo row identifier (1,2,3 and so forth).
- Select the current row using the jQuery find method.
- Select the grid cell for the column.
- Retrieve the cell�s value, which is actually the formatted and localized value.
- Use the replace function to remove characters like $, % or commas from the value string (watch out for localization issues here, the example is for the ENU locale).
- Convert the string to a floating point number.
- Calculate the share of the current value in percent of the target (threshold) value.
- Calculate the green and red color components for the current share. The algorithm increases the green value until the share reaches 50% and then reduces the red value. This results in a red/yellow/green color gradient.
- Use the calculated color to set the background of the cell with the jQuery css() method. For compatibility reasons the example code shows how to set a solid background as well as use the vendor specific linear-gradient CSS rules. A browser which understands the linear-gradient rule will apply it, other browsers will show a solid background.
After correctly associating this physical renderer example with a test list applet which has the necessary user properties defined, we can verify that the behavior is expected. Here is a screenshot of the sales order list applet after specifying the NRC Total field for conditional formatting.
Click to enlarge. |
After the test with a single list applet, we can modify the manifest administration to use the DEFAULT LIST APPLET entry for a physical renderer. Be aware that even the slightest error in the custom code could render any list applet unusable, including the ones you would need to undo your changes. If you find yourself in this undesirable situation, either rename the custom JavaScript file, so the browser can't download it or use the High-Interactivity client to access the Manifest Administration view.
Summary
The educational example in this and the previous article demonstrates the possibility of writing generic presentation model and physical renderer extensions for list applets. By externalizing as much code as possible we can limit the amount of code to achieve a consistent behavior across all UI objects of the same type.
Full Code Examples
The full code examples (for IP 2013 or higher) are available for download:
have a nice day
@lex
תגובות
הוסף רשומת תגובה