Jump to content

Problem with injecting custom JS to admin (jQuery is not defined)


teppo
 Share

Recommended Posts

Like the title says, I'm trying to inject my own little JS file into certain admin views and the problem is that jQuery gets loaded after my custom JS file -- in fact $this->config->scripts seems to be null at the init phase of my module. I've confirmed this by taking a look at markup of rendered page also; custom script is the first one added (even before jQuery) and thus won't work properly.

The funny thing here is that (after getting same error while trying to hack this up myself) I tried doing exactly what Ryan mentioned here, and I'm still getting exactly the same problem. Is it possible that something has changed since then, or is it just me doing something wrong?

Any help would be highly appreciated!

Link to comment
Share on other sites

Soma: in my test case I'm using the code slkwrm has at the first post from the thread I linked to, but with addLinks() removed and code from Ryan's post included in init() method.

Execute functions only apply to process modules, right? Since this isn't a process module, I'm not so sure that they're what's missing here. To be honest this problem probably is quite easy to work around by simply adding the script right before </head> in rendered markup, but the method posted in that thread looks so much cleaner that I'd rather do it that way :)

Edit: replaced aforementioned method with simple replace hooked after Page::render, which essentially gives the result I need here. Still, the original problem remains unclear. At least to me :)

Edited by teppo
Link to comment
Share on other sites

I don't mean "execute" function literally, just a hook or function that is added to a hook or process in the system or called directly somewhere. Adding script alone in the init on a autload module will always append it before jquery core.

The code example on that link does have a hook with with a addLink function. This will get processed at a certain point where jquery core and likely other script are already appended.

If you give us more example of what you are doing I can help.

The code Ryan posted, is how the ModuleJS does it, but as I recently found out, doing it the same way in your module init, will add it before jquery core always, so you can't use ModuleJS.

Look at the extensive thread I created also about the same subject here

  • Like 2
Link to comment
Share on other sites

I don't mean "execute" function literally, just a hook or function that is added to a hook or process in the system or called directly somewhere. Adding script alone in the init on a autload module will always append it before jquery core.

Sorry, my mistake for taking things too literally :)

The code example on that link does have a hook with with a addLink function. This will get processed at a certain point where jquery core and likely other script are already appended.

Yeah, first post does. But later when asked about the best way to inject JS into admin Ryan provided an answer where scripts get added to $this->config->scripts at init(), which is why I ended up with a combination of these two. Guess I was misunderstanding what that example really meant. Still kind of confused about this, especially since the question there was (quoting) "Also wanted to ask what is the best way to inject javascript in admin pages".. exactly what I'm trying to do here :)

If you give us more example of what you are doing I can help.

I just wanted to know if it was possible to inject scripts into admin views through $this->config->scripts at the init() method of my own module, without utilizing any hooks. Like I've mentioned above, I've solved this with a hook already, but that's just not nearly as pretty as adding them to scripts would be.

The code Ryan posted, is how the ModuleJS does it, but as I recently found out, doing it the same way in your module init, will add it before jquery core always, so you can't use ModuleJS.

Look at the extensive thread I created also about the same subject here http://processwire.c...er-jquery-core/

I had a closer look at that thread, and this answer by Ryan pretty much explains what's happening here (quoting): "it's feasible that an autoload Process module could load before JqueryCore." My module isn't a process module, but I guess same still applies here -- and that would essentially mean that the answer to my first question is "you can't do that." Which is a shame, but I can live with that.

Anyway, thanks for your time, this has once again been interesting :)

Link to comment
Share on other sites

I just wanted to know if it was possible to inject scripts into admin views through $this->config->scripts at the init() method of my own module, without utilizing any hooks. Like I've mentioned above, I've solved this with a hook already, but that's just not nearly as pretty as adding them to scripts would be.

Have you tried ready() method?

Link to comment
Share on other sites

Have you tried ready() method?

Now I have. Same effect.

Also, just realized that if I was doing this by extending ModuleJS there wouldn't really be any need for custom code at init() -- just calling parent::init() would be enough. But then again, ModuleJS clearly isn't supposed to be autoload, which (I think) is a requirement in this case, so I guess that's out of the question anyway.

The more I think about this the more I believe that what I originally asked just isn't possible, not the way I was trying to do it at least. So I'm guessing I had to misunderstand that post I quoted before and this really has to be done with a hook.

Link to comment
Share on other sites

Apeisa, also wanted to mention it.

A process module usually isnt autoload and loads scripts with same classname automatic, but i'm also confused everytime i want to add scripts and it gets appended before jquery hence my 1001 post about this subject.

Link to comment
Share on other sites

So u are having a ModuleJS? What if u don't make it autoload but permanent? So u dont have to install it, but maybe get loaded after.

Well I also gave up after so many tries and use hook on somerhing to add script after jquery or after certain other module.

Also as u wrote u want to add scripts on certain admin pages, u would anyway need some hook to determine when to do it. Sorry for triple post.. on mobile

  • Like 1
Link to comment
Share on other sites

Soma: I think you're right there. Should've thought this through before even asking, but.. at this point I'm also tempted to say that hooks look like the only possible answer to this particular problem :)

Link to comment
Share on other sites

It's not a good idea for 'autoload' to be the only condition necessary to add script or css/style files. That's because some (including me) use things like $config->scripts and $config->styles on the front-end of sites, and don't want it to be populated with files irrelevant to my site. Furthermore, we can't assume that we always know what ProcessWire is being used for (it might not have anything to do with HTML), so it's just taking up extra memory if some autoload module is populating filenames when they won't ever be used. This is why none of PW's modules that deal with script/style files are autoload, and also why Process and ModuleJS module interfaces are not autoload. Process modules are on-demand, but if you have a Process module that you've made autoload, then you'd want to manually load any script/style files in the relevant execute() method -- this ensures they won't get loaded unless they'll actually be used. The ModuleJS class is different, as it's really not intended to be autoload at all, so there's not really any use in combining ModuleJS with autoload.

The whole idea of javascript or css is specific to a runtime and on-demand context. And this is how it's happening in the admin template, as it is what ultimately triggers the JqueryCore and JqueryUI libraries to be loaded. And this is the time that they get placed into the $config->scripts array. So we'd just have to find some way to hook after that takes place, but before the markup of the page is generated. I think this may work for an autoload module:

public function ready() {
 if($this->page->template == 'admin') 
   $this->addHookBefore('ProcessController::execute', $this, 'hookExecute'); 
}

public function hookExecute(HookEvent $event) {
 $this->config->scripts->add(' your script file '); 
}
  • Like 2
Link to comment
Share on other sites

  • 1 month later...
  • 1 year later...

i'm trying to make a simple module to add various scripts to the page editor in the admin, for different templates.

class customAdminScripts extends WireData implements Module {

	public static function getModuleInfo() {
		return array(
			'title' => 'Custom Admin Scripts', 
			'version' => 100, 
			'summary' => 'A module to inject custom javascripts.',
			'href' => 'http://www.processwire.com',
			'singular' => true, 
			'autoload' => true, 
			//'autoload' => "template=camp",
			);
	}

	public function init() {
		$this->addHookAfter('ProcessPageEdit::execute', $this, 'addAdminScripts');
	}

	public function addAdminScripts(){	
		//if($page->template != 'camp') return;
		$this->config->scripts->add($this->config->urls->customAdminScripts . "customAdmin.js");
	}

}

how would i set this up so that i could add specific scripts to certain templates - right now i can only get it to work how it is now, loading on all templates

Link to comment
Share on other sites

Hey Macrura, if I understand correctly, this module is working on the Admin, so you need to get the template of the page that is being edited. If you do $page->template / wire('page')->template, it won't work, because this will be the template of the "Edit" page, which will be the admin template.

What you need to do is something like this:

$page_id = (int) wire('input')->get('id');
$edited_page = wire('pages')->get($page_id);

if($edited_page->template != 'camp') return;

I think that should do the trick!

  • Like 3
Link to comment
Share on other sites

right - thanks - i'll look at how you did the save alert module, should be able to figure it out;

also i wonder if there is a place where could be stored a collection of utility modules for devs;

basically they wouldn't do anything out of the box but provide infrastructures for building stuff - so you would have to edit the code for your use, rename etc..

examples would be modules that auto-build URLs for certain templates, add js or css to admin screens, auto-add new pages without having to name them first; these are some things i'm using on a current site, and that i've seen a lot of posts related to; but there's really not centralized place where they are available...

i guess they could be in modules directory as proof of concept or building blocks, with a disclaimer that they don't work without modification and shouldn't be installed on a live site..

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...