+ Start a Discussion
kdaviskdavis 

Java Script Remote Method Failure in Visual Force Component

Hi,

 

I'm putting a VF component on Case records. Essentially I return a set of Asset records and provide a checkbox next to each so they can add multiple assets to the case at once. Once they select a checkbox next to the assets, the asset ID is pushed to a JScript variable. 

 

After all the user has selected all their assets, they click a button which pushes the Javascript Var String to my remote method in my controller where I parse the Jscript string into the different ID's.

 

Problem is, everything works fine in the page, when I do it in editor. Once I get on an actual Case detail page I get an error everytime I try to call the remote method that tells me Uncaugh ReferenceError: [My Controller Name] is not defined. 

 

Any Ideas on how to fix this? I know they communicate correctly in the page editor just not in the acutal component. Code Below:

 

 

Page:

<apex:page standardController="Case" extensions="linkAssetExtension">
    <apex:includeScript value="{!$Resource.JqueryUI}"/>
    <apex:includeScript value="{!$Resource.JQueryCustom}"/>
    <apex:stylesheet value="{!$Resource.JqueryStyles}"/>
    <apex:stylesheet value="{!$Resource.JqueryStyles2}"/> 

    
<script type="text/javascript">

var j$ = jQuery.noConflict();

var assets = null;

function selectAsset(ele){
    
    console.log(j$(ele).is(':checked'));
    
    if(j$(ele).is(':checked')){
        console.log(j$(ele).attr('Id'));
        id = j$(ele).attr('Id');
        entitlement = j$(ele).attr('entitle');
        
        if(assets === null){
            assets = id+':'+entitlement;
        }else{
            assets += '-'+id+':'+entitlement;
        }
        console.log(assets);
    }
   
}
    
function insertAssets(){
    
        linkAssetExtension.linkAsset( 
        assets,
        function(result, event){
            console.log(result)
        }
    );

}

</script>

<apex:form >
    <apex:PageBlock title="Search Assets">

            Please Enter A Serial Number:&nbsp;&nbsp;&nbsp;
            <apex:inputText value="{!serialId}"/><br/><br/>

            <apex:pageBlockTable value="{!assets}" var="a" columns="4" Width="90%">
                <apex:column id="Select" headerValue="Select">
                    <input type="checkbox" onclick="selectAsset(this)" name="{!a.Name}" serial="{!a.Serial_Number__c}" id="{!a.Id}" entitle="{!a.Entitlement__c}"/>
                </apex:column>
                <apex:column id="Name" headerValue="Name" value="{!a.Name}"/>                

                <apex:column id="Serial" headerValue="Serial #" value="{!a.Serial_Number__c}"/>

                <apex:column id="Entitle" headerValue="Entitlement" value="{!a.Entitlement__c}"/>

            </apex:pageBlockTable>
      
        <apex:PageBlockButtons location="bottom">
            <apex:CommandButton value="Search" action="{!searchAssets}"/>
            <div style="width:45px;height:18px;border:1px solid black;border-radius:5px;text-align:center;display:inline-block;margin-top:-2px;vertical-align:middle;" onclick="insertAssets()">Link</div>
        </apex:PageBlockButtons>
    </apex:PageBlock>
</apex:form>

</apex:page>

 

Controller:

public class linkAssetExtension {
    
    public String serialId {get; set;} 
    public List<Asset> assets {get; set;}   
    private final Case c;
    public static Id caseId {get; set;}
    
    public linkAssetExtension(ApexPages.StandardController controller) {
        this.c = (Case)controller.getRecord();
        caseId = c.Id;
        assets = new List<Asset> ();
    }

    public void searchAssets(){
        if(serialId != null){
            assets = [SELECT Id, Name, Serial_Number__c, Entitlement__c, Asset_Type__c FROM Asset WHERE Serial_Number__c =: serialId];
        }
    }
    
    @RemoteAction
    public static Map<String, List<String>> linkAsset(String assetList){
       
       system.debug(assetList);
       List<Case> upsertCase = new List<Case> ();
       Map<String, List<String>> assetMap = new Map<String, List<String>> ();
       

        List<String> assetFields = new List<String> ();
        assetFields = assetList.split('-');
        
        for(String s : assetFields){
            List<String> fields = new List<String> ();
            fields = s.split(':');
            assetMap.put(fields[0], fields);
        }
            
     
        for(String s : assetMap.keySet()){
            //Add link records
        }

        return assetMap;
    }    
}

 

Juan SpagnoliJuan Spagnoli

Hi kdavis! try doing the call using:

 

Visualforce.remoting.Manager.invokeAction(
                    '{!$RemoteAction.MyController.MyMethod}', 
                    params,
                    function(result, event){
                        if (event.status) {
                            console.log('Result=',result);
                        } else if (event.type === 'exception') {
                            console.log('Event=',event);
                            console.log('Result=',result);
                            return false;
                        } else {
                            console.log('Event=',event);
                            console.log('Result=',result);
                            return false;
                        }
                    }, 
                    {escape: true}
                );

 

Good luck

kdaviskdavis

Hi Juan,

 

Thanks for the response but I am unfortunately recieving the same error.

 

I didn't notice this before but I have an error page load that indicates a domain issue with my I frame

Blocked a frame with origin "https://c.cs15.visual.force.com" from accessing a frame with origin "https://cs15.salesforce.com". Protocols, domains, and ports must match.

 

Any ideas on how to match them?

 

Juan SpagnoliJuan Spagnoli

You can't match them. That's happening because your visualforce run in a different domain (c.cs15..) than case´s standard page (cs15...). I'm not sure that this is the cause of your remoteaction's error. Try removing your remoteaction's javascript function, and check if that message shows again.

kdaviskdavis

Yea,

 

If I comment out the Remote function the error dissapears on page load. Any work arounds for this?

kdaviskdavis

I made my extension controller global as well as the remote method. The error dissappeared and I was able to get a response from the controller. Thanks for all the help, I suppose making the class global overrides the security of access from different servers? I'm just glad it works.

 

Thanks