Working with CUTE – JIRA Quicksearch

A deeper dive into the development process with the CUTE for JIRA add-on.

In my previous blogpost, I presented our solution to a JIRA Quicksearch. We used the CUTE Addon to get this running. Now, this blogpost dives a little deeper into the development process with CUTE. As an example, I will use the JIRA Quicksearch feature.

demojira

Preparation

Install the CUTE addon in your JIRA system. The addon is available in the Atlassian Marketplace. With this, a CUTE administration interface is available in JIRA. You can create a new extension using the “Create Extension” button. You are now ready for using CUTE.

cuteoverview

Step 1 – Create HTML

For our Quicksearch, we need a box which is used to hold our search results. So, we create a new velocity resource using the “Add a resource” button and select “Template (Velocity)”. We now enter our HTML code. Our result box also gets a unique name (“rich search-dropdown”) to address it later.

<!-- Dropdown -->
<div id="richsearch-dropdown" class="aui-style-default aui-dropdown2">
 <ul>
 </ul>
</div>

This HTML will now be rendered hidden on each JIRA page. We need step 2 to use it.

template

Step 2 – Move and interact

In step 2, we now move our HTML to a visible area in the page by using Javascript. In our case, the container should be displayed directly below the global search box. So, we create a new resource of type “Javascript” and use the following code to perform the move.

// Execute after the page was fully loaded
jQuery(function(jQuery){
 
    jQuery("#quickSearchInput").after(jQuery("#richsearch-dropdown"));
});

We use the Javascript Framework JQuery which is available by default in JIRA. This basic Javascript will now be extended to cover the requirements of searching after a user types in some characters. So, here is the code … it contains comments to give a better understanding what happens:

// Execute after the page was fully loaded
jQuery(function(jQuery){
 
     //register the quicksearch execution to the global search field
     jQuery("#quickSearchInput").keyup(getFilterInvoker()).attr("autocomplete", "off").after(jQuery("#richsearch-dropdown"));
     jQuery("#quickSearchInput").focus(doRichSearch); 
 
    //if the user clicks outside the quicksearchresult the result box should disappear
    jQuery(document).mouseup(function (e) {
        var container = jQuery("#quicksearch");
 
        if (!container.is(e.target) 
        && container.has(e.target).length === 0) {
            jQuery("#richsearch-dropdown").hide();
       }
    });
 
    //this is a timer for the delayed search execution
    function getFilterInvoker() {
        var filterTimer = 0;
        return function(event){
            clearTimeout(filterTimer);
            filterTimer = setTimeout(function() {
               doRichSearch(event)
           }, 300);
      }
   }
 
   //the search itself
   function doRichSearch() {
       var inputVal = jQuery("#quickSearchInput").val();
 
      //if at least 3 characters inserted
      if(inputVal.length > 2) {
 
          jQuery("#richsearch-dropdown").show();
 
             //build the query
             query = 'summary ~ "'+inputVal+'*"';
 
            //if someone iserts an issuekey we have to search in the key instead of the summary
            var res = inputVal.match(/^.*-\d+$/);
            if(res) {
                query = 'key = "'+inputVal+'"';
            }
 
           //we only want 10 results
           var maxResult = 10;
           jQuery("#richsearch-dropdown li").remove();
 
          //if the search is runnig we need to show a little spinner gizmo to show the process
          var spinnerListEntry = jQuery('<li><a href="#"><div class="button-spinner"></div></a></li>');
          spinnerListEntry.find("a").click(function(){
              jQuery(this).closest("form").submit(); 
          });
          jQuery("#richsearch-dropdown ul").append(spinnerListEntry);
          jQuery(spinnerListEntry).find('.button-spinner').spin();
 
         //here is the actual search. We use the same request confluence is using in the jiraissues macro
         jQuery.get(contextPath+"/sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml",{tempMax: maxResult, jqlQuery: query, returnMax: true, field: ["summary", "type", "link"]} ,function(xml) {
              jQuery("#richsearch-dropdown li").remove();
 
             //if no result was found we simply show it 
             if(jQuery(xml).find("item").length == 0) {
                 var elementToAddHtml = jQuery("<li><a href='#'>No results found for \""+inputVal+"\"</a></li>");
                 elementToAddHtml.find("a").click(function(){
                     jQuery(this).closest("form").submit(); 
                 });
                 jQuery("#richsearch-dropdown ul").append(jQuery(elementToAddHtml));
            }
 
           //rendering the results to list items and append them to the quicksearchbox
           jQuery(xml).find("item").each(function(){
                      var elementToAddHtml = "<li><a href='"+jQuery(this).find("link").text()+"'><img src='"+jQuery(this).find("type").attr("iconUrl")+"'> <span>"+jQuery(this).find("key").text()+" "+jQuery(this).find("summary").text()+"</span></a></li>";
                      jQuery("#richsearch-dropdown ul").append(jQuery(elementToAddHtml));
                  });
 
              });
         } else {
              jQuery("#richsearch-dropdown").hide();
         }
 
 
    }
});

Step 3 – Styling

Finally, we can style the container and its content. Create a new resource  of type “StyleSheet” for that. Here is the style code for our result box:

#richsearch-dropdown {
    z-index: 101; 
    width: 300px;
}
 
#richsearch-dropdown img {
    vertical-align: middle;
}
 
#richsearch-dropdown a {
    line-height: 25px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
 
#richsearch-dropdown .button-spinner {
    height: 25px; 
}


Conclusion

The CUTE extension is now complete and ready to use. You can find the complete Extension in the Communardo Support Portal. Now, it is your turn. Create your own little CUTE extensions by doing the 3 steps “create”, “move” and “style”. If you want, you can start right now!

>> Find out more about Atlassian licences here!

Related Posts

Leave a reply