Main GSP page where the call is made:
<%@ page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<g:applyLayout name="main" />
<title>Power Forms - Finished Form Info</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>
${processDefinition.name}
</h2>
<div class="margin-top-5 margin-bottom-5">
<span class="label label-default"> ${processDefinition.getCategory()}
</span>
</div>
<div class="col-sm-12">
<div class="supporting-text">
<span class="glyphicon glyphicon-info-sign"></span> Version
${processDefinition.version}
</div>
</div>
<div class="col-sm-12">
<div class="supporting-text">
<span class="glyphicon glyphicon-calendar"></span> Started
${processStartTime}
</div>
</div>
</div>
<div class="col-sm-6">
<div class="col-sm-12">
<div class="supporting-text">
<span class="glyphicon glyphicon-calendar"></span> Finished
${processEndTime}
</div>
<g:if test="${comments.size() <= 3}">
<g:set var="numOfCommentsToShow" value="${comments.size()}"></g:set>
<g:set var="showMoreLessLinks" value="false"></g:set>
</g:if>
<g:else>
<g:set var="numOfCommentsToShow" value="3"></g:set>
<g:set var="showMoreLessLinks" value="true"></g:set>
</g:else>
<g:render var="comments"
template="/landing/templates/regularComment"
collection="${comments.subList(0, "${numOfCommentsToShow}" as int)}" />
<div id="moreComments" style="display: none;">
<g:render var="comments"
template="/landing/templates/regularComment"
collection="${comments.subList("${numOfCommentsToShow}" as int, "${comments.size()}" as int)}" />
<div id="showLessBtn" class="margin-top-10 text-align-center">
<a id="showLessBtnLink" href="#"><span
class="fa fa-chevron-up"></span>Show (${numOfCommentsToShow})
Comments</a>
</div>
</div>
<g:if test="${showMoreLessLinks == 'true'}">
<div id="viewAllCommentBtn"
class="margin-top-10 text-align-center">
<a id="viewAllCommentBtnLink" href="#"><span
class="fa fa-chevron-down"></span>View All Comments</a>
</div>
</g:if>
<g:each in="${attachments}">
<g:link controller="history" action="attachment"
params='[id:"${it.attachmentId}"]'>
<div class="supporting-text">
<span class="glyphicon glyphicon-paperclip"></span>
${it.name}
</div>
</g:link>
</g:each>
</div>
</div>
Inside form Info ${completedTaskList}
<g:render template="/templates/completedTasksTemplate"
var="completedTask" collection="${completedTaskList}" />
</div>
</div>
<g:javascript>
$(document).ready(function(){
$("#viewAllCommentBtnLink").click(function(){
$("#viewAllCommentBtnLink").toggle();
$("#moreComments").toggle();
});
$("#showLessBtnLink").click(function(){
$("#moreComments").toggle();
$("#viewAllCommentBtnLink").toggle();
});
attachCommentExpandableListener();
userInfoModalListener();
});
function attachCommentExpandableListener() {
$(".comment-more").each(function() {
$(this).find(".more-link").on("click", function(e) {
e.preventDefault();
$(this).parent().hide();
$(this).parent().parent().find(".expandable-comment").slideDown('slow');
});
$(this).parent().find(".hide-link").on("click", function(e) {
e.preventDefault();
$(this).parent().slideUp('slow');
var commentMore = $(this).parent().parent().find(".comment-more");
setTimeout(function() { $(commentMore).show(); }, 800);
});
});
}
function userInfoModalListener(){
$(".userInfoModal").click(function(){
var modal = $("#infoModal").modal();
var avatar= $(this).find(".avatar").html();
var id = $(this).attr('networkId');
modal.find('.modal-body').html("");
modal.find(".modal-title").html("Loading . . .");
modal.find(".modal-loader").css("display", "");
getUserInfoForModal(id, avatar);
});
}
function getUserInfoForModal(networkId, avatar){
$.ajax({
url: "${g.createLink(controller: "landing", action: "getUserInfo")}",
data: {
query: networkId
},
success: function(data){
var modal = $("#infoModal").modal()
$(data).each(function(){
modal.find(".modal-title").html(avatar+" "+((this).firstName)+" "+((this).lastName));
modal.find(".modal-loader").css("display", "none");
var endHtml="";
var innerHtml =[];
if(this.title != null){
innerHtml.push("<label>Title</label>
<div>"+((this).title)+"</div>");
}
if(this.department != null){
innerHtml.push("<label>Department</label>
<div>"+((this).department)+"</div>");
}
if(this.deskPhone != null){
innerHtml.push("<label>Desk Phone</label>
<div>
<a href='tel:"+((this).deskPhone)+"'>"+((this).deskPhone)+"</a>
</div>");
}
if(this.cellPhone != null){
innerHtml.push("<label>Cell Phone</label>
<div>
<a href='tel:"+((this).cellPhone)+"'>"+((this).cellPhone)+"</a>
</div>");
}
if(this.emailAddress != null){
innerHtml.push("<label>Email Address</label>
<div>
<a href='mailto:"+((this).emailAddress)+"'>"+((this).emailAddress)+"</a>
</div>");
}
if (innerHtml.length>0){
endHtml ="<div class='row'>
"; for(x=0; x< innerHtml.length; x++){ endHtml+= "
<div class='col-xs-6'>"+innerHtml[x]+"</div>
" } endHtml+="
</div>"
modal.find(".modal-body").html(endHtml);
return false;
}
modal.find(".modal-title").html("Sorry for any inconvenience..");
modal.find(".modal-loader").css("display", "none");
modal.find(".modal-body").html("<div class='row'>
<div class='col-xs-12'>
No information for this user was found in LDAP.<br />For more
information please contact the IS Help Desk.<br /> <br />USA /
CAN: 717-534-5630 or 1-800-233-2170<br />MEX: 001-800-609-0354<br />INT'L
IID: +1-717-534-5630
</div>
</div>");
});
},
error: function(){
$("#infoModal").modal().find(".modal-title").html("Sorry for any inconvenience..");
$("#infoModal").modal().find(".modal-loader").css("display", "none");
$("#infoModal").modal().find(".modal-body").html("<div
class='row'>
<div class='col-xs-12'>
No information for this user was found in LDAP, please try again
later.<br />For more information please contact the IS Help Desk.<br />
<br />USA / CAN: 717-534-5630 or 1-800-233-2170<br />MEX:
001-800-609-0354<br />INT'L IID: +1-717-534-5630
</div>
</div>");
}
});
}
</g:javascript>
</body>
</html>
completedTasksTemplate.gsp
<div class="col-sm-6">
<h3>Completed Tasks</h3>
<g:if test="${completedTaskList.size() > 0}">
<g:each in="${completedTaskList}" var="completedTask">
<div class="action-row">
<div style="font-weight: bold;">
${completedTask.name}
</div>
<div class="supporting-text">
<span class="glyphicon glyphicon-inbox"></span> Task Assigned To:
${completedTask.assignee}
</div>
<div class="supporting-text">
<span class="glyphicon glyphicon-ok"></span> Task Completed By:
${completedTask.owner}
</div>
</div>
</g:each>
</g:if>
<g:else>
<div class="alert alert-info">No completed tasks found.</div>
</g:else>
</div>
In UI, called template is rendering more than once, based on number of items in the list. If there are two items in the "complatedTaskList" template will be rendered twice, likewise.
Because you're passing a collection into the g:render
<g:render template="/templates/completedTasksTemplate"
var="completedTask" collection="${completedTaskList}" />
According to the docs
For a List the template will be repeated for each instance
If you only want one item passed into the list then you can do that like so
<g:render template="/templates/completedTasksTemplate"
var="completedTask" collection="${completedTaskList[0]}" />