Widgets – Including Specific Javascript on Load

Situation, in brief:

  • I have a /_i/includes/ PHP file, which reads data from LiveWhale, modifies that data to echo into a list, and prints HTML inputs which take user input for a dynamic filter (Isotope) on that list.
  • I have a File widget, which calls the PHP file to print on a page.
  • I have a /_i/includes/ JS file written specifically for the module, which loads Isotope and sets up the triggers and conditions for the filtering behavior.

My instinct is to try and find a way to have this Javascript file only load on a page when the widget is called, but I can’t find an good way to do that.

  • Attempting to echo or print a <script> in the PHP file results in the script tag being stripped from the widget’s output. (A good thing.)
  • Adding the JS file to the widget’s page using the page details custom code section works but isn’t the “add widget and JavaScript comes along” solution sought.
  • I suspect there’s something I could do in modules, or perhaps including the JS in the theme doesn’t have enough of a performance impact to worry about isolating it like this.

Thus, what is the best approach or practice for including widget-specific Javascript?

1 Like

Hi Nick,

This isn’t very often used, but there’s an include_javascript setting that I think might do the trick here: Setting: include_javascript - LiveWhale Support

You can attach it to your saved file widget and I think it should work as intended. Hope this helps!

Karl

I thought that argument existed, but I couldn’t find a reference to it when I did my searches. -_-’

I applied the include_javascript argument inline on the widget and it works as expected. Perfecto, aside from one additional oddity I encountered that I’ll recount for you or anyone following in my footsteps here.


In an effort to avoid inline, I attempted to make a file widget template, given this argument isn’t part of the standard UI.

<widget type="file">
	<title>Majors and Minors List</title>
	<arg id="path">https://www.beloit.edu/_ingredients/includes/majors-minors/majors-minors.php</arg>
	<arg id="include_javascript">https://www.beloit.edu/_ingredients/includes/majors-minors/filtering.js</arg>
</widget>

However, when trying to use the template in LiveWhale, selecting it as the widget template does nothing. It appears that the “Display contents of file located at” field is hard coded to expect user input in the CMS. Of course, putting the file path there kind of defeats the purpose of the template, at its heart.

In hindsight, templating a file include widget is a bit odd under normal circumstances, but it’s the only way to include the include_javascript argument in a non-inline definition, I think?

In the end, I found a hybrid approach which pivots through a profile type central to the included file. A bit roundabout, but it comes with the additional benefit of validating the source data (do we have at least one requirement from Registrar with a valid type?) before trying to call the file.

<widget type="template">
	<title>Majors and Minors List</title>
	<args>
		<arg id="type">Major &amp; Minor Requirements</arg>
		<arg id="min">1</arg>
		<arg id="max">1</arg>
		<arg id="paginate">false</arg>
		<arg id="group">Registrar</arg>
		<arg id="filter" name="profiles_315" action="equals">Major</arg>
		<arg id="filter" name="profiles_315" action="equals">Minor</arg>
		<arg id="filter" name="profiles_315" action="equals">Program</arg>
		<arg id="filter_mode">any</arg>
		<arg id="clean_markup">true</arg>
		<arg id="format"><widget type="file"><arg id="path">https://www.beloit.edu/_ingredients/includes/majors-minors/majors-minors.php</arg></widget></arg>
		<arg id="include_javascript">https://www.beloit.edu/_ingredients/includes/majors-minors/filtering.js</arg>
	</args>
</widget>

(Would prefer to apply to the include_javascript argument to the file widget, but it doesn’t work, somehow. Still, I could apply it to the wrapping profile widget.)

One other option that might simplify things: if you’re already using a file widget and file include, you could actually just put a <script src="/_ingredients/path/to/my/script.js"></script> tag in the file include .html itself? That should load the JS, and LW will usually process that to put it behind the /live/resource/js endpoint.

Hello Karl,

I’m all but certain that I did try that at first, both PHP echo and directly in the HTML. Neither seemed to include the JS at all, showing no effects on the page, errors in console, or code in sources.

I assumed that LW saw those scripts and processed them out, to avoid someone from copy/pasting a suspicious file with malicious JS script for instance.

I may have tried that before I did serious work on timing and the like, so perhaps it was picked up and fired early or another kind of mistiming. Then again, I’d think I would have seen a console message like “Isotope not defined” or similar if that were the case.

Perhaps once dev is sorted out I can poke at it again briefly. Having all the components work from a single file include widget would certainly be ideal.

Thanks,
Nick

Thanks – Hmm, I guess see how it goes re-poking at it on dev and let us know. As long as it’s a relative URL (and not something external that would need to be allowlisted) I don’t think the file include version should be stripped. Or, could have been a self-closing XHTML script tag needed closing? Let us know if you run into more questions about that, thanks.