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
Karel SlabyKarel Slaby 

How can I call innerclass method in visualforce page?

Hello everyone,

is there any way how to call innerclass' method in visualforce page?

Thanks for answers in advance,

Karel.

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

This is a bug that may be related to internal bug number W-1065879. This bug specifically dealt with inputText references that would fail to work on maps, but apparently other elements fail to work correctly with maps as well. (See http://boards.developerforce.com/t5/forums/forumtopicprintpage/board-id/Visualforce/message-id/41334/print-single-message/false/page/1 for an example).

 

To work around this bug, you have to create a wrapper class as a list that is driven from the maps contents (independently discovered by myself, but I'm sure others have, too).

 

Here's your code, modified to work around the bug.

 

public with sharing class testtemp {
    // Public variables.
    public list<InnerClass> lstProcedures {get; set;}
    public string key { get; set; }
    
    // Contains map items for displayed list.
    map <string, innerclass> items;
        
    // Class Constructor, unchanged.
    public class InnerClass {
        public integer counter  {get; set;}
        public InnerClass() {
            counter = 0;
        } 
        
        public void edit(){
            counter++;
        }
    }
    
    // Default constructor.
    public testtemp() {
        key = 'mapkey';
        lstProcedures = new list<InnerClass>();
        lstProcedures.add(new InnerClass());
        items = new map<string, innerclass>();        
        items.put('mapkey', new InnerClass());
    }
    
    // Generate a map-driven list.
    public wrapper[] getmapprocedures() {
        wrapper[] w = new wrapper[0];
        for(string key:items.keyset()) {
            w.add(new wrapper(this,key));
        }
        return w;
    }
    
    public class wrapper {
        testtemp controller;
        string key;
        
        // Constructor for wrapper
        public wrapper(testtemp controller, string key) {
            this.controller = controller;
            this.key = key;
        }
        // Proxy retrieve InnerClass
        public Innerclass getItem() {
            return controller.items.get(key);
        }
        // Proxy call InnerClass
        public void edit() {
            controller.items.get(key).edit();
        }
    }
}

 

<apex:page controller="testtemp">
    <apex:form >
        <apex:repeat value="{!lstProcedures}" var="procedure">
            {!procedure.counter} <apex:commandLink action="{!procedure.Edit}" value="Edit"/>
        </apex:repeat>
        <apex:repeat value="{!mapProcedures}" var="var">
            {!var.item.counter} <apex:commandLink action="{!var.item.Edit}" value="Edit"/>
        </apex:repeat>
    </apex:form>
    
</apex:page>

You still get the benefits of using a map from a controller point of view by exposing the data to Visualforce as a list.

All Answers

jd123jd123

Hello

 

 

 

You need to reference the object of your inner class and then reference the methods from there.  You also must make sure that you have those innerclass methods marked as public.

 

 

 

Karel SlabyKarel Slaby

Thank you jd123 very much for reply,

I have just figured out where was the problem.

I tried to call innerclass method from map of inneclasses, and that causes problem.

Here is example how it is not working for maps, but it is working well for lists:

Controller:

public with sharing class testtemp {
    public list<InnerClass> lstProcedures {get; set;}
    public map<string, InnerClass> mapProcedures {get; set;}
    public string key {get; set;}
    
    public class InnerClass {
    	public integer counter  {get; set;}
        public InnerClass() {
            counter = 0;
        } 
        
        public void edit(){
            counter++;
        }
    }
    
    public testtemp() {
    	key = 'mapkey';
        lstProcedures = new list<InnerClass>();
        lstProcedures.add(new InnerClass());
        
        mapProcedures = new map<string, InnerClass>();
        mapProcedures.put(key, new InnerClass());
    }
}

 VF Page:

<apex:page controller="testtemp">
    <apex:form >
        <apex:repeat value="{!lstProcedures}" var="procedure">
            {!procedure.counter} <apex:commandLink action="{!procedure.Edit}" value="Edit"/>
        </apex:repeat>
        
        <apex:repeat value="{!mapProcedures}" var="key">
            {!mapProcedures[key].counter} <apex:commandLink action="{!mapProcedures[key].Edit}" value="Edit"/>
        </apex:repeat>
    </apex:form>
    
</apex:page>

 After calling Method from Map Inner class I obtain Visualforce Error:

Unknown property 'testtemp.InnerClass.Edit'

Error is in expression '{!mapProcedures[key].Edit}' in component <apex:page > in page testtemp

 

Is there any way how to call innerclass' method from MAP in visualforce page?

 

Thanks in advance for helping me,

Karel.

sfdcfoxsfdcfox

This is a bug that may be related to internal bug number W-1065879. This bug specifically dealt with inputText references that would fail to work on maps, but apparently other elements fail to work correctly with maps as well. (See http://boards.developerforce.com/t5/forums/forumtopicprintpage/board-id/Visualforce/message-id/41334/print-single-message/false/page/1 for an example).

 

To work around this bug, you have to create a wrapper class as a list that is driven from the maps contents (independently discovered by myself, but I'm sure others have, too).

 

Here's your code, modified to work around the bug.

 

public with sharing class testtemp {
    // Public variables.
    public list<InnerClass> lstProcedures {get; set;}
    public string key { get; set; }
    
    // Contains map items for displayed list.
    map <string, innerclass> items;
        
    // Class Constructor, unchanged.
    public class InnerClass {
        public integer counter  {get; set;}
        public InnerClass() {
            counter = 0;
        } 
        
        public void edit(){
            counter++;
        }
    }
    
    // Default constructor.
    public testtemp() {
        key = 'mapkey';
        lstProcedures = new list<InnerClass>();
        lstProcedures.add(new InnerClass());
        items = new map<string, innerclass>();        
        items.put('mapkey', new InnerClass());
    }
    
    // Generate a map-driven list.
    public wrapper[] getmapprocedures() {
        wrapper[] w = new wrapper[0];
        for(string key:items.keyset()) {
            w.add(new wrapper(this,key));
        }
        return w;
    }
    
    public class wrapper {
        testtemp controller;
        string key;
        
        // Constructor for wrapper
        public wrapper(testtemp controller, string key) {
            this.controller = controller;
            this.key = key;
        }
        // Proxy retrieve InnerClass
        public Innerclass getItem() {
            return controller.items.get(key);
        }
        // Proxy call InnerClass
        public void edit() {
            controller.items.get(key).edit();
        }
    }
}

 

<apex:page controller="testtemp">
    <apex:form >
        <apex:repeat value="{!lstProcedures}" var="procedure">
            {!procedure.counter} <apex:commandLink action="{!procedure.Edit}" value="Edit"/>
        </apex:repeat>
        <apex:repeat value="{!mapProcedures}" var="var">
            {!var.item.counter} <apex:commandLink action="{!var.item.Edit}" value="Edit"/>
        </apex:repeat>
    </apex:form>
    
</apex:page>

You still get the benefits of using a map from a controller point of view by exposing the data to Visualforce as a list.

This was selected as the best answer
Karel SlabyKarel Slaby

Thank you sfdcfox for your answer! Acually I have been using this workaround with lists of wrapper classes since I fonud this bug. I was just curious why it doesn't work and whether I make any mistake. Thanks for explanation.

B2000B2000
This issue still exists in Ver 30.0, Spring '14.  The difference now is that the VF page won't save and generates two error messages:
Error Error: java.lang.UnsupportedOperationException
Error Error: null
You can access the inner class method if it is a list as explained above, just not a map. 
lukasz zlukasz z
In API ver 31.0 this issue still exists.
Salesforce online editor gives an error during saving visualforce page:
[Error] Error: java.lang.UnsupportedOperationException
[Error] Error: null

Eclipse gives only: 
Save error: null