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

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

This widget could not be displayed.

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

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.

Have you tried vm part of my comment?

will try it tommorrow

@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;
	   }
};

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.

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?

If you specify your email I can send you a sample so that you can check it out
This widget could not be displayed.
Hi,

This widget could not be displayed.
Have you tried vm part of my comment?
This widget could not be displayed.

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.

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted yesterday in Jira

What modern development practices are at the heart of how your team delivers software?

Hey Community mates! Claire here from the Software Product Marketing team. We all know software development changes rapidly, and it's often tough to keep up. But from our research, we've found the h...

66 views 0 1
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you