Wes Nolte posted a great tip on his blog Silver Lining on passing javascript values to an Apex controller. After reading his post I realized that there is another way to skin that cat using ActionFunction and Param tags.
ActionFunction results in a javascript function being rendered on the page. Once that function is rendered on the page you can exercise it from within other javascript. The function that is rendered will cause a post to be executed in the same way a CommandButton or CommandLink will.
A common technique for form posts is to create properties or getter/setter pairs for fields in your Apex class that can be bound to hidden input fields on the form. But, what if you don't want or need to persist the data from your post? You may want to send some values that have been obtained via javascript to the controller to use in the action but don't need to be persisted in the view state. You can do this with the Param tag.
The following Visualforce page illustrates this concept.
<apex:page controller="ActionPageController">
<apex:form >
<apex:actionFunction name="hitMe" action="{!iWantMyJSValues}" rerender="jsvalues">
<apex:param name="one" value="" />
<apex:param name="two" value="" />
</apex:actionFunction>
<apex:outputPanel id="jsvalues">
<apex:outputText value="Value one: {!valueOne}" /><br/>
<apex:outputText value="Value two: {!valueTwo}" /><br />
</apex:outputPanel>
<span style="cursor: pointer;"
onclick="hitMe(Date(), 'best shot')">Hit Me</span>
</apex:form>
</apex:page>
When the page above is rendered a javascript function called hitMe will be created. You can see that I'm hooking the onclick event of the standard HTML span tag to invoke the hitMe method. I'm passing in a new instance of the current date and time followed by a javascript string value.
The controller is show below.
public with sharing class ActionPageController {
public String valueOne { get; set; }
public String valueTwo { get; set; }
public PageReference iWantMyJSValues() {
valueOne = Apexpages.currentPage().getParameters().get('one');
valueTwo = Apexpages.currentPage().getParameters().get('two');
return null;
}
}
Here I have created two properties to hold the values passed in. This is for illustration purposes. I could easily choose not save either of the values. The key is that I am getting access to the javascript values through the curretPage().getParameters() map.
To see what is happening it's useful to look at the firebug log of the actionFunction post.
You can see that the Param tags caused to post parameters to be included in the post, "one" and "two". The key is that getParameters() not only applies to url query parameters but also to post parameters. One thing to keep in mind is that the order that you define the param tags is the order that you should pass your values to the actionFunction generated javascript function. You are essentially defining the signature of the generated javascript function with
<actionFunction myfunc>
<param one>
<param two>
to result in
function myFunc(one, two) {}
You can give this a try by pasting the page code into a new page and the controller code into a new Apex class.
Cheers,
DevAngel