Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Application.cfm interferes with CFC-call...

Explorer ,
May 25, 2011 May 25, 2011

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.

2.1K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
May 25, 2011 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 25, 2011 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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 25, 2011 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?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 25, 2011 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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 25, 2011 May 25, 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.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 26, 2011 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

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011

@Adam

I don't completely agree with what you say. I expect the context of a method call to exclude(that is, not include) the contents of Application.cfm

@nHeroGo

I have tested a setup similar to yours and, as I very much expected, there were no problems. I took account of two things you didn't. They might help.

1) Delete the attributes value="mediumID" and value="artistID". Otherwise there will be duplication, because the purpose of the binding is to provide the values.

2) Have you ruled out my earlier theory about spaces? It could be that the content of the select field is something like "[loads of empty space]string_value". In fact, it is quite easy to verify this. Just have a look at the source code.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
May 26, 2011 May 26, 2011

@Adam

I don't completely agree with what you say. I expect the context of a method call to exclude(that is, not include) the contents of Application.cfm

It's not really a matter of whether you agree or disagree, or what your own expectations are.  I'm stating what happens.  I'm not offering it up as a vague speculative possibility, I'm just saying how it works.  Having been 90% certain to start with, and not being happy with that level of uncertainty: I tested it.

--

Adam

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011

Your expectation that the context of a method call would exclude the contents of Application.cfm is incorrect in this case, because you're not just calling a method. You're making a full HTTP request to a specific CFC. CF is generating the appropriate response.

Dave Watts, CTO, Fig Leaf Software

http://www.figleaf.com/

http://training.figleaf.com/

Dave Watts, Eidolon LLC
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011

@nHeroGo, @Adam, @Dave

I cannot reproduce the behaviour you describe. It's now 3 against 1, so chances are, I am probably the one missing something.  Here is my set-up:


ColdFusion Build: 9.0.1.274733

Directory: C:\ColdFusion9\wwwroot\cfapptest\

Files in directory cfapptest: Application.cfm, header.cfm, OnRequestEnd.cfm and search.cfm

CFC path: C:\ColdFusion9\wwwroot\searchFunctions.cfc

Application.cfm

==============

<cfapplication name="testApp"
    clientmanagement="Yes"
    sessionmanagement="Yes">
<cfinclude template="header.cfm">

header.cfm

===========

<p>Footer!</p>

OnRequestEnd.cfm

==================

<p>Footer!</p>

search.cfm

===========

<cfform>

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

</cfform>

How similar is this to your test code? How different?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011

I don't know if you're missing something, or if we're just talking past each other a bit. In the setup you describe, though, the CFC won't use the Application.cfm in /cfapptest. If you were to move it into the /cfapptest directory, you'd have the problem we described.

Dave Watts, CTO, Fig Leaf Software

http://www.figleaf.com/

http://training.figleaf.com/

Dave Watts, Eidolon LLC
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011
LATEST

Dave Watts wrote:

In the setup you describe, though, the CFC won't use the Application.cfm in /cfapptest. If you were to move it into the /cfapptest directory, you'd have the problem we described.

Aw, gosh! I was simply on another train. It all makes sense now. Given the set-up you describe, I can fully understand what is going on and don't even have to test.

@nHeroGo

In fact, to confirm what Adam and Dave have said, I will show you how to see for yourself that it is no mystery. Include the header and footer, and open the CFM page in Firefox, with Firebug switched on. Take a look at the Console pane.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
May 26, 2011 May 26, 2011

nHeroGo wrote:


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

> <cfinclude template="pageHeader.cfm">

Oh, I forgot. Another difference with my test code is that my Application.cfm contains this:

<cfapplication name="testApp" sessionTimeout="#CreateTimeSpan(0,0,20,0)#" sessionManagement="Yes">

<cfinclude template="pageHeader.cfm">

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources