function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
adrisseladrissel 

Javascript variables not passing to Apex controller

Hey all,

I am going absolutely mad trying to figure this out!  I have read tons and tons of articles online about how to pass a variable from Javascript to my Apex Controller...but NONE OF THEM ARE WORKING FOR ME!!  

Can someone take a look at my code here and let me know what the heck is going wrong?  I am only pasting the pertinent sections for now unless it is deemed that this code is accurate:

Visualforce Page:

<apex:page standardController="Case" recordSetVar="Cases" extensions="SIMSQuickCreate">
<head>
    <script> 
        
        function createCase(){
        
            var supplier = document.getElementById('{!$Component.form.block.section1.supplier}').value;
                
            createFunction();
        }
    </script>
    </head>
    <apex:form id="form" >
        <apex:actionFunction name="createFunction" action="{!createCase}" rerender=""/>
        <apex:pageBlock id="block" title="SIMS Quick Create" mode="edit">
            <apex:pageBlockSection id="section1" title="Contact Information" columns="2">
                <apex:inputField id="supplier" value="{!NewCase.Supplier__c}" required="true">
            </apex:pageBlockSection>
            <center><input type="button" value="Create" onclick="createCase();"/></center>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Thus far, if I use JavaScript alert() to show me the value of the "supplier" var it shows perfectly.  However, it doesn't pass to the controller:

public with sharing class SIMSQuickCreate{

    ApexPages.StandardSetController setCon;
    
       
    public SIMSQuickCreate (Apexpages.StandardSetController controller) {

        setCon = controller;
    }
        
    public String supplier {get; set;}   
        
    public Case c;

    public Case getNewCase() {
    
        if(c == null){
            
            c = new Case();
        }
        
        return c;
    }
    
    
    public PageReference createCase() {  
    
        System.Debug('>>>>>>>>>>>>> HERE IS THE VALUE --> ' + supplier);

       return null;
    }
}

The result of the System.Debug is:

(116783031)|USER_DEBUG|[82]|DEBUG|>>>>>>>>>>>>> HERE IS THE VALUE --> null

Everything I have read online tells me that the {get;set;} should get the Javascript variable and set it for the controller.

Why isn't this working for me?!?!
Best Answer chosen by adrissel
Jim JamJim Jam
I suspect your code, as it currently stands, is failing before the controller method is even called. I don't quite understand what '{!$Component.interviewDate}' refers to on your VF page? There is no input field, where is the variable being set? give this is a shot ..

Controller :

public with sharing class TestPassJSVariable{

    Apexpages.StandardController setCon;
   
    public string interviewdate {get; set;}
   
    public TestPassJSVariable(Apexpages.StandardController controller) {

        setCon = controller;
    }
   
    public void saveInterviewDate(){

        System.Debug('This is the variable --> '+interviewdate);

    }
}

VF Page:

<apex:page standardcontroller="Case" extensions="TestPassJSVariable">

<script type="text/javascript">
function doSave(date) {
    paraFunction(date.value);
}

</script>
    <apex:form id="form">
        <apex:actionFunction name="paraFunction" action="{!saveInterviewDate}" rerender="view">    
            <apex:param id="aname" assignTo="{!interviewdate}" name="interviewDate" value="" />
        </apex:actionFunction>
        <apex:inputText id="testString"/>
        <script> var searchTag = document.getElementById("{!$Component.testString}"); </script>
        <apex:commandLink onclick="doSave(searchTag);">              

            <apex:commandButton value="Save"/>
        </apex:commandLink>       
    </apex:form>
</apex:page>


All being well, whatever you enter into the text box should be passed to the controller.

All Answers

Ramu_SFDCRamu_SFDC
Implement this solution

http://salesforceworld.blogspot.com/2011/06/parameter-passing-using.html
adrisseladrissel

Still not working.  Here is the code now:

Visualforce:

<apex:page standardcontroller="Case" extensions="AdamsTest">

<script type="text/javascript">
function doSave(date) {
    paraFunction(document.getElementById(date).value);
}
</script>
    <apex:form id="form">
        <apex:actionFunction name="paraFunction" action="{!saveInterviewDate}" rerender="view">     
            <apex:param id="aname" name="interviewDate" value="" />
        </apex:actionFunction>
        <apex:commandLink onclick="doSave('{!$Component.interviewDate}');">               
            <apex:commandButton value="Save"/>
        </apex:commandLink>        
    </apex:form>
</apex:page>
Controller:

public with sharing class AdamsTest{

    Apexpages.StandardController setCon;
    
    String interviewdate = Apexpages.currentPage().getParameters().get('interviewDate');
    
    public AdamsTest(Apexpages.StandardController controller) {

        setCon = controller;
    }
    
    public void saveInterviewDate(){
    
        System.Debug('This is the variable --> '+interviewdate);
    }
}

This time NOTHING appears in the debug logs for my test.

What's wrong here?
Jim JamJim Jam
Try declaring your variable in the controller like ..

public string interviewdate {get; set;}

and in the visualfirce page pass paramater as follows ..

<apex:param id="aname" assignTo = "{!interviewdate}" name="interviewdate" value="" />
Andy BoettcherAndy Boettcher
To really pass data from your page/javascript to your controller - read up on Javascript Remoting.  I do this quite often and it's really stinking cool.  =)

https://www.salesforce.com/us/developer/docs/pages/Content/pages_js_remoting_example.htm (https://www.salesforce.com/us/developer/docs/pages/Content/pages_js_remoting_example.htm" target="_blank)
adrisseladrissel
Nothing else is working.  I saw Javascript remoting in a couple manuals as well, but it seems to always be in the context of returning variables BACK to the VF page after some other controller action.  Is that necessary for the remoting to work?  I merely need to pass the values to the controller for processing there.

Thanks to all!
Jim JamJim Jam
I suspect your code, as it currently stands, is failing before the controller method is even called. I don't quite understand what '{!$Component.interviewDate}' refers to on your VF page? There is no input field, where is the variable being set? give this is a shot ..

Controller :

public with sharing class TestPassJSVariable{

    Apexpages.StandardController setCon;
   
    public string interviewdate {get; set;}
   
    public TestPassJSVariable(Apexpages.StandardController controller) {

        setCon = controller;
    }
   
    public void saveInterviewDate(){

        System.Debug('This is the variable --> '+interviewdate);

    }
}

VF Page:

<apex:page standardcontroller="Case" extensions="TestPassJSVariable">

<script type="text/javascript">
function doSave(date) {
    paraFunction(date.value);
}

</script>
    <apex:form id="form">
        <apex:actionFunction name="paraFunction" action="{!saveInterviewDate}" rerender="view">    
            <apex:param id="aname" assignTo="{!interviewdate}" name="interviewDate" value="" />
        </apex:actionFunction>
        <apex:inputText id="testString"/>
        <script> var searchTag = document.getElementById("{!$Component.testString}"); </script>
        <apex:commandLink onclick="doSave(searchTag);">              

            <apex:commandButton value="Save"/>
        </apex:commandLink>       
    </apex:form>
</apex:page>


All being well, whatever you enter into the text box should be passed to the controller.
This was selected as the best answer
adrisseladrissel
Awesome cmrc1001.3884211976265837E12!  That worked.

I wonder if you might be willing to help me with one follow-up question.  If I wanted to pass an array of strings from the Javascript function to the controller, how would I format my System.Debug syntax to output both values?

I currently have the following:

public with sharing class TestPassJSVariable{

    Apexpages.StandardController setCon;
   
    // "data" is the array of strings passed from Javascript

    public List<String> data{get; set;}
   
    public TestPassJSVariable(Apexpages.StandardController controller) {

        setCon = controller;
    }
   
    // trying to reference a particular array value in the output

    public void createCase(){

        System.Debug('This is the Supplier variable --> '+data[0]);
        System.Debug('This is the Contact Person variable --> '+data[1]);

    }
}

See the comment tags for details. This yields the following:

Attempt to de-reference a null object
Error is in expression '{!createCase}' in page adams_test

Any ideas?
Jim JamJim Jam
Passing a list object as such is not possible, I would pass multiple parameters to the controller .. something like ..

<apex:param id="param1" assignTo="{!supplierVariable}" name="param1" value="" />
<apex:param id="param2" assignTo="{!ContactPersonVariable}" name="param2" value="" />

or .. you could pass a comma separated list for all your values from the VF Page into single string parameter in the controller and split it into an array there.
adrisseladrissel
Actually, I am doing that.  Here is the full code for the VF page and the controller:

<apex:page standardcontroller="Case" extensions="TestPassJSVariable">

<script type="text/javascript">

    function createCase() {
    
    var supplier = document.getElementById('{!$Component.form.supplierInput}').value;
    var conPerson = document.getElementById('{!$Component.form.conPersonInput}').value;
    
    var data = new Array(supplier,conPerson);
    
    createFunction(data);
}

</script>
    <apex:form id="form">
        <apex:actionFunction name="createFunction" action="{!createCase}" rerender="view">    
            <apex:param id="supplier" assignTo="{!supplier}" name="supplier" value="" />  
            <apex:param id="conPerson" assignTo="{!conPerson}" name="conPerson" value="" />
        </apex:actionFunction>
        <apex:inputField id="supplierInput" value="{!Case.Supplier__c}"/>
        <apex:inputField id="conPersonInput" value="{!Case.Contact_Person__c}"/>
        <input type="button" value="Create" onclick="createCase();" />       
    </apex:form>
</apex:page>

The array "data" is what I am wanting to be passed to the controller.

public with sharing class TestPassJSVariable{

    Apexpages.StandardController setCon;
   
    public List<String> data{get; set;}
   
    public TestPassJSVariable(Apexpages.StandardController controller) {

        setCon = controller;
    }
   
    public void createCase(){

        System.Debug('This is the Supplier variable --> '+data[0]);
        System.Debug('This is the Contact Person variable --> '+data[1]);

    }
}

This doesn't bring across the "data" variable at all.  When I debug for just that value it appears null.  I also tried this on the VF page:

function createCase() {
    
    var supplier = document.getElementById('{!$Component.form.supplierInput}').value;
    var conPerson = document.getElementById('{!$Component.form.conPersonInput}').value;
    
    createFunction(supplier,conPerson);
}

But, that doesn't even allow the page to process.  I think only one variable can be entered into the createFunction.

Thoughts?

I'm not familiar with how to split a list of comma separated values...
adrisseladrissel
I have tried this as well:

<script type="text/javascript">

    function createCase() {
    
    var supplier = document.getElementById('{!$Component.form.supplierInput}').value;
    var conPerson = document.getElementById('{!$Component.form.conPersonInput}').value;
    
    var data = supplier+','+conPerson;
    
    alert(data);
    
    createFunction(data);
}

</script>

Controller:

public with sharing class TestPassJSVariable{

    Apexpages.StandardController setCon;
   
    public String data{get;set;}
   
    public TestPassJSVariable(Apexpages.StandardController controller) {

        setCon = controller;
    }
   
    public void createCase(){
    
        System.Debug('This is the variable --> '+data);
    }
}

System.Debug results in a null value.

Any clue why?  All I'm passing is a comma-separated string.  If I just pass a single variable, it works (i.e. supplier, or conPerson).
Jim JamJim Jam
Have you change the parameter binding on your visualforce page ... 

<apex:actionFunction name="createFunction" action="{!createCase}" rerender="view">
            <apex:param id="data" assignTo="{!data}" name="data" value="" />   
 </apex:actionFunction>
adrisseladrissel
Duh!  That totally worked to bring the longer, comma separated string over.  Now, final questin (I think)...

How do I split the values in the controller to be able to reference/use them independently.  The following does NOT work and gives me a null object error:

public String data {get;set;}
    
String[] caseData = data.split(',');

I am missing something else totally obvious, right?
adrisseladrissel
Used the following:

public String data {get;set;}
    
    String caseData[] = data.split(',');

Got the following error:

Error: Compile Error: unexpected token: '[' at line 7 column 19

Looks like it doesn't like the "[" in that position.
adrisseladrissel
Strangely enough, this actually works:

String test = "test,test1";
    
String[] test2 = test.split('\\,');


for(String testVar : test2){
    
     System.Debug('This is the variable --> '+testVar);
}

So, I can create a comma separated string from within the controller, and it splits perfectly.  But I can't use a comma separated string sent from Javascript without getting an "attempt to de-reference a null object" error?
adrisseladrissel
Did anyone have any additional information to offer here?  Any ways that I can pass multiple variables instead of just one?