Skip to main content
Skip table of contents

Advanced: Making a "more details" Dialog execute its own Query

This builds on a previous example

Before you read this please make sure you have read and understand the example in this page: Adding a "Show more details" button to each row

In the Previous example we learned how to add a "more details" button that opens a dialog to each row of a table.

In the mentioned example we wanted a way to show information that came back in the result of the same Query, but would have been too much to show in a single table.

So we stored the extra information and displayed it at the click of a button.

But for cases where the first Query doesn't deliver all the information at once, we can also build a "more details" button that opens a dialog and executes another Query.

Since the JQL search doesn't return the attachments for each issue by default, we could use this to execute another Query that loads the attachments for a given issue.

Our final result will look like this:

Setting up the nested Query

First we want to define a second query that loads the attachments for a given issue key.

We can use the same Database as in our first Query, but will need a different Query URL: "/rest/api/2/issue/:issueKey"

We'll also need a different Converter and Template for this new Query.

Converter for nested Query

CODE
function convert(json) {
  var parsed = JSON.parse(json);
  var attachments = parsed.fields.attachment;
 
  var result = attachments.map(function(attachment) {
    return {
      name: attachment.filename,
      author: attachment.author.displayName, 
      created: moment(attachment.created).format('YYYY-MM-DD'),
      link: attachment.content
    };
  });
 
  return result;
}

Template for nested Query

CODE
<h3>This is the result of another (nested) Query:</h3>
 
<table class="aui confluenceTable pocketquery-table">
  <thead>
    <tr>
      <th class="confluenceTh">Attachment</th>
      <th class="confluenceTh">Author</th>
      <th class="confluenceTh">Created</th>
    </tr>
  </thead>
   
  <tbody>
    #foreach ($row in $result)
      <tr>
        <td class="confluenceTd">
          <a href="$row.get("link")">$row.get("name")<a/>
        </td>
        <td class="confluenceTd">
          $row.get("author")
        </td>
        <td class="confluenceTd">
          $row.get("created")
        </td>
      </tr>
    #end
  </tbody>
</table>
 
## This is just for debugging purposes.
## You can remove this, if you don't need it.
<div class="aui-message">
  <p class="title">These parameters were passed into the nested Query:</p>
  <ul>
    #foreach($parameter in $processedMacroParameters.keySet())
      <li>
        <strong>$parameter:</strong> $processedMacroParameters.get($parameter)
      </li>
    #end
  </ul>
</div>

If you have set this up correctly, the result should look like this:

Executing the nested Query in the Dialog

For the Query and Database we will be using the same setup as in the previous example.

For the Converter we will use a much simpler function that just gives us the fields that we want to show in the initial table:

CODE
function convert(json) {
  var parsed = JSON.parse(json);
 
  var result = parsed.issues.map(function(issue) {
    var fields = issue.fields;
 
    return {
      key: issue.key,
      summary: fields.summary,
      issuetype: fields.issuetype.name,
      status: fields.status.name
    };
  });
 
  return result;
}

Now, the interesting part is of course the Template.

In the template we need to define the $nestedQuery that we want to execute each time the Dialog is opened.

We then put a pocketquery-dynamic-load-container into the dialog, that we later want to render the nested Query into.

When a user clicks the "more details" button, we open the dialog and call PocketQuery.load().

To this function we pass the $nestedQuery, the container that the Query should be rendered into, and of course the issueKey for the selected issue.

CODE
## Enter the URL to your Jira here so PocketQuery can render links to issues
## Important: the URL needs to have a trailing slash!
#set($jiraBaseUrl = "http://www.YOUR-JIRA-DOMAIN.com/")
 
## Everytime the dialog is opened we want to execute another query.
## Specify the key of the query here.
#set($nestedQuery = "KEY-OF-YOUR-NESTED-QUERY")
 
<table id="pq-table-with-more-details-btn" class="aui confluenceTable pocketquery-table">
  <thead>
    <tr>
      ## Specify column headers manually
      <th class="confluenceTh">Issue</th>
      <th class="confluenceTh">Summary</th>
      <th class="confluenceTh">Type</th>
      <th class="confluenceTh">Status</th>
      <th class="confluenceTh">More Details</th>
    </tr>
  </thead>
   
  <tbody>
    #foreach ($row in $result)
      <tr data-issue-key="$row.get("key")">
        #foreach ($column in $row)
          <td class="confluenceTd">
            #if($velocityCount == 1)
              <a href="${jiraBaseUrl}browse/${column}">$!column</a>
            #else
              $!column
            #end
          </td>
        #end
       
        <td class="confluenceTd">
          <button class="aui-button more-details-btn">Show more details</button>
        </td>
      </tr>
    #end
  </tbody>
</table>
 
<!-- This is the HTML for the more details dialog. -->
 
<section id="pq-more-details-dialog" class="aui-dialog2 aui-dialog2-medium aui-layer" role="dialog" aria-hidden="true">
  <header class="aui-dialog2-header">
    <h2 class="aui-dialog2-header-main dialog-title"></h2>
  </header>
  <div class="aui-dialog2-content">
    ## Render the container for a second Query here, that we can later execute via JS!
    <div class="pocketquery-dynamic-load-container"></div>
  </div>
  <footer class="aui-dialog2-footer">
    <div class="aui-dialog2-footer-actions">
      <button class="aui-button aui-button-primary close-dialog-btn">Close</button>
    </div>
  </footer>
</section>
 
<!--
    This script binds the click-handlers that open and close the dialog.
    In the click handler for opening the dialog, it also renders the information for the given issue.
-->
 
<script>
  AJS.toInit(function(){
    $('#pq-table-with-more-details-btn').on('click', '.more-details-btn', function(e) {
        e.preventDefault();
        
        // Read information about current row
        var button = $(e.target);
        var row = button.closest('tr');
        var issueKey = row.attr('data-issue-key');
        var content = $('#pq-more-details-dialog .content');
        
        // Put information into the dialog
        $('#pq-more-details-dialog .dialog-title').text('More details for ' + issueKey);

        var dynamicLoadContainer = $('#pq-more-details-dialog .pocketquery-dynamic-load-container');
        
        PocketQuery.load({
        container: dynamicLoadContainer,
        data: {
            contentKey: $page.id,
            queryName: '$nestedQuery',
            queryParameters: {
				issueKey: issueKey
			}
        }
        });
        
        AJS.dialog2('#pq-more-details-dialog').show();
    });

    $('#pq-more-details-dialog').on('click', '.close-dialog-btn', function (e) {
        e.preventDefault();
        AJS.dialog2('#pq-more-details-dialog').hide();
    });
  });
</script>
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.