Hi, the problem is that... If I'm doing render action like switching on issue tabs panels/processing workflow, some HTML elements of velocity will be duplicated:

Here is my web-resource, issue-tabpanel in atlassian-plugin.xml:
<web-resource key="my_plugin-resources" name="my_plugin Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<dependency>jira.webresources:jira-global</dependency>
<dependency>com.atlassian.auiplugin:aui-experimental-iconfont</dependency>
<dependency>com.atlassian.auiplugin:aui-table-sortable</dependency>
<dependency>com.atlassian.auiplugin:aui-inline-dialog2</dependency>
<dependency>com.atlassian.auiplugin:aui-select2</dependency>
<dependency>com.atlassian.auiplugin:aui-toggle</dependency>
<dependency>com.atlassian.auiplugin:aui-flag</dependency>
<dependency>com.atlassian.auiplugin:aui-help</dependency>
<dependency>com.atlassian.auiplugin:dialog2</dependency>
<dependency>com.atlassian.auiplugin:aui-dropdown2</dependency>
<dependency>com.atlassian.auiplugin:java.lang.String</dependency>
<resource type="download" name="my_plugin.css" location="css/my_plugin.css"/>
<resource type="download" name="my_plugin.js" location="js/my_plugin.js">
<property key="content-type" value="text/javascript"/>
</resource>
<resource type="download" name="images/" location="/images"/>
<context>atl.general</context>
<context>my_plugin</context>
</web-resource>
<issue-tabpanel key="jira-issue-tab-panel" name="jira Issue Tab Panel" i18n-name-key="jira-issue-tab-panel.name" class="com.my.plugin.jira.tabpanels.JiraIssueTabPanel">
<description key="jira-issue-tab-panel.description">The jira Issue Tab Panel Plugin</description>
<label key="jira-issue-tab-panel.label"/>
<resource type="velocity" name="view" location="templates/tabpanels/jira-issue-tab-panel.vm"/>
<order>200</order>
<sortable>true</sortable>
<supports-ajax-load>true</supports-ajax-load>
</issue-tabpanel>
velocity file jira-issue-tab-panel.vm:
<script type="text/javascript">
#include("js/my_plugin.js");
</script>
<div id="issue_guide_body">
<textarea id="async" style="display:none">$async</textarea>
<textarea id="issueId" style="display:none">$issue.getId()</textarea>
<div class="aui-group">
<div class="aui-item" style="width:10%;">
<button id="create-guide-dialog-show-button" class="aui-button aui-button-primary">TEST</button>
</div>
</div>
<section role="dialog" id="create-guide-dialog" class="aui-layer aui-dialog2 aui-dialog2-xlarge" aria-hidden="true">
<header class="aui-dialog2-header">
<h2 class="aui-dialog2-header-main"></h2>
<a class="aui-dialog2-header-close">
<span class="aui-icon aui-icon-small aui-iconfont-close-dialog">Close</span>
</a>
</header>
<div class="aui-dialog2-content">
<form id="create-guide" class="aui">
<div class="aui-group">
<div class="aui-item" style="width:50%;">
<select style="width:100%; max-width:100%;" id="select1" name="select1" placeholder="">
#foreach( $row in $select1 )
<option value="$row.getName()">$row.getName()</option>
#end
</select>
</div>
<div class="aui-item" style="width:50%;">
<select style="width:100%; max-width:100%;" id="select2" name="select2" placeholder="" multiple="">
#foreach( $row in $select2 )
<option value="$row.getName()">$row.getName()</option>
#end
</select>
</div>
</div>
</form>
</div>
<footer class="aui-dialog2-footer">
<div class="aui-dialog2-footer-actions">
<button id="create-guide-dialog-submit-button" class="aui-button aui-button-primary">OK</button>
<button id="create-guide-dialog-close-button" class="aui-button">close</button>
</div>
<div class="aui-dialog2-footer-hint"></div>
</footer>
</section>
</div>
javascript file my_plugin.js:
var counter = 0;
var initialised = false;
AJS.$(document).ready(function() {
var async = AJS.$("#async").val();
console.log("async:"+async);
if(async === "true"){
initialised = false;
}
console.log("initialised:"+initialised);
if(!initialised && AJS.$("#issueId").length !== 0){
initialised = true;
counter++;
console.log("counter:"+counter);
if(typeof AJS.$("#select1").data('select2') === typeof undefined)
AJS.$("#select1").auiSelect2();
if(typeof AJS.$("#select2").data('select2') === typeof undefined)
AJS.$("#select2").auiSelect2();
AJS.$("#create-guide-dialog-show-button").off('click');
AJS.$("#create-guide-dialog-show-button").on('click', function(e){
e.preventDefault();
AJS.dialog2("#create-guide-dialog").show();
});
}
});
java class com.my.plugin.jira.tabpanels.JiraIssueTabPanel:
package com.my.plugin.jira.tabpanels;
import com.atlassian.jira.plugin.issuetabpanel.*;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.my.plugin.dao.SelectADAO;
import com.my.plugin.dao.SelectBDAO;
import com.my.plugin.entity.*;
public class JiraIssueTabPanel extends AbstractIssueTabPanel2 implements IssueTabPanel2{
private static final Logger log = LoggerFactory.getLogger(JiraIssueTabPanel.class);
public JiraIssueTabPanel(){ }
@Override
public GetActionsReply getActions(GetActionsRequest request) {
final List<SelectA> select1 = SelectADAO.getSelectAByIDJira(request.issue().getId().toString());
final List<SelectB> select2 = SelectBDAO.getSelectBByIDJira(request.issue().getId().toString());
return GetActionsReply.create(new JiraIssueAction(request.isAsynchronous(), descriptor(), request.issue(), request.remoteUser(), select1, select2));
}
@Override
public ShowPanelReply showPanel(ShowPanelRequest request) {
boolean isShowing = true;
return ShowPanelReply.create(isShowing);
}
}
java action class com.my.plugin.jira.tabpanels.JiraIssueAction:
package com.my.plugin.jira.tabpanels;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.plugin.issuetabpanel.AbstractIssueAction;
import com.atlassian.jira.plugin.issuetabpanel.IssueTabPanelModuleDescriptor;
import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import com.atlassian.jira.template.VelocityTemplatingEngine;
import com.atlassian.jira.user.ApplicationUser;
import com.my.plugin.entity.*;
import static com.atlassian.jira.template.TemplateSources.file;
public class JiraIssueAction extends AbstractIssueAction {
private static final String PLUGIN_TEMPLATES = "templates/tabpanels/";
List<SelectA> select1 = new ArrayList<SelectA>();
List<SelectB> select2 = new ArrayList<SelectB>();
Issue issue;
ApplicationUser remoteUser;
Boolean async;
public JiraIssueAction(Boolean async, IssueTabPanelModuleDescriptor descriptor, Issue issue, ApplicationUser remoteUser, List<SelectA> select1, List<SelectB> select2){
super(descriptor);
this.async = async;
this.issue = issue;
this.remoteUser = remoteUser;
this.select1=select1;
this.select2=select2;
}
public Date getTimePerformed(){
return issue.getCreated();
}
protected void populateVelocityParams(Map params){
params.put("async",async);
params.put("issue",issue);
params.put("remoteUser",remoteUser);
params.put("select1",select1);
params.put("select2",select2);
}
public String getHtml() {
final String templateName = "jira-issue-tab-panel.vm";
final VelocityTemplatingEngine templatingEngine = ComponentAccessor.getComponent(VelocityTemplatingEngine.class);
final Map<String, Object> params = new HashMap(5);
populateVelocityParams(params);
return templatingEngine.render(file(PLUGIN_TEMPLATES + templateName)).applying(params).asHtml();
}
}
I had to use "initialised" variable to avoid some repeat case, but it still appeared problem...
JIRA version:
<jira.version>7.6.2</jira.version>
<amps.version>6.3.14</amps.version>
Need your advice and helps,
Sincerely