Page tree

This is the documentation for ConfiForms Server/Data Center app

However, this might also work for ConfiForms cloud and in most cases it does. But please see this page to understand the differences between server and cloud versions of the ConfiForms app.


In this tutorial you will learn how to configure ConfiForms to provide sequential approvals workflow.

This tutorial is not very simple, and you have to pay attention to details. To learn the basics about ConfiForms see Creating a simple form in Confluence with ConfiForms

We believe that approach shown in Form with sequential approvals workflow which uses IFTTT macro instead of Formula field is a lot easier to maintain and develop.

This solution has been prepared before the ConfiForms had the feature to update own records based on the conditions.

However, this tutorial is still good way to demonstrate how formula fields could work together and what you can achieve


We will have 3 user groups who should be able to approve a proposal in a sequential way, one by one and only when a proposal is in a certain state.

3 user groups (security groups in Confluence) are as follows:

  • devs - developers security group
  • pm - project managers group (gives approval after the DEVs)
  • fin - finance (gives approvals after the PMs)

The form is very simple and has 2 common fields to capture the proposal text in a plaintext format and to set a readonly field to show the proposal approval state as a text.

For each user group we will setup own field control of type "checkbox" to change current approval state to next state. Fields are restricted to be editable by certain user group only

So in total we will have 5 fields here:

  • form has additional user groups set as administrators
  • Ordinal textarea field (proposaltext)


  • Formula field to calculate the value for the visual representation of the current status with this expression/formula (statelabel)


IF("[entry.approvedByFin]", "Approved By Finance", IF("[entry.approvedByPM]", "Approved By PMs", IF(NOT("[entry.approvedByDevs]"), "Created", "Approved By Devs")))

  • Checkbox to track approvals by developers (see "devs" set as a user group this field is visible to)
  • Checkbox to track approvals by projects managers (see "pm" set as a user group this field is visible to)
  • Checkbox to track approvals by finance (see "fin" set as a user group this field is visible to)
  • We have also specified the rules to hide check box fields when record is created

    The rule means that when an entry (record) does not have an ID (id:) then hide checkbox fields (field names are listed as csv: approvedByDevs,approvedByPM,approvedByFin)

The whole storage format for the form is listed below:

<ac:structured-macro ac:macro-id="81b6f18d-2cd2-4604-b9f3-7a3ea40d77fd" ac:name="confiform"
                                  ac:schema-version="1">
<ac:parameter ac:name="additionalFormAdmins">devs,pm,fin</ac:parameter>
<ac:parameter ac:name="formName">proposals</ac:parameter>
<ac:parameter ac:name="saveButtonLabel">Register proposal</ac:parameter>
<ac:parameter ac:name="registrationFormTitle">Register</ac:parameter>
<ac:rich-text-body>
  <p>
    <ac:structured-macro ac:macro-id="2b3a3bb8-fe7b-4e81-825f-ccda6816e9f5" ac:name="confiform-field-definition"
                         ac:schema-version="1">
      <ac:parameter ac:name="fieldName">proposaltext</ac:parameter>
      <ac:parameter ac:name="fieldLabel">Proposal text</ac:parameter>
      <ac:parameter ac:name="type">textarea</ac:parameter>
    </ac:structured-macro>
  </p>
  <p>
    <ac:structured-macro ac:macro-id="a6894605-f8a2-4954-8eab-f5779e267abe" ac:name="confiform-field-definition"
                         ac:schema-version="1">
      <ac:parameter ac:name="fieldName">statelabel</ac:parameter>
      <ac:parameter ac:name="fieldLabel">State</ac:parameter>
      <ac:parameter ac:name="extras">IF(&quot;[entry.approvedByFin]&quot;, &quot;Approved By Finance&quot;, IF(&quot;[entry.approvedByPM]&quot;,
        &quot;Approved By PMs&quot;, IF(NOT(&quot;[entry.approvedByDevs]&quot;), &quot;Created&quot;, &quot;Approved By
        Devs&quot;)))
      </ac:parameter>
      <ac:parameter ac:name="type">formula</ac:parameter>
    </ac:structured-macro>
  </p>
  <p>
    <ac:structured-macro ac:macro-id="b557fad8-d633-4e1d-8fa9-993eea0c3f53" ac:name="confiform-field-definition"
                         ac:schema-version="1">
      <ac:parameter ac:name="editRestrictions">devs</ac:parameter>
      <ac:parameter ac:name="fieldName">approvedByDevs</ac:parameter>
      <ac:parameter ac:name="fieldLabel">Approved (Devs)</ac:parameter>
      <ac:parameter ac:name="editRestrictions">devs</ac:parameter>
      <ac:parameter ac:name="type">checkbox</ac:parameter>
    </ac:structured-macro>
  </p>
  <ac:structured-macro ac:macro-id="16541513-8b13-47b1-9bf1-53e85f6a8f00" ac:name="confiform-field-definition"
                       ac:schema-version="1">
    <ac:parameter ac:name="editRestrictions">pm</ac:parameter>
    <ac:parameter ac:name="fieldName">approvedByPM</ac:parameter>
    <ac:parameter ac:name="fieldLabel">Approved By (PMs)</ac:parameter>
    <ac:parameter ac:name="editRestrictions">pm</ac:parameter>
    <ac:parameter ac:name="type">checkbox</ac:parameter>
  </ac:structured-macro>
  <p>
    <ac:structured-macro ac:macro-id="fb050936-7372-47b2-b6ca-a78a88e36600" ac:name="confiform-field-definition"
                         ac:schema-version="1">
      <ac:parameter ac:name="editRestrictions">fin</ac:parameter>
      <ac:parameter ac:name="fieldName">approvedByFin</ac:parameter>
      <ac:parameter ac:name="fieldLabel">Approved By (Finance)</ac:parameter>
      <ac:parameter ac:name="editRestrictions">fin</ac:parameter>
      <ac:parameter ac:name="type">checkbox</ac:parameter>
    </ac:structured-macro>
    <ac:structured-macro ac:macro-id="e30b9daf-18a1-4d15-936a-cdeafb2c4715" ac:name="confiform-entry-register"
                         ac:schema-version="1">
      <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
      <ac:rich-text-body>
        <p>&nbsp;</p>
      </ac:rich-text-body>
    </ac:structured-macro>
    <ac:structured-macro ac:macro-id="58421c25-de39-45da-b5f2-4d3b349470c8" ac:name="confiform-field-definition-rules"
                         ac:schema-version="1">
      <ac:parameter ac:name="condition">id:</ac:parameter>
      <ac:parameter ac:name="fieldName">approvedByDevs,approvedByPM,approvedByFin</ac:parameter>
      <ac:parameter ac:name="action">Hide field</ac:parameter>
      <ac:parameter ac:name="actionFieldName">statelabel</ac:parameter>
    </ac:structured-macro>
  </p>
</ac:rich-text-body>
</ac:structured-macro>

This is about everything about form configuration, let's proceed with an actual approvals workflow.

We use ListView macro to show the data and have setup multiple edit buttons what are visible to certain user groups. Here is how it looks in the editor

So, we reference the form by name ("proposals") and put references to field definitions using ConfiForms Field macros. So far, so good. Simple and straightforward. The trick though is with configuration of ConfiForms Edit Controls. We want it to appear only for certain user groups and only when a record is in certain condition. Let's see it in details:

  • First edit button, we call it "ApproveDEV" has the following settings

    Visible to only "devs" user group and hidden if already approved

  • Second edit button, we call it "ApprovePM" has the following settings

    Visible to only "pm" group and hidden when the following condition is met: 

    approvedByFin:true OR approvedByPM:true OR approvedByDevs:false

    Explanation: Button will be hidden when it already approved by PMs, or not approved yet by DEVs, or already approved by FINANCE

  • Third edit button, we call it "ApproveFIN" has the following settings

    Visible to only users in "fin" user group and hidden when the following condition is met: 

    approvedByFin:true OR approvedByPM:false OR approvedByDevs:false

    Explanation: Button will be hidden when it already approved by FINANCE, or not approved yet by PMs or not yet approved by DEVs

    Full storage format for this list view is listed below

    <ac:structured-macro ac:macro-id="96b70748-706b-4115-aaf2-5b9ae013b151" ac:name="confiform-list"
                                               ac:schema-version="1">
    <ac:parameter ac:name="formName">proposals</ac:parameter>
    <ac:rich-text-body>
      <h3>Proposal:</h3>
      <p>
        <ac:structured-macro ac:macro-id="ab7fd363-7416-40c7-b9fa-58d253f49c81" ac:name="confiform-field"
                             ac:schema-version="1">
          <ac:parameter ac:name="fieldName">proposaltext</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <strong>
          <ac:structured-macro ac:macro-id="cf8c064e-18f4-48ea-922c-18b9b348f13d" ac:name="confiform-field"
                               ac:schema-version="1">
            <ac:parameter ac:name="fieldName">statelabel</ac:parameter>
          </ac:structured-macro>
        </strong>
        <ac:structured-macro ac:macro-id="f04196d7-d5fe-49ed-a347-7a7234fe1b96" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">devs</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByDevs:true</ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApproveDEV</ac:parameter>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="c69b2a2c-b742-448d-be62-118d36680eb3" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">pm</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByFin:true OR approvedByPM:true OR approvedByDevs:false
          </ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApprovePM</ac:parameter>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="4ae8ce8d-066b-40b4-a74a-a564f58dc03a" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">fin</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByFin:true OR approvedByPM:false OR approvedByDevs:false
          </ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApproveFIN</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>&nbsp;</p>
    </ac:rich-text-body>
    </ac:structured-macro>

    And this is how the form looks like in Confluence view mode:


    This is how it is seeing by FINANCE team




    Final note: the solution presented here is just one way of implementing such requirements. As ConfiForms is very flexible and powerful in terms of how you can do things and what you can do.

    More ideas on how it can be implemented:

    - instead of using "Formula" field to track visual representation of current approval state you can employ a "readonly" field which will be updated using by defining "Set Value" Field rules for each checkbox field. Meaning that you just define a ConfiForms Field Definition Rules macro for each checkbox field and use a "Set Value" action to set the value (caption) for "readonly field"

    - also, instead of using "readonly" field you can use any field type which you actually want, a status field might be a good choice. In our example above we have just showed that you can use "formula" fields to track the status "automatically".

    If you are curious then here is the storage format for another solution


    3 more rules for Field definitions (for each checkbox). The rule basically just sets/updates the value for readonly field (statelabel)


    <h1>Office proposals</h1>
    <p>&nbsp;</p><ac:structured-macro ac:macro-id="81b6f18d-2cd2-4604-b9f3-7a3ea40d77fd" ac:name="confiform"
                                      ac:schema-version="1">
    <ac:parameter ac:name="additionalFormAdmins">devs,pm,fin</ac:parameter>
    <ac:parameter ac:name="formName">proposals</ac:parameter>
    <ac:parameter ac:name="saveButtonLabel">Register proposal</ac:parameter>
    <ac:parameter ac:name="registrationFormTitle">Register</ac:parameter>
    <ac:rich-text-body>
      <p>
        <ac:structured-macro ac:macro-id="bff7604a-060d-4767-9827-ae7f353d0ba1" ac:name="confiform-field-definition"
                             ac:schema-version="1">
          <ac:parameter ac:name="fieldName">proposaltext</ac:parameter>
          <ac:parameter ac:name="fieldLabel">Proposal text</ac:parameter>
          <ac:parameter ac:name="type">textarea</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <ac:structured-macro ac:macro-id="ba577edf-0564-466e-bc96-3e6b007993df" ac:name="confiform-field-definition"
                             ac:schema-version="1">
          <ac:parameter ac:name="fieldName">statelabel</ac:parameter>
          <ac:parameter ac:name="fieldLabel">State</ac:parameter>
          <ac:parameter ac:name="values">Created</ac:parameter>
          <ac:parameter ac:name="extras">IF(&quot;[entry.approvedByFin]&quot;, &quot;Approved By Finance&quot;, IF(&quot;[entry.approvedByPM]&quot;,
            &quot;Approved By PMs&quot;, IF(NOT(&quot;[entry.approvedByDevs]&quot;), &quot;Created&quot;, &quot;Approved By
            Devs&quot;)))
          </ac:parameter>
          <ac:parameter ac:name="type">read_only</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <ac:structured-macro ac:macro-id="24f69607-5f98-4d6c-919b-dfc38800110a" ac:name="confiform-field-definition"
                             ac:schema-version="1">
          <ac:parameter ac:name="editRestrictions">devs</ac:parameter>
          <ac:parameter ac:name="fieldName">approvedByDevs</ac:parameter>
          <ac:parameter ac:name="fieldLabel">Approved (Devs)</ac:parameter>
          <ac:parameter ac:name="restrictions">devs</ac:parameter>
          <ac:parameter ac:name="type">checkbox</ac:parameter>
        </ac:structured-macro>
      </p>
      <ac:structured-macro ac:macro-id="f4c64953-1d5d-4451-a7f5-c26a1f7e4374" ac:name="confiform-field-definition"
                           ac:schema-version="1">
        <ac:parameter ac:name="editRestrictions">pm</ac:parameter>
        <ac:parameter ac:name="fieldName">approvedByPM</ac:parameter>
        <ac:parameter ac:name="fieldLabel">Approved By (PMs)</ac:parameter>
        <ac:parameter ac:name="restrictions">pm</ac:parameter>
        <ac:parameter ac:name="type">checkbox</ac:parameter>
      </ac:structured-macro>
      <p>
        <ac:structured-macro ac:macro-id="9ef48024-74de-4948-936b-c41e933653e5" ac:name="confiform-field-definition"
                             ac:schema-version="1">
          <ac:parameter ac:name="editRestrictions">fin</ac:parameter>
          <ac:parameter ac:name="fieldName">approvedByFin</ac:parameter>
          <ac:parameter ac:name="fieldLabel">Approved By (Finance)</ac:parameter>
          <ac:parameter ac:name="restrictions">fin</ac:parameter>
          <ac:parameter ac:name="type">checkbox</ac:parameter>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="8b010d6b-4154-454c-9ba4-cf034159d1dc" ac:name="confiform-entry-register"
                             ac:schema-version="1">
          <ac:parameter ac:name="atlassian-macro-output-type">INLINE</ac:parameter>
          <ac:rich-text-body>
            <p>&nbsp;</p>
          </ac:rich-text-body>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="dc812989-906a-443a-a79e-4048c901e5aa" ac:name="confiform-field-definition-rules"
                             ac:schema-version="1">
          <ac:parameter ac:name="condition">id:</ac:parameter>
          <ac:parameter ac:name="fieldName">approvedByDevs,approvedByPM,approvedByFin</ac:parameter>
          <ac:parameter ac:name="action">Hide field</ac:parameter>
          <ac:parameter ac:name="actionFieldName">statelabel</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <ac:structured-macro ac:macro-id="db643f2f-a932-4326-a451-6881aa826d5d" ac:name="confiform-field-definition-rules"
                             ac:schema-version="1">
          <ac:parameter ac:name="condition">approvedByDevs:true</ac:parameter>
          <ac:parameter ac:name="values">statelabel=Approved By Devs</ac:parameter>
          <ac:parameter ac:name="action">Set value</ac:parameter>
          <ac:parameter ac:name="actionFieldName">approvedByDevs</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <ac:structured-macro ac:macro-id="cb5b6bd1-2f26-4cee-b4ef-cf90a2c79468" ac:name="confiform-field-definition-rules"
                             ac:schema-version="1">
          <ac:parameter ac:name="condition">approvedByPM:true</ac:parameter>
          <ac:parameter ac:name="values">statelabel=Approved By PM</ac:parameter>
          <ac:parameter ac:name="action">Set value</ac:parameter>
          <ac:parameter ac:name="actionFieldName">approvedByDevs</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <ac:structured-macro ac:macro-id="d0bb80ef-6740-474b-b0a2-32201ba4d355" ac:name="confiform-field-definition-rules"
                             ac:schema-version="1">
          <ac:parameter ac:name="condition">approvedByFin:true</ac:parameter>
          <ac:parameter ac:name="values">statelabel=Approved By FIN</ac:parameter>
          <ac:parameter ac:name="action">Set value</ac:parameter>
          <ac:parameter ac:name="actionFieldName">approvedByDevs</ac:parameter>
        </ac:structured-macro>
      </p>
    </ac:rich-text-body>
    </ac:structured-macro><ac:structured-macro ac:macro-id="96b70748-706b-4115-aaf2-5b9ae013b151" ac:name="confiform-list"
                                               ac:schema-version="1">
    <ac:parameter ac:name="formName">proposals</ac:parameter>
    <ac:rich-text-body>
      <h3>Proposal:</h3>
      <p>
        <ac:structured-macro ac:macro-id="adaa1e2d-a0ad-4288-b002-58d72f04c1f0" ac:name="confiform-field"
                             ac:schema-version="1">
          <ac:parameter ac:name="fieldName">proposaltext</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>
        <strong>
          <ac:structured-macro ac:macro-id="99a0aead-71b2-411d-bc20-07c3ee5f4241" ac:name="confiform-field"
                               ac:schema-version="1">
            <ac:parameter ac:name="fieldName">statelabel</ac:parameter>
          </ac:structured-macro>
        </strong>
        <ac:structured-macro ac:macro-id="66d4b31c-c95c-45d4-be41-16f93ef6e020" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">devs</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByDevs:true</ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApproveDEV</ac:parameter>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="ebea2fa1-9182-4af7-afb7-e0f21e8ee631" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">pm</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByFin:true OR approvedByPM:true OR approvedByDevs:false
          </ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApprovePM</ac:parameter>
        </ac:structured-macro>
        <ac:structured-macro ac:macro-id="c2f7f948-402b-4beb-8bdd-83aa31b04cda" ac:name="confiform-entry-edit"
                             ac:schema-version="1">
          <ac:parameter ac:name="restrictions">fin</ac:parameter>
          <ac:parameter ac:name="showBoth">false</ac:parameter>
          <ac:parameter ac:name="hideIfMatches">approvedByFin:true OR approvedByPM:false OR approvedByDevs:false
          </ac:parameter>
          <ac:parameter ac:name="updateMessage">Approved</ac:parameter>
          <ac:parameter ac:name="editButtonLabel">ApproveFIN</ac:parameter>
        </ac:structured-macro>
      </p>
      <p>&nbsp;</p>
    </ac:rich-text-body>
    </ac:structured-macro>










  • No labels