Would like to display a customfieldtype extended from MultiSelectCFType to show in .vm file

Umair Haroon
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.
May 5, 2014

Hi,

I am able to add my custom field type (which was added via a plugin by extending MultiSelectCFType) in Jira and associate it with screen and projects. However it does not show up in the screen(eg create issue screen with which it was associated). I populate the MultiSelectCFType with in jira after adding it.

My code for the field is:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import webwork.action.ActionContext;

import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.bc.project.component.ProjectComponent;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.config.FeatureManager;
//import com.atlassian.jira.issue.customfields.impl.*;
//import com.atlassian.jira.issue.customfields.impl.MultiSelectCFType;
import com.atlassian.jira.issue.customfields.impl.MultiSelectCFType;
//import com.atlassian.jira.issue.customfields.impl.GenericTextCFType;

import com.atlassian.jira.issue.fields.rest.json.beans.JiraBaseUrls;
import com.atlassian.jira.issue.customfields.manager.GenericConfigManager;
import com.atlassian.jira.issue.customfields.manager.OptionsManager;
import com.atlassian.jira.issue.customfields.option.Option;
import com.atlassian.jira.issue.customfields.persistence.CustomFieldValuePersister;
import com.atlassian.jira.issue.customfields.persistence.PersistenceFieldType;
import com.atlassian.jira.issue.customfields.impl.FieldValidationException;
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.config.FieldConfigScheme;
import com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager;
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
import com.atlassian.jira.security.JiraAuthenticationContext;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;


public class MyCustomField extends MultiSelectCFType 
{
	private JiraAuthenticationContext authContext;
	private OptionsManager optionsManager;
	
	private static final Logger log = LoggerFactory.getLogger(MyCustomField.class);
    
	public MyCustomField(OptionsManager optionsManager,	CustomFieldValuePersister valuePersister, GenericConfigManager genericConfigManager, JiraBaseUrls jiraBaseUrls, SearchService searchService, FeatureManager featureManager)
	{
		super(optionsManager, valuePersister, genericConfigManager, jiraBaseUrls, searchService, featureManager);
		this.optionsManager = optionsManager;
		this.authContext = authContext;
	}
    
    @Override
    public Map<String, Object> getVelocityParameters(final Issue issue,
                                                     final CustomField field,
                                                     final FieldLayoutItem fieldLayoutItem) 
     {
        final Map<String, Object> params = super.getVelocityParameters(issue, field, fieldLayoutItem);
        //field.getOptions(arg0, arg1)
       params.put("currentUser", authContext.getLoggedInUser().getName() );
          
       params.put("options", ActionContext.getParameters().get(field.getName()) );
       return params;
    }
 }

My plugin description uses two velocity files.
&lt;customfield-type name="My Custom Field" i18n-name-key="my-custom-field.name" key="my-custom-field" class="com.fieldPlugin.jira.customfields.MyCustomField"&gt;
    &lt;description key="my-custom-field.description"&gt;The My Custom Field Plugin&lt;/description&gt;
    &lt;resource name="view" type="velocity" location="templates/view-readonly-user.vm"/&gt;
    &lt;resource name="column-view" type="velocity" location="templates/view-readonly-user.vm"/&gt;
    &lt;resource name="xml" type="velocity" location="templates/view-readonly-user.vm"/&gt;
    &lt;resource name="edit" type="velocity" location="templates/edit-readonly-user.vm"/&gt;
  &lt;/customfield-type&gt;

My edit-readonly-user.vm is:

#customControlHeader ($action $customField.id $customField.name $fieldLayoutItem.required
					    $displayParameters)

<select name="$customField.id" id="$customField.id" multiple size="5">
            <option value="-1">None</option>
	#foreach ($option in $options)
            <option value="$option.id">$option.name</option>    
        #end
</select> #customControlFooter ($action $customField.id $fieldLayoutItem.fieldDescription $displayParameters)

My view-readonly-user.vm is:

$!value

I believe I might be getting the $options in the edit-readonly-user.vm wrong (from code).

Can anyone solve this for me? I have not been able to find a working tutorial for a multi-select custom field which gave the .vm as well.
Thanks

4 answers

1 accepted

2 votes
Answer accepted
Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 5, 2014

Hi,

Have you implemented getValueFromIssue method. A sample is as below

@Override
public Collection&lt;Option&gt; getValueFromIssue(CustomField field, Issue issue) {
	Collection&lt;Option&gt; retValues = new ArrayList&lt;Option&gt;();
	List&lt;Object&gt; values = customFieldValuePersister.getValues(field, issue.getId(),
					PersistenceFieldType.TYPE_LIMITED_TEXT);

	for (Iterator&lt;Object&gt; iterator = values.iterator(); iterator.hasNext();) {
		Long optionId = Long.valueOf((String)iterator.next());
				retValues.add(optionsManager.findByOptionId(optionId));
}

	return retValues;
}

And in the vm file try using $configs.options

#foreach ($option in $configs.options)
...
#end

Tuncay Senturk

Umair Haroon
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.
May 5, 2014

Yes I am aware of this funciton, however is it mandatory to override it?

After all I am extending MultiSelectCFType and would not mind using the super class function.

Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 5, 2014
Have you tried vm part of my comment?
Umair Haroon
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.
May 5, 2014

will try it tommorrow

Umair Haroon
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.
May 6, 2014

@TuncayYes I tried the vm part you suggested. It didnt work.

My edit vm is:

#customControlHeader ($action $customField.id $customField.name $fieldLayoutItem.required
$displayParameters)

<select name="$customField.id" id="$customField.id" multiple size="5">
<option value="-1">None</option>

#foreach ($option in $configs.options)
<option value="$option.id">$option.name</option>
#end
</select>

#customControlFooter ($action $customField.id $fieldLayoutItem.fieldDescription
$displayParameters)

While my class is:

public class MyCustomField extends MultiSelectCFType 
{
	private JiraAuthenticationContext authContext;
	private OptionsManager optionsManager;
	
	private static final Logger log = LoggerFactory.getLogger(MyCustomField.class);
    
	public MyCustomField(OptionsManager optionsManager,	CustomFieldValuePersister valuePersister, GenericConfigManager genericConfigManager, JiraBaseUrls jiraBaseUrls, SearchService searchService, FeatureManager featureManager)
	{
		super(optionsManager, valuePersister, genericConfigManager, jiraBaseUrls, searchService, featureManager);
		this.optionsManager = optionsManager;
		this.authContext = authContext;
	}
    
    @Override
    public Map&lt;String, Object&gt; getVelocityParameters(final Issue issue,
                                                     final CustomField field,
                                                     final FieldLayoutItem fieldLayoutItem) 
     {
        final Map&lt;String, Object&gt; params = super.getVelocityParameters(issue, field, fieldLayoutItem);
        //field.getOptions(arg0, arg1)
       params.put("currentUser", authContext.getLoggedInUser().getName() );
	   return params;
	   }
};

Umair Haroon
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.
May 6, 2014

Also I tried putting in this function as is you suggested in the class:

@Override
public Collection&lt;Option&gt; getValueFromIssue(CustomField field, Issue issue) {
    Collection&lt;Option&gt; retValues = new ArrayList&lt;Option&gt;();
    List&lt;Object&gt; values = customFieldValuePersister.getValues(field, issue.getId(),
                    PersistenceFieldType.TYPE_LIMITED_TEXT);
 
    for (Iterator&lt;Object&gt; iterator = values.iterator(); iterator.hasNext();) {
        Long optionId = Long.valueOf((String)iterator.next());
                retValues.add(optionsManager.findByOptionId(optionId));
}
 
    return retValues;
}

still the field doesnt show.

Umair Haroon
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.
May 6, 2014

Thanks for the sample @Tuncay.

It didnt work either.
I first tried the vm templates that the multiselectCFType uses itself (as is), that didnt work.
Then I used your templates as is and added the functions of your class in mine.
That did not work too.

The field doenst show up on the screen even when the type has been added.

One thing to know is that when I edit the custom field and go the edit custom field details from JIRA,

it says:

There are no search templates for this custom field type.

Could that be the problem?

Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 6, 2014
If you specify your email I can send you a sample so that you can check it out
0 votes
Umair Haroon
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.
May 7, 2014

I have been able to find out the reason why it was not working.

In the getVelocityParameters function of the class I was doing:

params.put("currentUser", authContext.getLoggedInUser().getName() );

For some reason with that particular statement present the class extended from MultiSelectCFType would not show.

@jobin kuruvilla[Go2Group]

I used your tutorial on how to make a custom field type where you made a class: ReadOnlyUserCF extends GenericTextCFType and used the statement :

params.put("currentUser", authContext.getLoggedInUser().getName() );

for illustration. It didnt give any problems displaying the field on the screen however when extending from MultiSelectCFType this prevents the field from even displaying.

0 votes
Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 5, 2014
Have you tried vm part of my comment?
0 votes
Tuncay Senturk
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 5, 2014
Hi,

Suggest an answer

Log in or Sign up to answer