Skip to main content
Participant
May 25, 2011
Question

Application.cfm interferes with CFC-call...

  • May 25, 2011
  • 4 replies
  • 2065 views

Application.cfm interferes with CFC-call...

I have some files called Application.cfm, PageHeader.cfm, OnRequestEnd.cfm, PageFooter.cfm, SearchFunctions.cfc, and of course the actual page called Search.cfm

The Application.cfm file is using CFINCLUDE to include the PageHeader.cfm file and the OnRequestEnd.cfm includes the PageFooter.cfm file in a similar way.

Search.cfm have some CFSELECT tags bound to a CFC, and the code is sound and should work, but the dropdowns come up empty.

However, if I move the CFINCLUDE tags from Application.cfm and OnRequestEnd.cfm and include them in the Search.cfm file instead, then the dropdown menus in the CFSELECT tag are filled with the data from the CFC (as it should).

It is a mystery.

For some unknown reason, the CFSELECT will not call the CFC even though the parameter bindonload="true" if the PageHeader.cfm file is included in the application-file, but it will call the CFC when it is included from the page.

Now you are wondering what it in the PageHeader.cfm file and PageFooter.cfm, I'm sure? But it's nothing important, just some html-code, some css, and some linked js, and it all works if it is not included in the application-file. Mysterious.

    This topic has been closed for replies.

    4 replies

    nHeroGoAuthor
    Participant
    May 26, 2011

    Nope. I think it is a bug. Try the following on your computer.

    Test One................

    Application.cfm: Let it only contain an include statement, and nothing else

    <cfinclude template="pageHeader.cfm">

    OnRequestEnd.cfm: Let it only contain and include statement

    <cfinclude template="pageFooter.cfm">

    pageHeader.cfm: let it only have one line of html code
    <p>test</p>


    pageFooter.cfm: leave it blank

    Make a cfm-page (call it TestPage.cfm, for example) with CFSELECT-tag that binds to a CFC, similar to this code


    <cfselect name="mediumID" bind="cfc:searchFunctions.listMedium()" value="mediumID" display="Medium" bindonload="true" />
    <cfselect name="artistID" bind="cfc:searchFunctions.listArtistsByMediumID({mediumID})" value="artistID" display="Artist"/>

    ...and the result will be empty drop-down menus.

    Test Two...................

    Remove (or comment out) the CFINCLUDE statement (for the pageHeader.cfm) in the Application-file, and put the CFINCLUDE statement at the top of the TestPage.cfm (or what ever you named the page with the cfform). ...and the result is that it is working.

    Test Three.................

    Keep it the way it was in test one, but delete the simple html-code in pageHeader.cfm file, or simply comment it out
    <!---<p>test</p>--->    ....and the result is that it will work

    Very mysterious.

    What I learn from this is that you cannot use <cfinclude template="pageHeader.cfm"> in an application.cfm if you will bind any CFCs to CFSELECT. And you cannot trick it either by using the CGI.scriptname and try to not include the pageHeader.cfm for particular pages. Bummer. My workaround is to simply not include the pageHeader-file in the Application-file, but to include it on every page in the directory.

    Inspiring
    May 26, 2011

    No, it's not a bug. I explained why, above. But I'll try again. Maybe you're not getting how the bind expression in your CFSELECT works.

    The bind expression specifies a CFC and a method and some method arguments. When the mark-up loads on the client, JavaScript calls that CFC method with those arguments, and expects the call to return JSON. That request is the same as any other CF request: when it comes in, processing is as follows:

    • run Application.cfm

    • run the requested template (in this case your CFC method)

    • run OnRequestEnd.cfm

    Now: your Application.cfm & OnRequestEnd.cfm output (returns) HTML. So what JavaScript gets back from its remote call to the CFC is:

    • your HTML header

    • the JSON it actually wants

    • your HTML footer

    This is invalid as far as the JS is concerned, so it ignores it. So your CFSELECT receives no data to populate itself with.

    So, back to what I said earlier: you're gonna have to rejig your Application.cfm & OnRequest.cfm to •not• output those header/footers if the request is coming from a CFC.

    Or you could put your CFC in a different directory which bypasses that Application.cfm.

    Or - better still - stop outputting mark-up in your Application.cfm which is really more appropriate for setting up the request environment, rather that performing output. Your kinda mixing up your model and view there (and ignoring the concept of controller completely).

    However you spin it, CF is doing exactly what you're telling it to do. You're just not telling it to do an appropriate thing.

    Make sense?

    --

    Adam

    BKBK
    Community Expert
    Community Expert
    May 25, 2011

    Your set-up seems to be in order. Including the header and footer as you have done is unlikely to be the problem.

    I'll take a wild guess. What happens when you set output="false"  in the cfcomponent and cffunction tags in the CFC being called?

    Inspiring
    May 25, 2011

    Your set-up seems to be in order. Including the header and footer as you have done is unlikely to be the problem.

    Really? You don't think returning a header and footer around the JSON that the CFSELECT is expecting back from the CFC will cause problems?

    Interesting.

    --

    Adam

    Inspiring
    May 25, 2011

    A call to a CFC is just a request, so Application.cfm will be executed, and it'll be including your header (and your OnRequestEnd.cfm will be including your footer).

    Which'll bugger-up what the JavaScript is expecting to receive back (which'll probably be a JSON object).

    You need to recode your Application.cfm (etc) to NOT do those includes when it's a CFC request.

    --

    Adam

    Owainnorth
    Inspiring
    May 25, 2011

    Do you get any Javascript errors? I'd guess it's some kind of scoping issue, and would suggest you start by changing to an Application.cfc model.