Friday 14 November 2014

Open UI - styling your form applets - add sections or tabs!

Most of the complaints you hear from typical Siebel users is that their screens are bulky, seeing a lot of unnecessary fields dumped into one big form applet. How about redesigning them so that you logically group only the relevant fields into one group and show only that group at a time.

I found Jquery UI has accordion and tab options to display content in group. See below to see them in action.
ezgif-optimize

You can get Accordion demo on jquery ui site here: http://jqueryui.com/accordion/


ezgif-optimize (1)


You can get Tabbed display demo on jquery ui site here: http://jqueryui.com/tabs/#mouseover

Go through their example to understand how they do it.

Now, I leveraged above in to my Siebel form applets and here is the outcome.



How to go about?


Most of your form applets are based on Web Template: “Applet Form Grid Layout”, swt file - CCAppletFormGridLayout.swt. If you open it and observe, you will see below code:
<div class="siebui-collapsible-applet-content">
         <swe:form-applet-layout>
         </swe:form-applet-layout>
</div>

Above code is responsible for displaying your form content into a <table>. You got no control over it. It runs through all the controls and adds to the table. I didn’t find any alternative to replace this with my own layout having <div> to enable tabs or accordion.

So, I exploited above and changed my Applet Layout (Applet –> Edit Web Layout) as below:

Applet: Opportunity Form Applet - Child
image


Applet: SIS Account Entry Applet
image

As you can observe above, I am adding HTML section and grouping controls under them. These HTML sections are going to be converted into Accordions/Sections or Tabs and controls will be shifted into those Accordions/Sections or Tabs using Jquery DOM manipulation.

Ok enough surprises, here is how the code looks like,

AppletAccordionPR.prototype.ShowUI = function () {
                SiebelAppFacade.AppletAccordionPR.superclass.ShowUI.call(this);
 
                var pm = this.GetPM();
                var appletId = "s_" + pm.Get("GetFullId") + "_div";
                var $FormLayoutTable = $("#" + appletId + " .siebui-collapsible-applet-content .GridBack");
 
                var $TabbedContent = GetAccordion($FormLayoutTable);
                $($FormLayoutTable).replaceWith($TabbedContent);
 
                $(function () {
                    $("#accordion").accordion({
                        event: "click hoverintent"
                    });
                });
}
This is what I am doing above, 
  • get appletId from pm

  • get handle for <table> holding your form layout – if you check on google chrome dev tools – you will see that the <table> has class .GridBack

  • Now, call your custom function GetAccordion to get a new layout

  • Call JqueryUI function .accordion() for your new <div id=”#accordion”> added by your function: GetAccordion. Remember I  told you to check JqueryUI demo and the code they have provided on their site. Check again, if you don’t get what I am doing here.
Finally, GetAccordion function explained here:

All it is doing is, looping through <tr> s within your <table> and
  • for each <tr> having .FormSection in it, (check on chrome, all HTML FormSection have class .FormSection) adds <h3>and <div> under which a new empty <table> will be inserted to hold all <tr>s. Again check the JqueryUI example to visualize.

  • Now for each <tr> not having .FormSection means, it is having controls in them. Copy them to empty  <table> you added above.
Below is the full function for your reference:
            function GetAccordion(ContentTable) {
                //main div to which accordion will be enabled in ShowUI
                var $AccordionsDOM = $("<div id='accordion'></div");
                
                //div to hold content for a section
                var $strAccordionDiv = $("");
                var skipInitRows = true;
                var AccordionIndex = 1;
                var AccordionOpen = false;
 
                if ($(ContentTable).length) {
 
                    //build an empty table to go into each FormSection
                    var $emptyTable = ($(ContentTable).clone());
                    $emptyTable.find("tbody").empty();
 
                    //Loop through the <tr>s
                    var $rows = $(ContentTable).find("tr");
                    $rows.each(function (i, row) {
                        //For <tr> check if it has FormSection
                        $FormSec = $(row).find('.FormSection');
                        if ($FormSec.length) {
                            //If so, check if it's not the first FormSection and if not, then append to main <div>
                            if (AccordionOpen) {
                                if ($strAccordionDiv.length) {
                                    $AccordionsDOM.append($strAccordionDiv);
                                }
                            }
                            skipInitRows = false;
                            //Initiate a new FormSection by adding <h3>
                            $AccordionsDOM.append($("<h3>" + $FormSec.text() + "</h3>"));
                            //initialize, contenct for new FormSection
                            $strAccordionDiv=$("<div></div>");
                            //Add empty table so that subsequent rows can be added to it.
                            $strAccordionDiv.append($emptyTable.clone());
                            AccordionOpen = true;
                            AccordionIndex++;
                        }
                        else if (!skipInitRows) //Add to the Accordion
                        {
                            // If <tr> is not a FormSection - means it is <tr> having controls, add to Accordion content
                            $strAccordionDiv.find("tbody").append($(row));
                        }
                    });
                    // Finally, add the last FormSection to main <div>
                    if (AccordionOpen) {
                        if ($strAccordionDiv.length) {
                            $AccordionsDOM.append($strAccordionDiv);
                        }
                    }
                }
                return $AccordionsDOM;
            }
If you have understood above example, you can code for Tabs too. Let me know if you struggle for tabs. I can explain!

Cheers,
Shiv

2 comments:

  1. Thank you so much for the post. It was very useful. Can you also share the code to get the Tab functionality? Thanks again in advance!!

    ReplyDelete
  2. Hi,

    Can you keep accordions open when you open another one? End Users should decide what to close.

    Some End users still want to see more or all fields.
    They could open all accordions and see all fields at the same time, resulting in showing the original form applet.

    ReplyDelete