3

I have a "header" Visualforce Page which contains a navigation bar with links to other various Visualforce pages. However, one of the links, instead of going to another VF page makes a call to a function in the controller class.

    //VF page for Header
<apex:page controller="headerPageController"
    sidebar="false"
    showheader="false"
    cache="false"
    expires="0"
    standardStylesheets="false">
         <div id="navbar">
                 (link to my page outside of Salesforce.)
                    <a class="nav" id="cMethod" href="#" onclick="ControllerMethod(); return false;">C</a> 
                  ...other nav link to other SF page
                  ...other nav link to other SF page 
                </div>

These header and footer VF pages are added to each of the other pages directed to from the home screen in order to keep a seamless page feel. The call works fine when clicked from the home screen which uses the included header and not much else.

However, if I am directed to "Page 1" and then click the method link, nothing happens. Why is this? Is an included page's controller method not accessible or overridden by its own controller?

//VF Page for otherPage
            <apex:page controller="otherPageController"
                sidebar="false"
                showheader="false"
                cache="false"
                expires="0"
                standardStylesheets="false">
                <body>
                <div class="body-container">

                <!-- Header -->
                <apex:include pageName="header_page" />

                .....

More info:

The controller method provides a link on return, which is used as a redirect. When it is clicked on a page other than the home page, a # is added to the URL and nothing else happens.

headerPageController

//I use a function for this so I can also add request parameters to the 
//page reference, they are not shown here as this is just an example.
public with sharing class headerPageController 
{         
         public PageReference ControllerMethod()
         { 
            String url = 'www.google.com';

            PageReference pr = new PageReference(url );
            return pr;
         }    
}
  • (1) where is implementation of Controller() defined in the VF page(s) (header, otherPage)? – cropredy Jun 2 '16 at 16:37
  • "ControllerMethod()" is defined in the "headerPageController", which is assigned as the controller in the header page. otherPage just includes the header page. – JWiley Jun 2 '16 at 16:43
  • 1
    ControllerMethod() is some javascript method? an actionFunction? -- onclick can't call controller methods directly. More details please. – cropredy Jun 2 '16 at 22:00
  • The method is in an Apex class defined as the controller in the header VF page. The page is then added via include to other pages. The method works as expected in our main page, but doesn't in other pages that include the header page but define their own controller. So, onclick can call the controller methods directly, it's already working that way. What I'm asking is if an included page's controller/controller methods don't work when added to a page with its own method. – JWiley Jun 3 '16 at 14:20
  • 1
    hmm... unless using javascript remoting, news to me that javascript can directly call controller method; otherwise - one uses an actionFunction action="controllerActionMethodName" ... – cropredy Jun 3 '16 at 14:27
1
+25

As I understand your question, you have a Visualforce page that has a header and a footer embedded in it. Both the header and the footer, along with each Visualforce page that uses these controllers has a controller. Each header and footer has code that calls a method in the controller using html that looks something like:

<a class="nav" id="cMethod" href="#" onclick="ControllerMethod(); return false;">C</a>

From your description, it sounds as though your home page controller contains this referenced ControllerMethod as does the headerPageController and each otherPageController that's used. If I'm mistaken, please correct this assumption as it's not entirely clear whether or not the home page controller includes the ControllerMethod. It does sound however as though each otherPageController includes the method. Again, please clarify if this is not correct.

What I believe is happening here would be an issue related to Visualforce Order of Execution. Because all of these controllers have a method of the same name, only the method in the first custom controller would be called. If the first controller listed on the page did not contain the method, then the next controller listed on the page that contained the method would be the one from which it would be called.

If this were a standard controller being used for the page, and an extension were listed in the Apex:Page definition, the first extension of several that contained the method of that name, would be the one from which it would be called.

<apex:page controller="Account" Extensions="headerPageController", "footerPageController">

In the above example, a method of the same name would always be called from the headerPageController, never from the footerPageController.

A custom controller cannot be extended. Any methods of the same name would always be called from the original custom controller and NOT from any other controller listed on the page unless it were the controller for a component. Perhaps what you might want to consider doing is making your headers and footers a component instead of creating them as pages of their own.

Edit

After seeing your code and your method, along with understanding that your Home Page does not have a controller, I believe I now understand the issues. It appears that what you're trying to do is to create a behavior where clicking on that link takes someone to the top of a page. It's having the href="#" that makes the link active by associating it with some page link. If that's your desire, I recommend you create an Id named top and apply it to the first element in the visual hierarchy for each of your pages.

It appears to me that what's happening here is that since you don't have a controller on the Home page, the initial PageReference that's returned is ignored since it isn't of the form page/pagename. The # then acts like a regular html anchor, causing the link to send the user to the top of the page when its clicked on.

Since the # isn't located at the end of the PageReference, where it needs to be, when your Action Method returns someurl to the Home Page, with no controller on that page, the Browser Window doesn't know what to do with it other than move the cursor to the top of the page. However, when you're on other pages, those pages each have a controller that maintains the current PageReference and has control over the Window. That's why there's no change.

Your method needs to get the current PageReference and return it, plus append the anchor # to it, preferably with an Id that will move the cursor to a specific location on the page. Thus, my recommendation to return a PageReference of the Current Page + #top, provided of course that you can put an Id of that sort at the top of each of your pages.

| improve this answer | |
  • headerPageController is only controller which contains a reference for the controller method in question. The page which includes the VF header page has its own controller, which does not have a reference to any method named the same. Also there are no extensions with methods of the same. This method is unique, I don't think this has anything to do with order of execution. – JWiley Jun 13 '16 at 19:42
  • From your original post and all the back & forth comments, I found it difficult to ascertain exactly what the case was with your code. I used the extensions as a known example of order of execution. If the headerPageController is the only one with the method, it would seem that there's either a missing reference the controller needs to work with other pages OR, there's something different between how the Home Page is constructed vs how other pages are constructed. I recommend you post your headerPageController code. – crmprogdev Jun 13 '16 at 20:45
  • I added the relevant headerPageController code. The method "ControllerMethod" only returns/redirects when on the homepage. The only difference I could tell that would maybe affect this, is that the homepage does not have a controller assigned. The pages where it doesn't work, have their own assigned controller. So I thought maybe <apex:include pageName> controller would be overridden by the parent page. – JWiley Jun 14 '16 at 14:03
  • From your edit, I think we are narrowing in on the issue but what you have outlined is not my intention. The PageReference to "someurl" is an actual URL, for a page outside of Salesforce, which I am redirecting them to. That being said, the proposed solution is for another purpose, though I think it can be adjusted for my requirement if you understand it better now. – JWiley Jun 17 '16 at 13:30
  • Ahh, redirecting to a specific URL is a very different use case! From your edits, I'm going to assume it's the same for all pages. You should be including http:// in front of the www.google.com or whatever the actual url is that you're sending them to. Don't count on their browser to resolve it. I believe you should also be creating that as an <apex:outputLink> or as an <apex:command link> (latter requires wrapping in a form tag), not as an anchor. with the #. – crmprogdev Jun 17 '16 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.