+ Start a Discussion
SalesRedSalesRed 

Assign Value To Controller From Javascript Without ActionFunction

Hi,

 

This is a very unusual requirement I know and may not be possible but I thought I'd put it out there all to same to confirm.

 

- I require to use Javascript Remoting to perform a particular requirement in my Force.com site.  With this (and if this was possible it would be ideal)  I would like to assign the result returned from the remoting funciton to a variable in my controller.

I know an actionFunction can be used for this but I require to do this without an actionFunction and directly from my Javascript.

 

Can this be done or is it impossible?  Can the actionFunction be replicated in Javascript?

 

Thanks in advance for any help on this and I know it's a very unusual scenario! 

Best Answer chosen by Admin (Salesforce Developers) 
Rahul SharmaRahul Sharma

Hello 

You are right, We are unable to get the updated value of property in javascript.

I am wondering why that is the case(even after adding a rerender/refresh).

 

In below code you can see, The property is updated with remoting result once remote method is executed(Used a button to just rerender the controller property.):

 

// Controller
------------------------------------------------------------------------------------------------------------
public with sharing class remotingExample {
    public String controllerProperty {get;set;}
    public remotingExample() {
        controllerProperty = '1';
    }
    @RemoteAction
    public static String testRemoteJS(String testStringValue){
          return testStringValue;
    }
}
------------------------------------------------------------------------------------------------------------
// Visualforce page 
------------------------------------------------------------------------------------------------------------
<apex:page controller="remotingExample">
    <!-- Add your jQuery files, Now it is referring to my static resource file-->
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-1.3.2.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-ui-1.7.2.custom.min.js')}"/>
    <apex:stylesheet value="{!URLFOR($Resource.jquery, 'css/ui-lightness/jquery-ui-1.7.2.custom.css')}"/>
    
    <script type="text/javascript">
    function testRemoteFunc() {
        Visualforce.remoting.Manager.invokeAction(
            '{!$RemoteAction.remotingExample.testRemoteJS}',
            '2',
            function(result, event){
                if (event.status) {
                    console.log('value retrieved from remoting : ', result);
                    $('input[id$=changedProperty]').val(result);
                    console.log('remoteTest1=','{!controllerProperty}');
                    console.log('remoteTest1Val=',$('input[id$=changedProperty]').val());
                }
            },
            {escape: true}
        );
    }
    </script>
    <apex:form >
        <apex:pageBlock title="fun with remoting">
            <apex:pageblockSection >
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Test Remote Action</apex:outputLabel>
                    <apex:inputCheckbox onclick="testRemoteFunc()">
                        <apex:actionsupport event="onclick" rerender="controllerProperty"/>
                    </apex:inputCheckbox>
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="old controllers property"></apex:outputLabel>
                    <apex:inputText id="controllerProperty" value="{!controllerProperty}"/>
                </apex:pageBlockSectionItem>
                
                
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="updated controllers property"></apex:outputLabel>
                    <apex:inputText id="changedProperty" value="{!controllerProperty}"/>
                </apex:pageBlockSectionItem>
                
            </apex:pageblockSection>
            
            <apex:pageblockButtons location="top">
                    <apex:commandButton value="If I click on this button then controllers property will be updated" rerender="controllerProperty"/>
                </apex:pageblockButtons>
        </apex:pageBlock>
        
    </apex:form>
</apex:page>
------------------------------------------------------------------------------------------------------------

 

The only issue is you don't get the updated property(Or I don't know how to access updated one) in javascript even after setting the Hidden variable.

All Answers

Rahul SharmaRahul Sharma

I think you should try something like this.


Define a apex:inputHidden tag with controller's property  assigned to its value.

And from javascript, assign the remoting result to hidden tag's value.

 

Now you will be able to get the remoting result in controller's property(which is binded with inputHidden).

SalesRedSalesRed

Hi Rahul,

 

Thank you for your suggestion. My understanding of this though is that via Javascript (or jQuery) I can assign the result to the value of my hidden field in my browser but that it won't bind to the controller variable until I perform some action to pass this to the controller (by an actionFUnction or commandLink for example)  Do you think it should bind immediately on assigning it to the hiddenfield?  

 

Thanks for your suggestion.

Rahul SharmaRahul Sharma
Yes, I think it will bind automatically once the remote method is performed.
SalesRedSalesRed

Hi Rahul,

 

if I try somethign along the lines of t the following

 

--> In my Visualforce page

 

<apex:outputLabel >Test Remote Action</apex:outputLabel><apex:inputCheckbox onclick="testRemoteFunc()"/>
<apex:inputHidden id="testStrValueField" value="{!testStrValue}"/>

 

<script type="text/javascript">
     function testRemoteFunc() {

                                                  Visualforce.remoting.Manager.invokeAction(
                                                               '{!$RemoteAction.TestRemote.testRemoteJS}',
                                                                'Hello from test',
                                                                function(result, event){
                                                                      if (event.status) {

                                                                              console.log('resultVal=', result);
                                                                              $('input[id$=testStrValueField]').val(result);
                                                                              console.log('remoteTest1=','{!testStrValue}');
                                                                              console.log('remoteTest1Val=',$('input[id$=testStrValueField]').val());
                                                                     }

                                                                },
                                                                {escape: true}
                                                    );
                                      }
 </script>


--->And in my controller

 

String testStrValue;


@RemoteAction
public static String testRemoteJS(String testStringValue){
      return testStringValue;
}

 

My console log prints out

 

resultVal= testing123333
remoteTest1=
remoteTest1Val= testing123333
 
The same occurs if I change my remote function in my controller to change a static variable.
 

String static testStrValue;


@RemoteAction
public static String testRemoteJS(String testStringValue){

       testStrValue = testStringValue;
      return testStrValue;
}

 

Are what I am trying above incorrect?

 

 

Thanks again for your help.

Rahul SharmaRahul Sharma

Hello 

You are right, We are unable to get the updated value of property in javascript.

I am wondering why that is the case(even after adding a rerender/refresh).

 

In below code you can see, The property is updated with remoting result once remote method is executed(Used a button to just rerender the controller property.):

 

// Controller
------------------------------------------------------------------------------------------------------------
public with sharing class remotingExample {
    public String controllerProperty {get;set;}
    public remotingExample() {
        controllerProperty = '1';
    }
    @RemoteAction
    public static String testRemoteJS(String testStringValue){
          return testStringValue;
    }
}
------------------------------------------------------------------------------------------------------------
// Visualforce page 
------------------------------------------------------------------------------------------------------------
<apex:page controller="remotingExample">
    <!-- Add your jQuery files, Now it is referring to my static resource file-->
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-1.3.2.min.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery, 'js/jquery-ui-1.7.2.custom.min.js')}"/>
    <apex:stylesheet value="{!URLFOR($Resource.jquery, 'css/ui-lightness/jquery-ui-1.7.2.custom.css')}"/>
    
    <script type="text/javascript">
    function testRemoteFunc() {
        Visualforce.remoting.Manager.invokeAction(
            '{!$RemoteAction.remotingExample.testRemoteJS}',
            '2',
            function(result, event){
                if (event.status) {
                    console.log('value retrieved from remoting : ', result);
                    $('input[id$=changedProperty]').val(result);
                    console.log('remoteTest1=','{!controllerProperty}');
                    console.log('remoteTest1Val=',$('input[id$=changedProperty]').val());
                }
            },
            {escape: true}
        );
    }
    </script>
    <apex:form >
        <apex:pageBlock title="fun with remoting">
            <apex:pageblockSection >
                <apex:pageBlockSectionItem >
                    <apex:outputLabel >Test Remote Action</apex:outputLabel>
                    <apex:inputCheckbox onclick="testRemoteFunc()">
                        <apex:actionsupport event="onclick" rerender="controllerProperty"/>
                    </apex:inputCheckbox>
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="old controllers property"></apex:outputLabel>
                    <apex:inputText id="controllerProperty" value="{!controllerProperty}"/>
                </apex:pageBlockSectionItem>
                
                
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="updated controllers property"></apex:outputLabel>
                    <apex:inputText id="changedProperty" value="{!controllerProperty}"/>
                </apex:pageBlockSectionItem>
                
            </apex:pageblockSection>
            
            <apex:pageblockButtons location="top">
                    <apex:commandButton value="If I click on this button then controllers property will be updated" rerender="controllerProperty"/>
                </apex:pageblockButtons>
        </apex:pageBlock>
        
    </apex:form>
</apex:page>
------------------------------------------------------------------------------------------------------------

 

The only issue is you don't get the updated property(Or I don't know how to access updated one) in javascript even after setting the Hidden variable.

This was selected as the best answer
SalesRedSalesRed

Hi Rahul

 

Thanks again for your help.  For my required scenario I would need to do something similar to the following.

-> Call the remote function.

 - On receiving the result use this result to set it to a controller variable and pass this variable as an attribute to a custom cumponent contained in my vForce page..

 

Do you think without using a commabdButton like you have used for rerenderng below that the variabe when passed to my custom component would take the new value as set in the Javascript remoting function (or still have the old value)?

 

Thanks.

 

 

SalesRedSalesRed

I guess I may still need to rerender the outputPanel where my custom component is included.  Do you know if apex outputPanel's can be rerendered from my remoting function also?

 

Thanks again.

bujjibujji
Hi Rahul,

I am struck up with some challenge. Please help me to solve this.
I am displaying some account info using apex:repeat tag in a pageBlock. I want to edit the data and update to the same account. How can i do this. I am using custom controller.

Below is the page and controller code i am using.

Page
------------------------------

<apex:page controller="AccountSearchController" showHeader="false" tabStyle="Opportunity" >

<apex:form >
<apex:pageMessages id="errors" />

&lt;script type="text/javascript">
function doSearch() {
searchServer(
document.getElementById("firstName").value);
}
&lt;/script&gt;
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="results,results1,debug,errors">
<apex:param name="firstName" value="" />
<apex:param name="bCity" value="" />
</apex:actionFunction>

<div style="width:183px;margin:0px 5px;">
<table width="100%">
<tr><td>&nbsp;</td></tr>
<tr>
<td style="font-weight:bold;" colspan="3" width="50%" >
<input class="quickfindInput" type="text" id="firstName" onclick="(this.value='')" onblur="rev()" onkeyup="doSearch();" style="border-radius:5px 5px 5px 5px;" title="Quick Find"/>
<tr><td>&nbsp;</td></tr>
<span style="font-weight:normal;">search by Name or customer ID</span>
</td>
</tr>
</table>
</div>
<div style="width:1000px;margin:0px 0px;">
<div style="width:175px;height:510px;margin:0px 10px;float:left;overflow:auto;">
<apex:pageBlock id="results" >
<apex:pageBlockTable value="{!accounts}" var="acc" >
<apex:column headerValue="Account Name">
<apex:commandLink action="{!getAccounts}" value="{!acc.Name}" reRender="results1,results2">
<apex:param name="accId" value="{!acc.Id}"/>
</apex:commandLink>
</apex:column>
</apex:pageBlockTable>
</apex:pageBlock>
</div>

<div style="width:1000px;margin:0px -190px;float:right;height:100%;overflow:auto;">
<apex:pageBlock id="results1" title="Account Details" mode="inlineEdit">
<table width="100%" align="center" >
<apex:pageBlockButtons >
<apex:commandButton id="saveButton" value="save">
</apex:commandButton>
</apex:pageBlockButtons>
<apex:repeat value="{!accs}" var="acc1">
<tr><td>&nbsp;</td></tr>
<tr>
<td width="11%" align="left" style="font-size:12px;font-weight:bold;">Account Name&nbsp;</td>
<td width="30%" align="left">
<apex:inputField value="{!acc1.Name}">
</apex:inputField>
</td>
<td width="6%" align="left" style="font-size:12px;font-weight:bold;">Phone&nbsp;</td>
<td width="43%" align="left">
<apex:inputField value="{!acc1.Phone}"> </apex:inputField>
</td>
</tr>

</apex:repeat>
</table>
</apex:pageBlock>
</div>
</div>
</apex:form>
</apex:page>

Controller
-------------------

public class AccountSearchController {

private String soql {get;set;}
public List<Account> accounts {get;set;}
public List<Account> getAccs {get;set;}

public String debugSoql {
get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20'; }
set;
}
public AccountSearchController() {
soql = 'select Id,Name,BillingCity from Account where Name != null';
}
public void runQuery() {
try {
accounts = Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20');
} catch (Exception e) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
}
}
public PageReference runSearch() {

String accName = Apexpages.currentPage().getParameters().get('firstName');
String bCity = Apexpages.currentPage().getParameters().get('bCity');

soql = 'select Id,Name,BillingCity from Account';
if (!accName.equals(''))
soql += ' where Name LIKE \''+String.escapeSingleQuotes(accName)+'%\' or BillingCity LIKE \''+String.escapeSingleQuotes(accName)+'%\'';
if (!bCity.equals(''))
soql += ' and BillingCity LIKE \''+String.escapeSingleQuotes(bCity)+'%\'';
// run the query again
runQuery();
return null;
}
public PageReference getAccounts() {
Account acc = [select Id,Name From Account where Id = :ApexPages.currentPage().getParameters().get('accId')];
system.debug('************************************************'+acc);
return null;
}
public List<Account> getAccs() {
List<Account> accList = [select Id,Name,Phone,Fax,Website,BillingCity,BillingState,BillingPostalCode From Account where Id = :ApexPages.currentPage().getParameters().get('accId')];
return accList;
}
public List<Contact> getCons(){

String aId = ApexPages.currentPage().getParameters().get('accId');
system.debug('***********************************************'+aId);
if(aId == null){
return null;
}
else{
List<Contact> conList = [select Id,Name,Email,HomePhone,MobilePhone From Contact where Account.Id = :ApexPages.currentPage().getParameters().get('accId')];
return conList;
}
}
}


Thanks,
Bujji