Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to pass a Javascript array to my apex controller. I know you can pass a string from Javascript through the use of hidden input field and apex action function (and I have used it in the past) but trying a similar thing for arrays did not work. E.g

<apex:page controller="MyController" id = "MyPage">
    <apex:form id="myForm">
        <button type="button" id="B" onclick = "setHidden()">Set Array!</button>
        <apex:inputHidden value="{!StringArr}" id="myHiddenField"/>
        <apex:actionFunction name="passArryToCon" action="{!MyConMethod}" rerender="myForm"/>
    </apex:form>
    <script type="text/javascript">
        j$ = jQuery.noConflict();
        function setHidden() {
           var StrArr = ['product 1', 'product 2', 'product 3'];
           document.getElementById('{!$Component.MyPage.myForm.myHiddenField}').value = (StrArr); //**masterpagefullwidth component id** 
           passArryToCon();
    }     
    </script>
</apex:page>

My Controller

public with sharing class MyController {
    public List<string> StringArr {get; set;}
    public PageReference MyConMethod() {
        system.debug('Passed in value: '+StringArr);
        return null;
    }
}

Could someone suggest a way to get this working? Thanks.

share|improve this question
up vote 1 down vote accepted

Passing an array natively wouldn't be easy, if it is even possible. Personally, I'd convert the array to JSON, then on the controller side, use JSON to turn it back to an array. You could also use page parameters, such as with an action function, but you'd ask have to convey from a string to an array.

share|improve this answer
    
It sounds like assigning to a List<String> through an apex:actionFunction would suffice for his needs. What exactly do you mean by natively? – Adrian Larson Jan 28 '15 at 17:36
    
The only way you could pass an array would be to bind to a select list with multiple attribute set to true. However, Visualforce validates the values given to it on form submit, so that method would only with if the list of known values were already present in the view state, and even then, it's a massive amount of dom manipulation compared to a simple JSON serialize and deserialize. – sfdcfox Jan 28 '15 at 18:11
    
Thanks guys - I think the JSON serialize and deserialize might be the way to go. I will try it out and update this space. Thanks again. – CescFab Jan 28 '15 at 18:37

This can be achieved without a @RemoteAction if you want to stick to stateful methods by using apex:actionFunction. If you were not using primitives in your array, you would need to convert to/from JSON.

<apex:form>
    <apex:actionFunction name="afConMethod" action="{!MyConMethod}">
        <apex:param value="" name="array" assignTo="{!StringArr}" />
    </apex:actionFunction>
</apex:form>
<script type="text/javascript">
    function setHidden() {
       var StrArr = ['product 1', 'product 2', 'product 3'];
       afConMethod(StrArr);
    }     
</script>
share|improve this answer

In addition to my previous suggestion, Here is what I propose coding wise....

In Visualforce:

<apex:actionFunction name="applyFltr" action="{!loadProjects}">
<apex:param name="countries" assignTo="{!countries}" value="" /></apex:actionFunction>

In Javascript:

var countries = []; //fill this javascript array by some sort of javascript processings.
$('#countryCheck').each(function() {
if ($(this).is(":checked") == true) {
  countries.push($(this).val());
}
});

$(document).ready(function () { 
jq('#applyFilter').on('click', function() {
    applyFltr(countries.toString()); //this will call the actionFunction method from javascript, one of the parameters is a converted string format of javascript array.
});    
});

In Apex Controller:

public with sharing controller {
public String countries{get;set;} //String formatted array which we will receive from VF page. 
public String[] countryList{get;set;} //To convert into the list from the string formatted input.
public constructor(){
    countryList = new list<String>();
}
public void loadProjects() {
    countryList = convertStrToList(countries);
}
public String[] convertStrToList(string str) {
    String[] listToReturn = new List<String>();
    if(String.isNotBlank(str)) {
        for(String eachStr : str.split(',')) {
            listToReturn.add(eachStr);
        }
    }
    return listToReturn;
}}
share|improve this answer

One option would be to use Javascript Remoting. Instead of passing the array to a variable, you could just call an apex method using javascript remoting, and pass the array as a parameter.

share|improve this answer
    
Unless you need access to the view state. Then you'd need something different. – sfdcfox Jan 28 '15 at 17:29

I would suggest to convert the javascript array to string from the front end using JS_ARRAY.toString() and send the parameter via string and catch it via string property and process this input via a comma(,) delimiter.

share|improve this answer
    
Great idea -- although using JSON.stringify() (in the browser) and JSON.deserialize() (in Apex) is safer. Can you expand with a short example of how to actually set up the actionFunction etc.? – Benj Jul 6 '15 at 15:43
    
Done, please check answer in this thread and mark may be give a thumbs up if you like it :) – Irfan Jul 8 '15 at 11:07

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.