Where to Put Block JS That's Shared Between View and Edit?

Permalink 1 user found helpful
I might be missing something obvious, but if I have some common JS code - a JS class, for instance - and that code is used both in the block's view as well as when adding/editing a block, how do I reference that code without putting it in two separate places - e.g. in both view.js and auto.js?

-Steve

Shotster
 
Tony replied on at Permalink Reply
Tony
unless there are shared functions, it's best to use two separate files, but if not, try either putting it in the controller's on_start() or __construct() methods
Shotster replied on at Permalink Reply
Shotster
Thanks for the info, Tony. There are indeed common functions. In fact, it's a JS class that's instantiated in both view and edit modes, so it would be redundant and more of a maintenance issue to have it in two separate places.

So am I correct in assuming you're suggesting I use the "helper" methods to include the JS in the doc head?

I'll give it a try...

-Steve
Shotster replied on at Permalink Reply
Shotster
It appears that the add() and edit() methods of a block controller are places to add items to the document head, but I can't figure out how to get a URL to a block from its controller. :-/

Perhaps I should simply resort to JS to do this...

-Steve
jordanlev replied on at Permalink Reply
jordanlev
In case anyone is wondering how to do this in the future: put your common JS code in auto.js, so it will be loaded automatically on the add/edit forms. Then in your controller's on_page_view() function, add this code:
$html = Loader::helper('html');
$bv = new BlockView();
$bv->setBlockObject($this->getBlockObject());
$this->addHeaderItem($html->javascript($bv->getBlockURL() . '/auto.js'));

now it will be outputted in the view as well.

-Jordan
Shotster replied on at Permalink Reply
Shotster
Thanks Jordan!

Your suggestion will be a good solution under most circumstances. What I neglected to mention, however, is that in my particular case, the block is part of a package, and I wish to make the JS available to other developers. (It works in conjunction with a PHP script that resides in the "libraries" directory in the package root.) I decided, therefore, to put the JS inside a "js" directory in the package root so that a developer can load it like so...

$hh = Loader::helper('html');
$this->addHeaderItem( $hh->javascript('pkgscript.min.js', $pkgNam) );

This seems to be the way that shared JS is intended to be referenced when it's part of a package. So instead of requiring developers to load the JS in a "non-standard" way, I decided that I would jump through the hoop instead. So when the block is in edit mode, I add a reference to the script via jQuery like so...

var script_url = <?php echo $this->getBlockURL(); ?> + '/../../js/pkgscript.min.js';
if (!($('head').children('script[href*=' + script_url + ']').length)) {
   $('head').append($('<script>').attr({
      'type'   : 'text/javascript',
      'src'   : script_url
   }));
}

If you know of a better way to go about this, I'd love to hear it.

-Steve
jordanlev replied on at Permalink Reply
jordanlev
Sounds like a good solution to me, although I'd probably prefer to get the URL to the js file in the controller and pass it to the view using $this->set() -- but that's just my style.

-Jordan