Passing Javascript values to Apex Controller

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.

Screen-capture-182

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

tagged , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • http://d3developer.wordpress.com d3developer

    “Continue reading” link doesn’t work.

  • http://www.trineo.co.nz Dan Fowlie

    I think you can simplify further by using the assignTo attribute on the param tag which will call the setter method and remove the need for the 2 lines in the controller method that get the values from the current page parameters.

  • http://profile.typepad.com/davecarroll Dave Carroll

    For sure, if I need to save the values that are being posted. This technique allows me to not HAVE to go to the extra trouble of binding the params to properties. I simply am setting them in this case to illustrate that the values are being passed and are accessible through the getParameters method of the currentPage object.
    The great advantage I think is that in this pattern we don’t have to reference {!$Component.Name} in the javascript to set values of hidden fields.
    Cheers

  • http://www.tehnrd.com Jason

    Very slick!
    Posts like this are great as you would never really know how to do this unless you had some back end knowledge of how Visualforce works.

  • Mike Leach

    Having to trust that property setters will be called before an action feels awkward.
    I like this approach of letting the Action access the volatile params directly.
    Thx!

  • Anonymous

    is there a way i could get bac values from a javascript function i created and store into a text field