It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

A User Macro for Making Panels Collapsible

Using panels on a page is a great way to structure your page content to make it look less cluttered and more professional. One great feature of the code block macro that I wish was part of the panel macro is the ability to collapse the content section.

For instance, you may have a page in Confluence that serves as a dashboard of sorts with graphs, Jira macros, and other important metrics that are structured using panels. It would be nice to have a way to maybe collapse some of those panels to save some screen real-estate and prevent having to scroll. Oh well, I guess it can't be done. Tough luck!

Wait! Don't leave. I was just kidding! :) We can easily create a user macro for this to give us that ability. The code for this is below along with some screenshots of how it looks on the page and how to set it up when editing the page. If English is not your native language you can easily change the expand/collapse text by editing lines 18 and 19 to your liking. Enjoy!

How it looks on the page

panel.png

How to set it up on your page

paneledit.png

User Macro Code

Macro Name:
collapsible_panel

Macro Title:
Collapsible Panel

Description:
Any panel macros placed within this macro that have a Panel Title will be collapsible.

Macro Body Processing:
Rendered

Template:

## Developed by: Davin Studer
## Date created: 05/31/2018

## @param ID:title=Panel ID|type=string|required=false|desc=Optionally provide a unique id to surround the panel(s) (no spaces).
## @param Start:title=Start Collapsed|type=boolean|required=false|desc=

########################################################################
## Use the given ID if present otherwise generate one. The reason for ##
## this is so that we can target each user macro distinctly if this   ##
## is included more than once per page.                               ##
########################################################################
#if( $paramID && $paramID != "" )
    #set( $id = $paramID )
#else
    #set( $id = $action.dateFormatter.calendar.timeInMillis )
#end

#set( $expandText = "Expand panel" ) ## Change this to fit your desired verbiage/language
#set( $collapseText = "Collapse panel" )  ## Change this to fit your desired verbiage/language

<script type="text/javascript">
//<![CDATA[
AJS.toInit(function(){
    // These are the CSS styles for this macro. It used to use a style element, but that was causing Confluence
    // to not keep the header bar at the top when you scroll the page. For some reason just putting style elements
    // in a user macro will cause the top bar to not remain static at the top of the page.
    var style = '<style type="text/css">#collapser-$id .panel.collapser-closed .panelContent {display: none;}\n#collapser-$id .panel.collapser-open .panelContent {display: block;}\n.collapser {float: right; cursor: pointer; margin-right: 5px;}\n.collapser-text {vertical-align: top; color: #3b73af;}\n.collapser-text:hover {text-decoration: underline;}</style>';
    AJS.$('#main-content').prepend(style);
    
	/////////////////////////////////////////////////////
    // This block is a mix of Velocity and Javascript. //
    // The Velocty variable will add Javascript to     //
    // open or close the panel(s) within the macro     //
    // depending upon what the user set.               //
    /////////////////////////////////////////////////////
#if ( $paramStart == true )
    AJS.$('#collapser-$id .panel .panelHeader').append('<span class="collapser"><span class="collapser-button expand-control-icon icon">&nbsp;</span><span class="collapser-text">$expandText</span></span>');
    AJS.$('#collapser-$id .panel').has('.panelHeader').addClass('collapser-closed');
#else
    AJS.$('#collapser-$id .panel .panelHeader').append('<span class="collapser"><span class="collapser-button expand-control-icon icon expanded">&nbsp;</span><span class="collapser-text">$collapseText</span></span>');
    AJS.$('#collapser-$id .panel').has('.panelHeader').addClass('collapser-open');
#end

    AJS.$('#collapser-$id .panel .collapser').click(function() {
        var panel = AJS.$(this).parent().parent(); // Get the panel for this specific collapser
        var open = AJS.$(panel).hasClass('collapser-open'); // Is it currently open or closed?

        if(open) {
            toggleCollapser$id(panel, 'close');
        } else {
            toggleCollapser$id(panel, 'open');
        }
    });
});

function toggleCollapser$id(panel, action) {
    if(action === "close") {
        AJS.$(panel).removeClass('collapser-open').addClass('collapser-closed');
        AJS.$('.collapser-button', panel).removeClass('expanded');
        AJS.$('.collapser-text', panel).text('$expandText');
    } else {
        AJS.$(panel).removeClass('collapser-closed').addClass('collapser-open');
        AJS.$('.collapser-button', panel).addClass('expanded');
        AJS.$('.collapser-text', panel).text('$collapseText');
    }
}
//]]>
</script>

<div id="collapser-$id">$body</div>

 

10 comments

Bill Bailey Community Leader May 31, 2018

I really appreciate these kind of examples. Even if I don't have need for this function, it shows some advance concepts for writing user macros that one cannot find in the user docs. THX!

Alana Fernando Community Leader Jun 01, 2018

This is awesome @Davin Studer

Davin Studer Community Leader Jun 01, 2018

Thanks @Alana Fernando.

I could really use this tool for a dashboard I am creating using panels, but I can't find the "Collapsible Panel" macro on the marketplace! I'm new to Confluence, so maybe there's something I'm missing. Any assistance would be much appreciated @Davin Studer!

Davin Studer Community Leader Jun 19, 2018

This is the code for a user macro. User macros are available in the self host Confluence, but not Confluence Cloud. If you are on the self hosted server or data center version then a Confluence Admin can create the user macro by cutting and pasting in the above code.

Hi Davin, we tried this and it worked great. Thanks for sharing. However I noticed that some events doesn't get triggered anymore when I put this on our page. Particularly the problem I notice is this:when I have a long page and I scroll all the way down, things still look normal but when I move the page up I don't see the "menu-header" div getting displayed on top anymore.  html code wise it normally adds the "overlay-header" class when I do this. Any suggestions to check why is this so? or possible fixes to the script? we're running confluence version 6.13.3.

Davin Studer Community Leader Jul 23, 2019

It is odd. Turns out just having a <style> element in the user macro causes the header to not be sticky. I've edited the code above to dynamically insert the styles. <sigh>.

Like Paolo Aquino likes this

Thank you very much!

Like Davin Studer likes this

Thank you - I love it!

Like Davin Studer likes this

Comment

Log in or Sign up to comment
Community showcase
Published in Confluence

What's New in Confluence Cloud – November 2019 Edition

Hey community! This month we’re excited to share brand new features to help you make your mark on Confluence. If you haven’t already, check out our updates from October and September too! Expre...

11,332 views 11 30
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you