How to Post data in web panel in jira(Velocity)

Chenyu Jia December 6, 2017

I have used jira sdk to create a plugin include web panel.I can used simple Javascript code to get an value of input box in web panel and use "alert()" method to show the value in front page.But I can't find any way to post data to other where.I've tried AJAX and jQuery but nothing changed.Or is there any way to get input value in Velocity from Java class?

1 answer

0 votes
Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2017

Do you want to POST data from the web panel? instead of alert(), put something like this

AJS.$.ajaxSetup({
    baseUrl: "http://localhost:8090/jira" // The base url of your instance
});

AJS.$.ajax({
    url : '/rest/jiragroupmanagementrestresource/latest/group/FOO",
    type: 'POST',
    data : {}, // form data
    cache : false,
    success: function(response){
        alert('Success');
    }
});
Chenyu Jia December 7, 2017

Thank you for your reply.

I tried this code,put them into "

function myFunction() {}

"

Then I use jira quick reload but the web panel throw an error "Error rendering myjava class"

What's wrong?

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2017

It is difficult to say without seeing your code. What is myjava.class?

Chenyu Jia December 7, 2017

I just copy the code you reply to me in last question.

package com.example.plugins.tutorial;

import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.plugin.webfragment.contextproviders.AbstractJiraContextProvider;
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.user.ApplicationUser;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;

public class DueDateIndicator extends AbstractJiraContextProvider
{
private static final int MILLIS_IN_DAY = 24 * 60 * 60 * 1000;



@Override
public Map getContextMap(ApplicationUser applicationUser, JiraHelper jiraHelper) {
Map contextMap = new HashMap();
Issue currentIssue = (Issue) jiraHelper.getContextParams().get("issue");
Timestamp dueDate = currentIssue.getDueDate();
if (dueDate != null)
{
int currentTimeInDays = (int) (System.currentTimeMillis() / MILLIS_IN_DAY);
int dueDateTimeInDays = (int) (dueDate.getTime() / MILLIS_IN_DAY);
int daysAwayFromDueDateCalc = dueDateTimeInDays - currentTimeInDays + 1;
contextMap.put("daysAwayFromDueDate", daysAwayFromDueDateCalc);
}
return contextMap;
}
}

I think it's nothing wrong with this java class. 

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2017

And what is in your vm file? Where did you add the Ajax call?

Chenyu Jia December 7, 2017
<input id="dStart" name="dStart" type="text" class="text medium-field" />
<script language="javascript" type="text/javascript">
Calendar.setup({
firstDay : 1,
inputField : 'dStart',
button : 'dStart_trigger',
align : 'Br',
singleClick : true,
showsTime : false,
useISO8601WeekNumbers : false,
ifFormat :'%Y-%m-%d' //'%d/%m/%Y'
});
</script>
<button onclick="myFunction()">Post data</button>
<button onclick="newFunction()">Post</button>
<script language="javascript" type="text/javascript">
function myFunction() {
var x = document.getElementById('dStart').value;
AJS.$.ajaxSetup({
baseUrl: "http://localhost:8090/jira" // The base url of your instance
});
AJS.$.ajax({
url : '/rest/jiragroupmanagementrestresource/latest/group/FOO",
type: 'POST',
data : {}, // form data
cache : false,
success: function(response){
alert('Success');
}
});
alert(x)
}
</script>


Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2017

This script is in the due-date-indicator.vm file? You replaced the old content?

Chenyu Jia December 7, 2017

Yes..

Alexey Matveev
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
December 7, 2017

Write it like this

<input id="dStart" name="dStart" type="text" class="text medium-field" />
<script language="javascript" type="text/javascript">
Calendar.setup({
firstDay : 1,
inputField : 'dStart',
button : 'dStart_trigger',
align : 'Br',
singleClick : true,
showsTime : false,
useISO8601WeekNumbers : false,
ifFormat :'%Y-%m-%d' //'%d/%m/%Y'
});
</script>
<button onclick="myFunction()">Post data</button>
<button onclick="newFunction()">Post</button>
<script language="javascript" type="text/javascript">
function myFunction() {
var x = document.getElementById('dStart').value;
AJS.ajaxSetup({
baseUrl: "http://localhost:8090/jira" // The base url of your instance
});
AJS.ajax({
url : '/rest/jiragroupmanagementrestresource/latest/group/FOO',
type: 'POST',
data : {}, // form data
cache : false,
success: function(response){
alert('Success');
}
});
alert(x);
}
</script>
Rahul_MG May 29, 2020

 

@Alexey Matveev  I do have a similar issue.I have  created a pluggin using web-panel module. This pluggin fetches some data from DB and populates one field in the Issue page. My requirement is to input some values for the field created in the vm file and on button click the data needs to be saved to DB.

As i am new in creating pluggin, i require your support and help here.

In case if i missed anything please suggest and help.

The UI looks as below,

screen_create.PNG

My atlassian-plugin.xml looks like this

<web-panel name="DueDateIndicator" i18n-name-key="due-date-indicator.name" key="due-date-indicator" location="atl.jira.view.issue.left.context" weight="1000">
<description key="due-date-indicator.description">The DueDateIndicator Plugin</description>
<context-provider class="com.example.plugins.tutorial.DueDateIndicator"/>
<resource name="view" type="velocity" location="templates/due-date-indicator.vm"/>
<label key="due-date-indicator.title"/>
</web-panel>

My VM file (due-date-indicator.vm) looks as below. It does not have the <html> tag.When i put the <html > tag the other field in the issue page is gone.Only the fields in the vm file are viewable.

 

<style type="text/css">
.init-template-div {
margin-left: 5px;
border: 1px dashed #ccc;
border-radius: 0;
padding: 7px;
transition: background-color 0.01s linear 0.01s;
position: relative;
text-align: center;
}
.init-template-div > div {
padding: 4px 0;
}
</style>


<script language="javascript" type="text/javascript">
function myFunction() {
var x = document.getElementById('remarks').value;
AJS.ajaxSetup({
baseUrl: "http://localhost:8090/jira" // The base url of your instance
});
AJS.ajax({
url : '/saveConfigDetails',
type: 'POST',
data : {remarks :x}, // form data
cache : false,
success: function(response){
alert('Success');
}
});
alert(x);
}
</script>

<div id="issue-left" class="module toggle-wrap">
<div id="issue-left_heading" class="mod-header">
<ul class="ops"></ul><a href="#" class="aui-button toggle-title">
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><g fill="none" fill-rule="evenodd"><path d="M3.29175 4.793c-.389.392-.389 1.027 0 1.419l2.939 2.965c.218.215.5.322.779.322s.556-.107.769-.322l2.93-2.955c.388-.392.388-1.027 0-1.419-.389-.392-1.018-.392-1.406 0l-2.298 2.317-2.307-2.327c-.194-.195-.449-.293-.703-.293-.255 0-.51.098-.703.293z" fill="#344563"></path></g></svg></a>
<!--<h4 class="toggle-title">Configuration CheckLists</h4>-->
</div>
<div class="mod-content">
<div class="table-issue-panel ghx-container" data-nocache="1588788605635" id="elements-ISSUE">
<div data-reactroot="" style="background-color: white;">

<div id="95s1rtdyf" class="module">

<div class="panelHeaderTitleServer mod-header">
<b class="panel-title-label collapse-panel">
<span class="aui-iconfont-arrow2-down aui-icon aui-icon-small "></span>
</b>
<form class="aui top-label" style="margin-top: 15px;" action="/jira/saveConfigDetails" method="get">
<fieldset class="top-label">

<div class="field-group top-label">
<label for="generatedNodeId-15">Check Points</label>

<select name="globalConfigurationDetails" id="globalConfigurationDetails"
class="text auiTextInput">
<option value="-1">--Select Issue Types--</option>
#foreach( $globalConfigurationDetails in $globalConfigurationDetailsList )
<option value="$globalConfigurationDetails" >$globalConfigurationDetails</option> #end
</select>
</div>

<div class="field-group top-label">
<label for="generatedNodeId-15">Status</label>

<select name="status" id="status"
class="text auiTextInput">
<option value="-1">-Select Status-</option>
<option value="YES" >YES</option>
<option value="NO" >NO</option>
<option value="NA" >NA</option>
</select>
</div>

<div class="field-group top-label"><label for="issue_panel_new_element47ujln567">Remark</label>
<input type="text" id="remarks" name="remarks" class="text auiTextInput long-field" value="">
</div>
<span class="issue-form-actions">
<button class="aui-button aui-button-compact marginRight" aria-disabled="false" onclick="myFunction()">Create</button>
<a id="1dm5gbplj" href="#" class="actionLink ">Cancel</a></span>
</fieldset>
</form>
</div>

</div>


</div>
</div>

</div>
</div>

My Java class is below,

 

package com.example.plugins.tutorial;

import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.plugin.webfragment.contextproviders.AbstractJiraContextProvider;
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.user.ApplicationUser;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.customfields.CustomFieldType;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.sql.Date;
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;


import com.atlassian.plugins.tutorial.objects.CustomFieldNames;
import static java.time.temporal.ChronoUnit.DAYS;

import com.atlassian.plugins.tutorial.utils.DBUtils;
import com.atlassian.plugins.tutorial.objects.GlobalConfigurationDetails;
import org.springframework.stereotype.Controller;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.stereotype.Component;

@RequestMapping(value = "/jira")
public class DueDateIndicator extends AbstractJiraContextProvider {

/*@Override
protected void populateVelocityParams(Map params)
{
params.put("instance", this);
}*/

@Override
public Map<String, Object> getContextMap(ApplicationUser applicationUser, JiraHelper jiraHelper) {
Map<String, Object> contextMap = new HashMap<>();
Issue currentIssue = (Issue) jiraHelper.getContextParams().get("issue");

System.out.println("################# currentIssue.getIssueType()NAME ###################" + currentIssue.getIssueType().getName());

String currentIssueType = currentIssue.getIssueType().getName();
String currentStatusType = currentIssue.getStatus().getName();

/**
* Logic to fetch the Configuration based on the issue typeand status.
*/
List<String> globalConfigurationDetailsList = new ArrayList<String>();

globalConfigurationDetailsList = DBUtils.filterGlobalConfigurationDetails(currentIssueType, currentStatusType);
//System.out.println(
// "************************************ DueDateIndicator ####################################");
System.out.println(" ****************** Global Configuration DetailsList ***************** "+globalConfigurationDetailsList);
contextMap.put("globalConfigurationDetailsList", globalConfigurationDetailsList);


return contextMap;
}

@RequestMapping(value = "/saveConfigDetails", method = RequestMethod.GET)
public void saveConfigDetails() {
System.out.println(" ****************** saveConfigDetails GET ***************** ");
}

@RequestMapping(value = "/saveConfigDetails", method = RequestMethod.POST)
public void saveConfigDetailsPOST() {
System.out.println(" ****************** saveConfigDetails POST ***************** ");
}


}

Suggest an answer

Log in or Sign up to answer