How to Selectively Include JavaScripts in ColdBox?

I been playing around with your framework quite a bit the past few
days, and I love it. This is an amazing project you have created. I
just rewrote part of a Fusebox project yesterday, and I can already
see how much faster and simpler it would be to build out the entire
thing in ColdBox.

Anyway, I was actually wondering if I could pick your brain for best
practices for intelligently loading JavaScripts. In other words,
selectively load scripts based on what is needed in the request.
Something more elegant than a huge cfswitch block in the head of the
layout doc.

Ideally, I would like to be able to announce what I need (i.e. -
jQuery, AjaxCFC, some UI component, etc.) within each event handler,
or, for an entire event handler CFC?

I’m dreaming of something like a comma delimited list of the
JavaScript blocks/packages I want to include in a handler… <cfset
event.getScript("jQuery, AjaxCFC, tableSorter") />

How do you handle this? Can you give me some tips, or an example that
is helpful?

Would it be better if I post this in the forum?

Thanks,
Thomas Dehli

Also, I should have included a style sheet for the PU-36 form template
I sent, something like this…

.formLayout label {
       float:left;
       color: #333366;
       text-align:right;
       font-weight:bold;
       font-size:11px;
       margin-right:8px;
       display:block;
       width:20em;
       line-height:1.5em;
       }

ul.formLayout {
       clear:both;
       float:left;
       list-style: none;
       padding:0;
       margin:8px 0;
       width:99%;
       }

ul.formLayout li {
       clear:both;
       color:#000;
       padding:0;
       margin:6px 0;
       }

There are several ways to handle this Thomas. However, I have used
some in the past, where I use my implicit "preHandler" methods on my
event handler cfc. This method gets executed before any event in the
component. That way, you can select dynamic js or any css here. You
can do it in several ways, either just setting a variable in the
request collection with the js and css to load, or actually readin in
the js and css and creating a content variable that can then outputed
on your layout.

Here is an example of just setting the js.

<cffunction name="preHandler" access="public" returntype="void">
  <cfargument name="event" type="any">
  <cfscript>
  var rc = event.getCollection();
  //set the js to use for this handler
  rc.js_list = "includes/ajaxcfc.js, includes/myjs.js";
  </cfscript>
</cffunction>

Then on your layout, you could do something like:

<cfloop index="listelement" list="rc.js_list">
<script language="javascript" src="#listelement#"></script>
</cfloop>

That would do the trick!! You can do the same for css this way.

In conclusion, you can use the preHandler, postHandler methods to do
implicit settings into the request collection, depending on which
event handler got executed. Or you can just use a global request
start handler to do it or an interceptor that executes preRender.

Let me know if it helps.

Nice.. how would you do it with a layer of abstraction? Say for
instance I could just call 'AjaxCFC' or 'Forms' regardless of its
location or the number of js files included for it, etc?

In other words, I could now go back and edit what my AjaxCFC content
variable entails... without having to change any handlers where it is
is referenced?

Another example would be forms, where I may need jQuery and a few
plugins as a package for all forms pages. Then one day the 'forms'
package changes, and I only want to update one location.

Thanks for the help,
Thomas

I would have to see samples, I don't quite visualize it.

For some reason I'm having a hard time explaining what I want to do,
so bear with me. As far as a 'script package', I simply mean a group
of scripts that work together to provide certain functionality.

For instance, I may want to include the following scripts only on
pages with forms...

<!--- Forms --->
<script type="text/javascript" src="/js/jq/form/jquery.form.js"></

<script type="text/javascript" src="/js/jq/form/jquery.metadata.js"></

<script type="text/javascript" src="/js/jq/form/jquery.validate.js"></

<script type="text/javascript" src="/js/jq/form/
jquery.selectboxes.pack.js"></script>

Now let's say on another page, I also want some UI stuff (in addition
to the form scripts)...

<!--- UI --->
<script type="text/javascript" src="/js/jq/ui/ui.mouse.js"></script>
<script type="text/javascript" src="/js/jq/ui/ui.draggable.js"></

<script type="text/javascript" src="/js/jq/ui/ui.droppable.js"></

<script type="text/javascript" src="/js/jq/ui/ui.sortable.js"></

I like to be able to say something like, "get me the Forms, UI, and
AjaxCFC scripts for this page" (or preHandler, or whatever). So if the
scripts included in the Forms variable cahnge, they're only changed in
one place.

Per your example, I could create separate variables (somewhere
global), and then figure out a way to append them together before
looping through the list...

Forms = "/js/jq/form/jquery.form.js,/js/jq/form/jquery.metadata.js,/js/
jq/form/jquery.validate.js,/js/jq/form/jquery.selectboxes.pack.js"

UI = "/js/jq/ui/ui.mouse.js,/js/jq/ui/ui.draggable.js,/js/jq/ui/
ui.droppable.js,/js/jq/ui/ui.sortable.js"

Seems like I'm missing an elegant way of doing this...

Any of this making sense ;}
Then figure out a way to append the lists together before looping the
list?

Hi ,

I think you are looking something which require to be fire at the end of your process.

you can do this by using [ehMain.onRequestEnd()] to figure what you need and append into list.

have a global settings of array in config.xml.cfm

I hope this would work for you.

Regards
Sana