In this tutorial we will create a tabbed view with dynamic content. Dynamic content will be served by ConfiFOrms and for tabbed view we will develop a custom User macro and will use the AUI interface elements, https://docs.atlassian.com/aui/latest/docs/tabs.html

The end result will look like this:

And here is how it is done.
The solution is a combination of User macro and ConfiForms ListView

 

Here is the full source code for user macro

## @param page:title=Page|type=confluence-content|required=true|desc=Select a page with ConfiForms products form
<div class="aui-tabs horizontal-tabs" role="application">
  <ul class="tabs-menu" role="tablist">
    <li class="menu-item active-tab" role="presentation">
      <a href="#tabs-mac" id="aui-uid-mac" role="tab" aria-selected="true"><strong>Mac</strong></a>
    </li>
    <li class="menu-item" role="presentation">
      <a href="#tabs-ipad" id="aui-uid-ipad" role="tab" aria-selected="false"><strong>iPad</strong></a>
    </li>
    <li class="menu-item" role="presentation">
      <a href="#tabs-iphone" id="aui-uid-iphone" role="tab" aria-selected="false"><strong>iPhone</strong></a>
    </li>
    <li class="menu-item" role="presentation">
      <a href="#tabs-watch" id="aui-uid-watch" role="tab" aria-selected="false"><strong>Watch</strong></a>
    </li>
  </ul>
  <div class="tabs-pane active-pane" id="tabs-mac" role="tabpanel" aria-hidden="false">
    <br/>
    <h1>Mac</h1>
    <table style="min-width: 100.0%;border: 0 !important;" class="confluenceTable tablesorter">
      <tbody>
      <tr>
        <td class="confluenceTd">
          <ac:structured-macro ac:name="confiform-list"
                               ac:schema-version="1">
            <ac:parameter ac:name="pageTitle">
              <ac:link>
                <ri:page ri:content-title="${paramPage}"/>
              </ac:link>
            </ac:parameter>
            <ac:parameter ac:name="formName">myProducts</ac:parameter>
            <ac:parameter ac:name="filter">type:mac</ac:parameter>
            <ac:rich-text-body>
              <table style="min-width: 100.0%;border: 0 !important;">
                <tr>
                  <td colspan="2" style="border: 0">
                    <h2>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">title</ac:parameter>
                      </ac:structured-macro>
                    </h2>
                  </td>
                </tr>
                <tr>
                  <td style="width:200px; min-width: 200px !important;max-width: 200px!important;border: 0">
                    <ac:structured-macro ac:name="confiform-field"
                                         ac:schema-version="1">
                      <ac:parameter ac:name="fieldName">logo</ac:parameter>
                      <ac:parameter ac:name="css">width:200px;height:150px</ac:parameter>
                    </ac:structured-macro>
                  </td>
                  <td style="border: 0">
                    <p>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">description</ac:parameter>
                      </ac:structured-macro>
                    </p>
                  </td>
                </tr>
              </table>
            </ac:rich-text-body>
          </ac:structured-macro>
        </td>
      </tr>
    </table>
  </div>
  <div class="tabs-pane" id="tabs-ipad" role="tabpanel" aria-hidden="true">
    <br/>
    <h1>iPad</h1>
    <table style="min-width: 100.0%;border: 0 !important;" class="confluenceTable tablesorter">
      <tr>
        <td class="confluenceTd">
          <ac:structured-macro ac:name="confiform-list"
                               ac:schema-version="1">
            <ac:parameter ac:name="pageTitle">
              <ac:link>
                <ri:page ri:content-title="${paramPage}"/>
              </ac:link>
            </ac:parameter>
            <ac:parameter ac:name="formName">myProducts</ac:parameter>
            <ac:parameter ac:name="filter">type:ipad</ac:parameter>
            <ac:rich-text-body>
              <table style="min-width: 100.0%;border: 0 !important;">
                <tr>
                  <td colspan="2" style="border: 0">
                    <h2>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">title</ac:parameter>
                      </ac:structured-macro>
                    </h2>
                  </td>
                </tr>
                <tr>
                  <td style="width:200px; min-width: 200px !important;max-width: 200px !important;border: 0">
                    <ac:structured-macro ac:name="confiform-field"
                                         ac:schema-version="1">
                      <ac:parameter ac:name="fieldName">logo</ac:parameter>
                      <ac:parameter ac:name="css">width:200px;height:150px</ac:parameter>
                    </ac:structured-macro>
                  </td>
                  <td style="border: 0">
                    <p>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">description</ac:parameter>
                      </ac:structured-macro>
                    </p>
                  </td>
                </tr>
              </table>
            </ac:rich-text-body>
          </ac:structured-macro>
        </td>
      </tr>
    </table>
  </div>
  <div class="tabs-pane" id="tabs-iphone" role="tabpanel" aria-hidden="true">
    <br/>
    <h1>iPhone</h1>
    <table style="min-width: 100.0%;border: 0 !important;" class="confluenceTable tablesorter">
      <tr>
        <td class="confluenceTd">
          <ac:structured-macro ac:name="confiform-list"
                               ac:schema-version="1">
            <ac:parameter ac:name="pageTitle">
              <ac:link>
                <ri:page ri:content-title="${paramPage}"/>
              </ac:link>
            </ac:parameter>
            <ac:parameter ac:name="formName">myProducts</ac:parameter>
            <ac:parameter ac:name="filter">type:iphone</ac:parameter>
            <ac:rich-text-body>
              <table style="min-width: 100.0%;border: 0 !important;">
                <tr>
                  <td colspan="2" style="border: 0">
                    <h2>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">title</ac:parameter>
                      </ac:structured-macro>
                    </h2>
                  </td>
                </tr>
                <tr>
                  <td style="width:200px; min-width: 200px !important;max-width: 200px !important;border: 0">
                    <ac:structured-macro ac:name="confiform-field"
                                         ac:schema-version="1">
                      <ac:parameter ac:name="fieldName">logo</ac:parameter>
                      <ac:parameter ac:name="css">width:200px;height:150px</ac:parameter>
                    </ac:structured-macro>
                  </td>
                  <td style="border: 0">
                    <p>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">description</ac:parameter>
                      </ac:structured-macro>
                    </p>
                  </td>
                </tr>
              </table>
            </ac:rich-text-body>
          </ac:structured-macro>
        </td>
      </tr>
    </table>
  </div>
  <div class="tabs-pane" id="tabs-watch" role="tabpanel" aria-hidden="true">
      <br/>
      <h1>Watch</h1>
      <table style="min-width: 100.0%;border: 0 !important;" class="confluenceTable tablesorter">
        <tr>
          <td class="confluenceTd">
            <ac:structured-macro ac:name="confiform-list"
                                 ac:schema-version="1">
              <ac:parameter ac:name="pageTitle">
                <ac:link>
                  <ri:page ri:content-title="${paramPage}"/>
                </ac:link>
              </ac:parameter>
              <ac:parameter ac:name="formName">myProducts</ac:parameter>
              <ac:parameter ac:name="filter">type:watch</ac:parameter>
              <ac:rich-text-body>
                <table style="min-width: 100.0%;border: 0 !important;">
                  <tr>
                    <td colspan="2" style="border: 0">
                      <h2>
                        <ac:structured-macro ac:name="confiform-field"
                                             ac:schema-version="1">
                          <ac:parameter ac:name="fieldName">title</ac:parameter>
                        </ac:structured-macro>
                      </h2>
                    </td>
                  </tr>
                  <tr>
                    <td style="width:200px; min-width: 200px !important;max-width: 200px !important;border: 0">
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">logo</ac:parameter>
                        <ac:parameter ac:name="css">width:200px;height:150px</ac:parameter>
                      </ac:structured-macro>
                    </td>
                    <td style="border: 0">
                      <p>
                        <ac:structured-macro ac:name="confiform-field"
                                             ac:schema-version="1">
                          <ac:parameter ac:name="fieldName">description</ac:parameter>
                        </ac:structured-macro>
                      </p>
                    </td>
                  </tr>
                </table>
              </ac:rich-text-body>
            </ac:structured-macro>
          </td>
        </tr>
      </table>
    </div>
</div>

And the storage format for the page where we use this user macro and where we also have a form configured (please note that the form could be configured in any other page, does not have to be on the same page where it is used)

<ac:structured-macro ac:macro-id="07106609-1469-4d58-9506-c69091b7cf66" ac:name="confiform" ac:schema-version="1">
  <ac:parameter ac:name="formName">myProducts</ac:parameter>
  <ac:parameter ac:name="registrationFormTitle">Register new product</ac:parameter>
  <ac:rich-text-body>
    <p>
      <ac:structured-macro ac:macro-id="39f22f01-80b1-4e4a-96b9-5c08be429d00" ac:name="confiform-field-definition" ac:schema-version="1">
        <ac:parameter ac:name="fieldName">logo</ac:parameter>
        <ac:parameter ac:name="fieldLabel">Logo</ac:parameter>
        <ac:parameter ac:name="fieldDescription">Image of 300px width max</ac:parameter>
        <ac:parameter ac:name="type">file</ac:parameter>
      </ac:structured-macro>
    </p>
    <p>
      <ac:structured-macro ac:macro-id="c9bfa47d-e7df-4252-94bc-55b053ff1355" ac:name="confiform-field-definition" ac:schema-version="1">
        <ac:parameter ac:name="fieldName">title</ac:parameter>
        <ac:parameter ac:name="fieldLabel">Title</ac:parameter>
        <ac:parameter ac:name="type">page</ac:parameter>
      </ac:structured-macro>
    </p>
    <p>
      <ac:structured-macro ac:macro-id="0db79b00-ab74-4978-8318-324ca9097ccc" ac:name="confiform-field-definition" ac:schema-version="1">
        <ac:parameter ac:name="fieldName">type</ac:parameter>
        <ac:parameter ac:name="fieldLabel">Type</ac:parameter>
        <ac:parameter ac:name="values">false[mac=Mac|ipad=iPad|iphone=iPhone|watch=Watch|]</ac:parameter>
        <ac:parameter ac:name="type">select</ac:parameter>
      </ac:structured-macro>
    </p>
    <p>
      <ac:structured-macro ac:macro-id="688ee4cb-5367-4a71-8651-2b6753562e45" ac:name="confiform-field-definition" ac:schema-version="1">
        <ac:parameter ac:name="fieldName">description</ac:parameter>
        <ac:parameter ac:name="fieldLabel">Description</ac:parameter>
        <ac:parameter ac:name="type">textarea</ac:parameter>
      </ac:structured-macro>
    </p>
    <p> <ac:structured-macro ac:macro-id="2bf091f1-989b-47ef-8033-61d699c548db" ac:name="confiform-entry-register" ac:schema-version="1">
        <ac:parameter ac:name="registrationButtonLabel">Register New Product</ac:parameter>
        <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
        <ac:rich-text-body>
          <p> </p>
        </ac:rich-text-body>
      </ac:structured-macro>
    </p>
  </ac:rich-text-body>
</ac:structured-macro>
<p>
  <ac:structured-macro ac:macro-id="e5ca7d43-2cce-40b4-abeb-e2a4678ed0b8" ac:name="our-products-showcase" ac:schema-version="1">
    <ac:parameter ac:name="page">
      <ac:link/>
    </ac:parameter>
    <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
    <ac:rich-text-body>
      <p> </p>
    </ac:rich-text-body>
  </ac:structured-macro>
</p>

Let's start with the form configuration, it is a simple form with just 4 fields

Looks like this:

Pretty simple form, nothing unusual. Here is how it looks in editor:

Now let's proceed with custom user macro, learn more about Confluence user macros here: https://confluence.atlassian.com/doc/user-macro-template-syntax-223906130.html

 

And as macro body content we put the one attached earlier to this tutorial.

Please note that macro body processing must be set to Rendered

 

Some important bits about user macro body:

 

## @param page:title=Page|type=confluence-content|required=true|desc=Select a page with ConfiForms products form

And then using the AUI layout for tabs, https://docs.atlassian.com/aui/latest/docs/tabs.html, put the necessary tags and styles

The important bit is how and what we put into tab body. Let's see it in more details:

<h1>Mac</h1>
    <table style="min-width: 100.0%;border: 0 !important;" class="confluenceTable tablesorter">
      <tbody>
      <tr>
        <td class="confluenceTd">
          <ac:structured-macro ac:name="confiform-list"
                               ac:schema-version="1">
            <ac:parameter ac:name="pageTitle">
              <ac:link>
                <ri:page ri:content-title="${paramPage}"/>
              </ac:link>
            </ac:parameter>
            <ac:parameter ac:name="formName">myProducts</ac:parameter>
            <ac:parameter ac:name="filter">type:mac</ac:parameter>
            <ac:rich-text-body>
              <table style="min-width: 100.0%;border: 0 !important;">
                <tr>
                  <td colspan="2" style="border: 0">
                    <h2>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">title</ac:parameter>
                      </ac:structured-macro>
                    </h2>
                  </td>
                </tr>
                <tr>
                  <td style="width:200px; min-width: 200px !important;max-width: 200px!important;border: 0">
                    <ac:structured-macro ac:name="confiform-field"
                                         ac:schema-version="1">
                      <ac:parameter ac:name="fieldName">logo</ac:parameter>
                      <ac:parameter ac:name="css">width:200px;height:150px</ac:parameter>
                    </ac:structured-macro>
                  </td>
                  <td style="border: 0">
                    <p>
                      <ac:structured-macro ac:name="confiform-field"
                                           ac:schema-version="1">
                        <ac:parameter ac:name="fieldName">description</ac:parameter>
                      </ac:structured-macro>
                    </p>
                  </td>
                </tr>
              </table>
            </ac:rich-text-body>
          </ac:structured-macro>
        </td>
      </tr>
    </table>
  </div>

Take a look at row 6, we add a storage format for ConfiForms ListView, referencing our form and page (given as parameter)

Inside we have an HTML table which has 2 rows, one row with just one column spanning 2 columns to show the title and the next row has 2 columns, one for logo, showing the picture, and another for description

On row 20 we have a ConfiForms field macro which references a form field named "logo" and this will render as image.

On rows 29 and 37 you will find another declaration of ConfiForms Fields referencing "title" field and referencing "description" field.

As title field is of type "Page" it will be rendered as a link to Confluence Page.

Description field is a usual Textarea field, and is rendered as simple text (but respecting line brakes)

 

Here is how you can use User Macros and ConfiForms together to build very custom solutions

If you have questions, as usual, ping us at vertuna(at)vertuna.com