+ Start a Discussion
Miriam LückeMiriam Lücke 

Issues with Passing variables from Javascript to Controller

I have some JS function which will create two vars. I write this var to a <apex:inputText> (will change this to inputHidden when it works). It appears in the field but after everything is done the var doesn't appear in the controller and so isn't saved. I did a lot of search but didn't come to a solution, so maybe you could help.
My Visualforce with JS (shortened):
<script type="text/javascript">
<!-- called from another function and works as expected-->
function paymillResponseHandler(error, result) 
{
    if (error) 
    {
      // Displays the error above the form
      alert(error.apierror);
    } 
    else 
    {
      // Output token
      var token = result.token;
      // Insert token into form in order to submit to server
     $("[id$=paymilltoken]").val(token);
     PassStringToController();
    }
} 
</script>
[....]
<apex:form id="paymentform">
...
    <apex:inputHidden value="{!PaymentId}" id="paymentid" />
    
    <apex:inputText value="{!PaymillToken}" id="paymilltoken" />
...
    <div style="float:left;"><br/>
        <p><apex:commandButton action="{!toRegistration}" value="{!$Label.Zur_ck}" styleClass="ab" /></p>
    </div>
    
    <div style="float:right;"><br/>
    <apex:inputHidden value="{!PaymillToken}" id="PaymillTokenField" />
        <p>
<apex:commandButton value="{!$Label.Weiter}" action="{!finishRegistration}" onclick="Paymillfunction();" /></p>
    </div>
</apex:form>
....
My Controller (shortened):
public without sharing class EventmanagementCtrler 
{
    public String PaymillToken{get;set;}
    public String PaymentId{get;set;}
	public Quellen_Kontakt_Zuordnung__c Teilnehmer {get;set;}

	// some more vars ...
	
	// Constructor
    public EventmanagementCtrler()
    {
    	// initialize
	    PaymentId = '';
	    PaymillToken = '';
	}
	...
	    public PageReference finishRegistration()
    {
		system.debug(this.PaymillToken);        	
    	Teilnehmer.Paymill_Token__c = this.PaymillToken; // Teilnehmer is created earlier in the whole process
    	Teilnehmer.Status__c = 'angemeldet';
        upsert Teilnehmer;
        return Page.Sonstiges;
    }
	...
}
Since I'm not that into JS it was hard work for me to get that far - maybe I just don't see a small thing which causes the issue.
Jigar.LakhaniJigar.Lakhani
Hello,

If you do not want to user action function with parameter, then you need to rerender the input hidden, which is not best practice.
Please try to use action function with parameter like below.

Replace your action function:
<apex:actionFunction action="{!finishRegistration}" rerender="anything">
	<apex:param name="prmPaymillToken" value="">
</apex:actionFunction>

Replace your JS function in else condition:

else 
{
  // Output token
  var token = result.token;
  // Insert token into form in order to submit to server
 //$("[id$=paymilltoken]").val(token);
 PassStringToController(token);
}
Replace your controller function:
public PageReference finishRegistration() {
	String strPaymillToken = Apexpages.currentPage().getParameters().get('prmPaymillToken')
	system.debug('########## '+strPaymillToken);
	Teilnehmer.Paymill_Token__c = this.PaymillToken; // Teilnehmer is created earlier in the whole process
	Teilnehmer.Status__c = 'angemeldet';
	upsert Teilnehmer;
	return Page.Sonstiges;
}

You do not need to user inputhidden fields and extra global variables in controller using it.

Let me know if you have any question.

Thanks & Cheers,
Jigar



 

Miriam LückeMiriam Lücke

First of all: Thank you for your help!

I changed my code according to your suggestions. But my controller didn't receive any value. Maybe anything is missing?

Btw. I need the js function (Paymillfunction) to be called from the button (see line 34 in VF-Code above). It is a payment form and in the Paymillfunction I call the library for the payment which delivers the error and the result to the paymillResponseHandler(error, result), as you can see here: 

<script type="text/javascript" src="https://bridge.paymill.com/"></script>
<script type="text/javascript">
function Paymillfunction()
{
    // get all vars from form
    var zahlungsweise = document.getElementById('{!$Component.paymentform.zahlungsweise}').value;
    var card_number = document.getElementById('{!$Component.paymentform.card_number}').value;    
    // ... all other vars accordingly

    // payment method is credit card, otherwise the vars would be empty and error would be thrown 
    if(zahlungsweise == 'Kreditkarte')
    {
        paymill.createToken({
          number:         card_number,        // required
          exp_month:      expiry_date_month,     // required
          exp_year:       expiry_date_year,      // required
          cvc:            cvc,                  // required
          amount_int:     amount_int,           // required, e.g. "4900" for 49.00 EUR
          currency:       currency,              // required
          cardholder:     holdername            // optional
},
paymillResponseHandler);    }
}
function paymillResponseHandler(error, result) 
{
    if (error) 
    {
      // Displays the error above the form
      alert(error.apierror);
    } 
    else 
    {
      // Output token
      var token = result.token;
      // Insert token into form in order to submit to server
     // $("[id$=paymilltoken]").val(token);
     PassStringToController(token);
    }
} 
</script>
Maybe this information is necessary for the solution.
Jigar.LakhaniJigar.Lakhani
Hello,

Replace your apex commandbutton:
<apex:commandButton value="{!$Label.Weiter}" onclick="Paymillfunction();return false;" />

Replace JS Function:

function paymillResponseHandler(error, result) 
{
    if (error) 
    {
      // Displays the error above the form
      alert(error.apierror);
    } 
    else 
    {
      // Output token
      var token = result.token;
      // Insert token into form in order to submit to server
     // $("[id$=paymilltoken]").val(token);
     //PassStringToController();  // Idont know what is it, actionfunction or other JS Function.
     afFinishRegirstration(token);
    }
}

Replace your action function:

<apex:actionFunction name="afFinishRegirstration" action="{!finishRegistration}" rerender="abc">
       <apex:param name="prmPaymillToken" value="">
</apex:actionFunction>

Dont change anything in controll function which I have provided you before.

Thanks & Cheers,
Jigar
Miriam LückeMiriam Lücke
Now I have the token in my Controller but no navigation (which would be done in the finishRegistration-method) happens; when I try to achieve this with a separate button an error appears: The page you submitted was invalid for your session. Please click Save again to confirm your change.

:(