Expanding/Collapsing Menus with CSS and Javascript in Workflow Forms

Here’s a gif illustration featuring a decent-looking expandable menu system for a form I’m working on.  Instead of trying to fit all the required fields into a single visible panel, I wanted the user to be able to view information on demand, and only have the pertinent asset info at the top of the element set.

Symantec Workflow Expanding/Collapsing Menus Concept
In order to make the user experience more fluid, I created an expandable/collapsible menu system from CSS classes and javascript onclick events.

Here’s the javascript, and this code goes in the “Script” section in the Form Builder canvas options (note – if you copy/paste, paste it first into Notepad so that the html doesn’t come along too):


/// declare global css classes
classCollapsed = 'gaMenuPanelCollapsed';
classExpanded = 'gaSmallDetailsPanel';
/// collapse called panel
function collapsePanel(panelid){
panelid.className = classCollapsed;
}
/// expand called panel
function expandPanel(panelid){
panelid.className = classExpanded;
}

function setPanels(label, panel){
/// declare variables
var panelOne = document.getElementById('Panel1');
var panelTwo = document.getElementById('Panel2');
var panelThree = document.getElementById('Panel3');
var labelOne = document.getElementById('Label1');
var labelTwo = document.getElementById('Label2');
var labelThree = document.getElementById('Label3');
/// declare array variables
var panels = [panelOne, panelTwo, panelThree];
var labels = [labelOne, labelTwo, labelThree];
/// declare clicked section variables
var labelElem = document.getElementById(label);
var panelElem = document.getElementById(panel);
/// flag current panel state
var panelOpen;
if (panelElem.className == classCollapsed) {
panelOpen = 'False';
} else {
panelOpen = 'True';
}
/// declare button
var goButton = document.getElementById('GoButton');
/// collapse panels
for (i = 0; i < panels.length; i++) {
collapsePanel(panels[i]);
}
/// reset labels and panels
for (i = 0; i < labels.length; i++) {
if (labels[i] != labels[0]) {
var prevLabelIndex = (i - 1);
var prevLabel = labels[prevLabelIndex];
labels[i].style.top = parseInt(prevLabel.style.top) + parseInt(prevLabel.style.height);
panels[i].style.top = parseInt(prevLabel.style.top) + parseInt(prevLabel.style.height) + parseInt(labels[i].style.height);
}
}
if (panelOpen === 'False') {
expandPanel(panelElem);
/// declare and refresh expanded panel height
var panelElem = document.getElementById(panel);
/// adjust labels and panels
for (i = 0; i < labels.length; i++) {
if (labels[i] != labels[0]) {
if (parseInt(labels[i].style.top) > parseInt(labelElem.style.top)) {
labels[i].style.top = parseInt(labels[i].style.top) + parseInt(panelElem.style.height);
panels[i].style.top = parseInt(labels[i].style.top) + parseInt(labels[i].style.height) - 2;
}
}
}
}
/// declare last panel in array
var lastPanel = panels[panels.length - 1];
/// move button
if (lastPanel.className == classCollapsed) {
goButton.style.top = parseInt(lastPanel.style.top) + 8;
} else {
goButton.style.top = parseInt(lastPanel.style.top) + parseInt(lastPanel.style.height) + 8;
}
}

and here’s the CSS that goes into the IncludeHTML component on the Form canvas:


<style>

/***Buttons***/
.gaButton1 {
text-transform: uppercase;
font-family: Verdana, Serif;
font-size: 14px;
letter-spacing: .5px;
border: none;
text-align: center;
color: white;
background-color: #569fbe;
outline: none !important;
padding-bottom: 2px;
cursor: pointer;
-webkit-appearance: none;
border-radius: 6px;
outline: none;
-moz-transition: top 200ms ease-in-out;
-o-transition: top 200ms ease-in-out;
-webkit-transition: top 200ms ease-in-out;
transition: top 200ms ease-in-out;
}
/******************************************/
/******************************************/
/***Labels***/
.gaSmallDetailsLabel {
color: #666666;
font-family: Verdana, Serif;
text-align: right;
font-size: 14px;
padding-right: 5px;
background-color: #f2f4fa;
}
.gaSmallDetailsData {
color: #999999;
font-family: Verdana, Serif;
text-align: left;
font-size: 14px;
font-weight: normal;
border-left: solid 2px #6dbdef;
padding-left: 5px;
z-index: 2;
}
.gaTitleLabel {
color: #808080;
font-family: Verdana, Serif;
text-align: left;
font-size: 18px;
font-weight: 500;
-webkit-font-smoothing: antialiased;
}
.gaMenuLabel {
color: #ffffff;
background: #b3b3b3;
padding-left: 12px;
padding-top: 3px;
font-size: 14px;
font-family: Verdana, Serif;
font-weight: 500;
border-left: solid 3px #5888d2;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-moz-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
-webkit-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
.gaMenuLabel:hover {
background: #999999;
}
/******************************************/

/******************************************/
/***Panels***/
.gaSmallDetailsPanel {
border: solid 1px #b3b3b3;
-moz-transition: all 200ms ease-in-out;
-webkit-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
.gaMenuPanelCollapsed {
height: 0px !important;
border: solid 1px #b3b3b3;
-moz-transition: all 200ms ease-in-out;
-webkit-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
/******************************************/

</style>

The form should be structured properly as well, with the panel labels and their child panels cascading top to bottom in reverse z-index order.  The z-index is adjusted with these buttons in the Form designer:

Symantec Workflow Z-Index Adjustment Buttons
Z-index adjustment buttons.
Symantec Workflow Collapsible Menus
The panel labels and panels cascade top to bottom in reverse z-index order, meaning that the labels themselves sit on top of one another in the y-position, but the Test Section 1 and its panel are a lower z-index than Test Section 2 and its panel, and so on. The lowest panel should be the only visible panel in the form designer.

The only onclick javascript needed for each panel label is this:


setPanels(this.id, 'Panel1');

where the “Panel1” is the Control Id of the label’s child panel.  This pipes the proper values into the backend script function.

In the original code I created for this feature, no functions or reusable code was implemented and every label contained everything it needed onclick to move everything else around.  This became exceptionally convoluted and tedious.  Adding another panel (I already had 7 in use) would have been a terrible ordeal.  Adding additional panels/sections to this new, extensible code takes about 3 minutes and works seamlessly.

To extend the code, attend the label onclick event itself, the control ids of the new panel and label, and adjust the javascript variables and arrays in the form script here:



/// declare variables
var panelOne = document.getElementById('Panel1');
var panelTwo = document.getElementById('Panel2');
var panelThree = document.getElementById('Panel3');
var labelOne = document.getElementById('Label1');
var labelTwo = document.getElementById('Label2');
var labelThree = document.getElementById('Label3'); 
/// declare array variables
var panels = [panelOne, panelTwo, panelThree];
var labels = [labelOne, labelTwo, labelThree];

After adding a 4th and 5th section, the code looks like this:


/// declare variables
var panelOne = document.getElementById('Panel1');
var panelTwo = document.getElementById('Panel2');
var panelThree = document.getElementById('Panel3');
var panelFour = document.getElementById('Panel4');
var panelFive = document.getElementById('Panel5');
var labelOne = document.getElementById('Label1');
var labelTwo = document.getElementById('Label2');
var labelThree = document.getElementById('Label3');
var labelFour = document.getElementById('Label4');
var labelFive = document.getElementById('Label5'); 
/// declare array variables
var panels = [panelOne, panelTwo, panelThree, panelFour, panelFive];
var labels = [labelOne, labelTwo, labelThree, labelFour, labelFive];

Send along any questions, or suggestions for my humble attempt at extensible javascript functions.

Here is a moving picture of the results of the test scripts above.

dynamicbuttondemo2


Featured Components

Form Builder

IncludeHTML


compatible_ie2020compatible_firefox2020compatible_chrome2020compatible_safari2020compatible_opera2020

6 thoughts on “Expanding/Collapsing Menus with CSS and Javascript in Workflow Forms

  1. Hi,

    Can you share more details about these collapsing menus and How exactly you made it work with Workflow. It seems very interesting and I think I can make a good use of it in my application.

    Regards
    Sandeep

    Like

      1. Hi,

        Can you post more details.
        Iwas able to make Panel 1 and 2 work, but Panel 3 is static and when i click nothing happens.
        All text is visible too.
        See

        Regards

        Dldraco

        Like

      2. Hello Draco – on first glance, it looks like your panels are set to “overflow”. Change that property on your workflow elements themselves (in the “Appearance” tab, “Overflow Behavior” field) to “Clip” instead.

        There’s a typo in your code, as well, where:
        <span id="Label3" class="cgaMenuLabel" name="Label3" onclick="setPanels(this.id, 'Panel3);"
        is missing a closing apostrophe after the "Panel3" value in the onclick function call. It should be:
        <span id="Label3" class="cgaMenuLabel" name="Label3" onclick="setPanels(this.id, 'Panel3');".

        Try those adjustments in Workflow and ignore the Codepen positioning. Let me know how it looks afterwards, and if you're still running into issues.

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s