loading more javascript after the first call to enhance()

16 views
Skip to first unread message

Karl Rosaen

unread,
Feb 26, 2010, 8:32:47 PM2/26/10
to EnhanceJS
Hey all,

I was playing with modifying my site to use enhancejs today, and ran
into an issue because of the way I currently structure the loading of
javascript. I use a templating system as part of the tornado web
framework (quite similar to django's and many others I imagine), and
as part of the base template, I include the libraries I always use
(jquery and some others).

In some pages I load more javascript that is specific to a particular
page (e.g applies some enhancements to items only on a particular
page). The base template includes a block before the end of the
closing body tag that I usually use in templates when I want to add
more javascript, e.g:

{% block body-end %}

<script type="text/javascript" src="{{ static_url("javascript/
pagespecificcode.js") }}"></script>

{% end %}

and this works because I know it is loaded after any of the javascript
included in the base template. Now it doesn't work because it won't
be loaded after the scripts loaded in the call to enhance in the base
template. I tried to fix this by calling enhance() again with another
script, but it doesn't seem to work:

<!-- enhance.js -->
<script type="text/javascript" src="{{ static_url("javascript/
enhance.js") }}"></script>

<script type="text/javascript">
enhance({
loadScripts: [
'{{ static_url("javascript/jquery-1.4.2.js") }}',
'http://www.google.com/jsapi?
key={{ google_api_key }}',
]
});
</script>

then in the other page:

{% block body-end %}
enhance({
loadScripts: [
'{{ static_url("javascript/pagespecificcode.js") }}'
]
});
{% end %}


So anyways, to make a long story short, it seems I have two feature
requests:

1) the ability to load more scripts after the first call to enhance()
that guarantees they are loaded after anything loaded in the original
call.

2) the ability to load a block of code (in the form of a function).
this would be nice during development, analogous to having inline
javascript before cleaning it up into a separate file.

Or, if I'm mistaken and this functionality already exists, do tell! I
can also try to put together a patch to add this functionality if we
can agree it is needed.

Thanks,
Karl


ScottJehl

unread,
Feb 26, 2010, 9:07:33 PM2/26/10
to EnhanceJS
Hi Karl,
I think both of these are good ideas.
#2 would likely be an easy addition. We could add an option for
something like "scriptsLoaded", which can accept a callback function
that will execute after the final script loads. Request #1 may take a
little more work, but if #2 is available, there's a chance you might
not even need it.

Let me give it a little thought and get back to you.
If you have implementation ideas for #1, feel free to post them.

Thanks,
-Scott

Karl Rosaen

unread,
Feb 27, 2010, 7:15:41 AM2/27/10
to EnhanceJS
Thanks Scott.

> that will execute after the final script loads. Request #1 may take a
> little more work, but if #2 is available, there's a chance you might
> not even need it.

yes that would definitely provide a workaround for all cases where
callback could embed the functionality or just invoke a function
defined in one of the loaded scripts.

> If you have implementation ideas for #1, feel free to post them.

could the queue inside appendScriptsSync be moved up to a module
variable that could be appended to?

enhance = function(options) {
...
var syncscripts = options.queueLoading ?
[].concat(options.loadScripts) : [];
var asyncscripts = options.queueLoading ? [] :
[].concat(options.loadScripts);
...
}

function enhancePage() {
...
appendScriptsAsync(asyncscripts);
appendScriptsSync(syncscripts);
..
}

enhance.defaultSettings = {
...
addScript : function(script) {
asyncscripts.push(script);
}
}

the addScripts could also check whether the appending of all of the
original async scripts had occurred yet, and if so, start adding them
right away.

Karl

Karl Rosaen

unread,
Feb 27, 2010, 7:51:11 AM2/27/10
to EnhanceJS
On playing with this a little bit more, I realized a couple of things
that were incorrect about my previous posts:

1) calling enhance again passing in more loadScripts *does* work,
there was a different error in my code preventing it from working at
first.

but because the two different calls will be working off separate
queues, it seems like won't guarantee the desired ordering.

2) in my proposed solution, addScripts shouldn't be placed in the
settings, but exported as part of enhance:

enhance.addScript = function(script) {
syncScripts.push(script);
};

I tried adding this to enhance.js locally, and it works. E.g I
called:

enhance.addScript('{{ static_url("javascript/
page_specific_code.js") }}');

ScottJehl

unread,
Mar 1, 2010, 3:05:10 PM3/1/10
to EnhanceJS
Hi Karl,
I think your most recent post sounds good, though for #2, we'll need
to keep addScripts as an option (but also make an addScript method
available later on). That may have been what you were saying already,
but I wasn't sure.

Maybe we should move these requests to the Issues section so we can
reference them as they're developed: http://code.google.com/p/enhancejs/issues/list

Would you mind filing the issues, and since you said you have a
working example, would you be able to put together a patch to include?
Thanks again,
Scott

Karl Rosaen

unread,
Mar 1, 2010, 8:15:18 PM3/1/10
to enha...@googlegroups.com
Hey Scott,

Yeah, I'll create an issue at code.google and include my patch there
so you can see in detail what I'm talking about.

The reason I think it needs to be a method is that rather than call
enhance() again with an option, I think it might be better to call
addScript which will append to the queue of scripts that are already
in line to be added.

Karl

> --
> You received this message because you are subscribed to the Google Groups "EnhanceJS" group.
> To post to this group, send email to enha...@googlegroups.com.
> To unsubscribe from this group, send email to enhancejs+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/enhancejs?hl=en.
>
>

ScottJehl

unread,
Mar 2, 2010, 9:36:03 AM3/2/10
to EnhanceJS
Sounds great, Karl.
To be clear, I think adding the addScript method is a great idea (or
possibly an "addScripts" method to match the option and support one or
many). I just don't want to remove the option that's already in use,
that's all.
Sounds like we're on the same page here. I'll look forward to seeing
the issue/patch.
Thanks again!

Karl Rosaen

unread,
Mar 4, 2010, 12:13:22 PM3/4/10
to EnhanceJS

ScottJehl

unread,
Mar 24, 2010, 6:04:46 PM3/24/10
to EnhanceJS
Karl,
Your request #2 from above (onScriptsLoaded callback) should be
addressed now:
commit: http://code.google.com/p/enhancejs/source/detail?r=79
issue: http://code.google.com/p/enhancejs/issues/detail?id=6

Still working on your other patch for addScripts.
If you get a chance, let me know what you think!
-Scott

Karl Rosaen

unread,
Mar 26, 2010, 6:05:52 PM3/26/10
to enha...@googlegroups.com
Hi Scott,

This patch looks useful, but it might be missing the use case of being
able to add a block of code to be executed after the fact.
onScriptsLoaded waits until the tests have passed and the other
scripts have been loaded, but I would need to setup the callback at
the site of the first call to enhance()

I think what I'm looking for is something I can call after the initial
call to enhance, e.g to execute some code only if the tests pass only
on one page of my site (not in the base template that loads the
commonly used scripts and css).

so if I could do something like

enhance.onScriptsLoaded(function() {
// do something now that we know it is safe and the other scripts
have been loaded, e.g
$("#dateinput").datepicker();
});

that said, I would only use it while playing around until extracting
it out into its own script and using the forthcoming (hopefully!)
addScripts() function.

Let me know if this makes any sense or if I'm mistaken in any way.

Karl

Karl Rosaen

unread,
Mar 26, 2010, 6:28:25 PM3/26/10
to enha...@googlegroups.com
for perhaps a more realistic use case of adding some javascript
safely, I could imagine using this in conjunction with tornado's UI
modules:

http://www.tornadoweb.org/documentation#ui-modules

where the embedded javascript would guard against whether the page
passed its tests by wrapping its code in enhance.onScriptsLoaded

it may be that I'm asking for something new in addition to
onScriptsLoaded, perhaps named something like 'enhance.enhanced()' and
onScriptsLoaded could remain the callback used as a parameter.

that way, much in the same way where you can use $(document).ready in
jquery from anywhere and know that your code won't execute until the
document is ready, you could call enhance.enhanced from anywhere and
know the callback passed in won't be called until / if the enhance
tests have passed.

Karl

Reply all
Reply to author
Forward
0 new messages