Java method call from javascript velocity Templates

Prameesha Samarakoon July 3, 2014

Hi,

I have a requirement to get data from a java method on the 'onChange' method of a Combobox in a velocity template. The java object reference is passed to the velocity template through the 'getVelocityParams' method. How can I pass this velocity parameter( a java class instance) to a javascript method and call the java method from javascript in the velocity Template. I have only gone as far as trying to call the method, what I have done so far is as follows. Is this requirement possible and if so how could I go about this.

[Velocity Template]

<script>
	function loadval(){
			alert($class.getValues()); 
	}
	
</script>
<select class="text long-field" id="r1_c1" name="r2_c1" title="Project" onChange = "loadval()">
        #foreach($project in $projects)
            <option value="$project">$project</option>
        #end    
    	</select>

[Java class]

@Override
	public Map getVelocityParameters(Issue issue, CustomField field, FieldLayoutItem fieldLayoutItem) {
		Map params = super.getVelocityParameters(issue, field, fieldLayoutItem);
		DBAccess dba = new DBAccess();
		List<String> projects = dba.GetProjectList();
		
		params.put("projects", projects);
		params.put("class", new TableCF(customFieldValuePersister, genericConfigManager, authenticationContext));
		return params;
	}

public String getValues(){
		String message = "Method called";
		return message;
	}

I have managed to do a direct method call from the vm template but not through javascript, an error stating 'illegal syntax' gets thrown in the code above. Can someone please suggest a way to go about this?

Thanks

3 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

1 vote
Answer accepted
Andy Brook [Plugin People]
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.
July 3, 2014

Two things,

  1. as a velocity template, you would access your action at render time with $action.getValues().
  2. assuming you are rendering the script inline, the value from your action will be injected into the javscript at render time, not at runtime on the client. You'll need to put that in quotes:alert('$class.getValues()');
Prameesha Samarakoon July 3, 2014

Thanks a lot Andy, that solved my problem :)

Prameesha Samarakoon July 7, 2014

Hi Andy,

If I need to get a value passed in to velocity parameter to a document.ready event is it still the same way to call the variable?

I used the following code and it doesn't seem to work.

<script>
	
	AJS.$(document).ready(function() {
  		 		
  		alert('$value');
  		
	});

</script>

Could you please suggest a way to go about this?

Thanks

0 votes
Andy Brook [Plugin People]
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.
July 7, 2014

No its not the same, Velocity is rendered on the server at Render Time. The HTML content is then sent to the Client Browser where it is Loaded, after which the AJS.$(document).ready() runs. $value has no meaning at that time. The description in my last answer indicated that you can 'inject' values into 'inline' javascript only at render time.

To dynamically load values is different, you will need a REST api for that.

- https://developer.atlassian.com/display/DOCS/Developing+a+REST+Service+Plugin

Prameesha Samarakoon July 9, 2014

Hi Andy,

Thanks a lot for the explanation. The $value is assigned to a text box of the velocity template. So shouldn't I be able to capture the same value from the textbox at the onload event? I've tried this but, document.getElementById("Copy") function gives a null value at this point.

The requirement is to get the value from the text box and populate a table at the onload event, Is there a way to do this without using a REST API?

Also about the previous query of calling a java method if I had to pass a parameter would the following be accurate?

<script>
var value = "abc"; 
('$class.getValues(value)');
</script>

[Java Method]
public String getValues(String val){
return "complete"; }

Thanks again

Andy Brook [Plugin People]
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.
July 13, 2014

Please re-read my comment above, understand the difference between when velocity runs (on the server) and when javascript runs (on the clinet). You can't mix them both as they happen in different places in different contexts.

You can achieve what you want by pre-storing the value from the action class in an inline script variable, however, this is perhaps not the best way to do it, writing a REST API to expose your info and doing an async get from javascript would be better.

Again, $action.getValues('something') will work, but you can't relate it to live javascript.

0 votes
Andy Brook
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.
July 3, 2014

Two things,

  1. as a velocity template, you would access your action at render time with $action.getValues().
  2. assuming you are rendering the script inline, the value from your action will be injected into the javscript at render time, not runtime on the client. You'll need to put that in quotes: alert('$class.getValues()');
TAGS
AUG Leaders

Atlassian Community Events