Issues with dynamically adding add-ons after load

Hello,

I have a project I’m working on that creates multiple cm instances. On initial load, CM is loaded and works great. Afterwards an ajax call pulls the necessary add-on js/css resources and loads them.

These files get pulled fine, and I ensured that the js script is executed.

Still, I see no result. (ex: Match brackets and lang highlighting via mode don’t work even though mode is definitely set and match brackets option is set to true).

So, I figured maybe the editor just needs to call refresh! However that didn’t do anything for me either. I even tried to do it manually in console just to check ( $(’.CodeMirror’)[0].CodeMirror.refresh() ) which results in ‘undefined’, and the editor there is definitely the correct/valid editor.

So I have no idea how to get this to work right and it’s driving me crazy.

This is how I have tried refreshing:

 $('.CodeMirror').each(function(idx, el){
 	console.log('cm instance: ', el); 
 	el.CodeMirror.refresh();
 });

for(var i = 0; i < structure.count; i++)
{
	console.log('cm instance: ', $('.CodeMirror')[i].CodeMirror); 
	$('.CodeMirror')[i].CodeMirror.refresh();
}

Here is an album of relevant? images.

It’s also worth noting that when I explicitly hardcoded the scripts on the client side it worked ok. However, I need to be dynamically serving these files.

I’m using CM 5.12.

Any thoughts?

Have you tried re-setting the relevant option with setOption? If the option initially didn’t exist, it’ll be ignored, and the editor won’t notice that it gets defined later on.

Didn’t seem to help… Assuming I understand you right, after all resources are loaded and editors init’d, I essentially tried:

var cm = $('.CodeMirror')[i].CodeMirror; 
cm.setOption('matchBrackets', true);
cm.setOption('autoRefresh', true);
cm.setOption('mode', mode[i]);
cm.refresh();

but to no effect.

Thanks for the quick response/help!

Oh, there’s a check that ignores setOption when the value is equal to the old value. So for now, you’ll have to first set these to something else, and then update them again with their intended value.

Hm, so I set those options to false, refresh, then set them back to true and refresh (two separate fors just to be extra sure haha). Still seeing the same result sadly.

Initializing editors without those settings and then using setOption after everything is loaded still doesn’t show any results either.

I just ran this code on the demo on the webpage, and it turned the editor purple. So it might be that your problem is elsewhere.

CodeMirror.defineOption("bg", null, function(cm, val) {
  cm.display.wrapper.style.background = val
})
editor.setOption("bg", "purple")

One possibility is that the way you’re loading the addon is causing it to load a separate CodeMirror module from the one your editor is using, and register its options there. Thus, your editor won’t see it. Add a console.log to the top of codemirror.js to find out how often it is being loaded.

Okay so cm.js is called only once. I also added your color check and that worked and turned all the editors purple! How frustrating!! As you have said, my problem most likely lies elsewhere at this point…

Part of why I load some add-ons afterward is because codemirror.js itself is being served first (not hardcoded with script tag). Initially when I tried loading them sequentially, I got errors regarding codemirror not being undefined which led me to staggering the load (cm first then add-ons at the next stage)

Could this be the problem?

Thanks for all your help!!

The addons all register themselves with the codemirror.js module, so you have to load that first. But I don’t see a reason to initialize the editor before loading the addons.

I realized I forgot to post a reply here. I’ve run out of time and had to work around that feature. Not the end of the world really.

Thanks for taking the time to try and help me out marijn! You’re awesome!