How to create a Jira Plugin Custom Field SelectCFType

James Lamb May 2, 2017

I am looking to create a Custom Field for Jira with the type 'SelectCFType'. 

I am new to atlassian development and velocity templates. I am trying to teach myself and have successfully followed the tutorials to create some basic text field plugins. I have had a read around on the forums to see if I can find an example of how to implement a 'SelectCFType' custom field and could not find anything. 

I would really appreciate if someone could point me in the right direction to get me stated with a 'SelectCFType' custom field type. 

 

So far what i have is taken from here: https://community.atlassian.com/t5/Answers-Developer-Questions/How-to-work-assign-Option-value-to-selectCfType-customField-from/qaq-p/483685 

 

************************************************************************

selectboxCustomField.java

************************************************************************

package com.example.plugins.tutorial.jira.customfield;

import com.atlassian.jira.issue.customfields.impl.SelectCFType;
import com.atlassian.jira.issue.customfields.manager.OptionsManager;
import com.atlassian.jira.issue.customfields.option.Option;
import com.atlassian.jira.issue.customfields.option.Options;
import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls;
import com.atlassian.jira.issue.search.SearchContextImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;
import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.fields.config.FieldConfig;
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;

import java.util.HashMap;
import java.util.Map;

public class selectboxCustomField extends SelectCFType {

private static final Logger log = LoggerFactory.getLogger(selectboxCustomField.class);
private final OptionsManager optionsManager;

public selectboxCustomField(CustomFieldValuePersister customFieldValuePersister, OptionsManager optionsManager, GenericConfigManager genericConfigManager, JiraBaseUrls jiraBaseUrls) {
super(customFieldValuePersister, optionsManager, genericConfigManager, jiraBaseUrls);
this.optionsManager = optionsManager;
}


@Override
public Map<String, Object> getVelocityParameters(final Issue issue,
final CustomField field,
final FieldLayoutItem fieldLayoutItem) {

final Map<String, Object> parameters = super.getVelocityParameters(issue, field, fieldLayoutItem);

FieldConfig fieldConfiguration = null;
if(issue == null)
{
fieldConfiguration = field.getReleventConfig(new SearchContextImpl());
} else
{
fieldConfiguration = field.getRelevantConfig(issue);
}
Options options = this.optionsManager.getOptions(fieldConfiguration);
if (options.isEmpty()) {
this.optionsManager.createOption(fieldConfiguration, null, new Long(1), "A");
this.optionsManager.createOption(fieldConfiguration, null, new Long(2), "B");
}
options = this.optionsManager.getOptions(fieldConfiguration);
Map<Long, String> results = new HashMap<Long, String>();

Long selectedId= (long) -1;
boolean selected = false;
Object value = field.getValue(issue);
if (value!=null) {
selected=true;
}
for (Option option : (Iterable<Option>) options) {
results.put(option.getOptionId(), option.getValue());
if (selected && value.toString().equals(option.getValue())) {
selectedId = option.getOptionId();
}
}

parameters.put("results", results);
parameters.put("selectedId", selectedId);
return parameters;
}
}

 

************************************************************************

edit.vm
************************************************************************

#* @vtlvariable name="results" type="java.util.Map" *#
#* @vtlvariable name="selectedId" type="java.lang.String" *#
#controlHeader ($action $customField.id $customField.name $fieldLayoutItem.required $displayParameters.noHeader)

<select name="$customField.id" id="$customField.id" >
<option value="-1">Not selected</option>
#foreach ($mapEntry in $results.entrySet())
#if ( $selectedId == $mapEntry.key )
<option selected="selected" value="$mapEntry.key">$mapEntry.value</option>
#else
<option value="$mapEntry.key">$mapEntry.value</option>
#end
#end
</select>

#controlFooter ($action $fieldLayoutItem.fieldDescription $displayParameters.noHeader)

 

************************************************************************

view.vm
************************************************************************

#if($value)
$value
#end

 

************************************************************************

atlassianplugin.xml
************************************************************************

<?xml version="1.0" encoding="UTF-8"?>

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="tutorial-jira-custom-field"/>
<!-- add our web resources -->
<web-resource key="tutorial-jira-custom-field-resources" name="tutorial-jira-custom-field Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="tutorial-jira-custom-field.css" location="/css/tutorial-jira-custom-field.css"/>
<resource type="download" name="tutorial-jira-custom-field.js" location="/js/tutorial-jira-custom-field.js"/>
<resource type="download" name="images/" location="/images"/>
<context>tutorial-jira-custom-field</context>
</web-resource>

<customfield-type name="selectbox Custom Field" i18n-name-key="selectbox-custom-field.name" key="selectbox-custom-field" class="com.example.plugins.tutorial.jira.customfield.selectboxCustomField">
<description key="selectbox-custom-field.description">The selectbox Custom Field Plugin</description>
<resource name="view" type="velocity" location="/templates/customfields/selectbox-custom-field/view.vm"/>
<resource name="edit" type="velocity" location="/templates/customfields/selectbox-custom-field/edit.vm"/>
<resource name="column-view" type="velocity" location="templates/view.vm"/>
<resource name="xml" type="velocity" location="templates/view.vm"/>
</customfield-type>
</atlassian-plugin>

************************************************************************

 

When I run "atlas-run" to start my local instance of jira. This plugin successfully installs and I can see this within "Add-ons -> Manage add-ons" where is states that both modules for this plugin are enabled. 

The first issue presents itself when I try to view this custom field in "Issues -> Custom fields". This field does not appear when I try to "Add custom field". 

 

Any help / pointers would be greatly appreciated.

1 answer

4 votes
Jlamb250194 May 4, 2017

I have solved this issue. 

I modified my constructed to use the @ComponentImport: 

@Inject
public IntegerCustomField(@ComponentImport CustomFieldValuePersister customFieldValuePersister,@ComponentImport OptionsManager optionsManager,@ComponentImport GenericConfigManager genericConfigManager,@ComponentImport JiraBaseUrls jiraBaseUrls) {
super(customFieldValuePersister, optionsManager, genericConfigManager, jiraBaseUrls);
this.optionsManager = optionsManager;
this.jiraBaseUrls = jiraBaseUrls;
}

Suggest an answer

Log in or Sign up to answer