Re. C5-8.3: How to add js script for adding a block?
Permalink
I use:
to add the script in the header for the block. But when I just installed the package and want to add my block, the script doesn't run, I can't find it in the header. If I paste that into the add(), it still doesn't work.
How can I load it for adding the block for the first time?
Thank you.
public function on_page_view() { $html = $this->app->make('helper/html'); $this->addHeaderItem($html->javascript('https://api-maps.yandex.ru/2.1/?lang=ru_RU')); }
to add the script in the header for the block. But when I just installed the package and want to add my block, the script doesn't run, I can't find it in the header. If I paste that into the add(), it still doesn't work.
How can I load it for adding the block for the first time?
Thank you.
I tried this:
but it doesn't work, still tells me the variable from the remote script is not defined.
I added $this->requireAsset('javascript', 'yandex-maps'); to the add() - no difference.
public function on_start() { $this->set('app', $this->app); $al = \Concrete\Core\Asset\AssetList::getInstance(); $al->register( 'javascript', 'yandex-maps', 'https://api-maps.yandex.ru/2.1/?lang=ru_RU', array( 'position' => \Concrete\Core\Asset\Asset::ASSET_POSITION_HEADER, 'local' => false ) ); $this->requireAsset('javascript', 'yandex-maps'); }
but it doesn't work, still tells me the variable from the remote script is not defined.
I added $this->requireAsset('javascript', 'yandex-maps'); to the add() - no difference.
I've checked the page source, that script doesn't get added to the header
The script is on another server? I don't think you can register a remote script, I think it needs to be on your server. You might need to do something like:
But I might not be right about that, I usually put the script in my package directory and not use remote scripts
$this->addHeaderItem('<script type="text/javascript" src="https://api-maps.yandex.ru/2.1/?lang=ru_RU"></script>');
But I might not be right about that, I usually put the script in my package directory and not use remote scripts
Yes, it's on the remote server.
I've already tried that, it doesn't work either. That works for view, but that doesn't work for add.
The thing is if I go to that address, Firefox asks me to save a json.txt, it's not a .js file. I don't know how it works.
I've already tried that, it doesn't work either. That works for view, but that doesn't work for add.
The thing is if I go to that address, Firefox asks me to save a json.txt, it's not a .js file. I don't know how it works.
if a remote script can't be registered, how can I load it in the add block form? Having a <script> tag with that source doesn't work.
Some of my older blocks have 'CONTROLLER' included in the addHeaderItem,I don't remember the significance of that, but give it a try.
Did you try putting the addHeaderItem in the controller add() function? It's just a guess but I would give that a try too.
Did you try putting the addHeaderItem in the controller add() function? It's just a guess but I would give that a try too.
$this->addHeaderItem('<script type="text/javascript" src="https://api-maps.yandex.ru/2.1/?lang=ru_RU"></script>','CONTROLLER');
Yep, tried both, doesn't show up in the header.
Also tried auto.js with:
Also tried auto.js with:
(function () { $('body').append('<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"'); });
Why doesn't including
in the form.php work either? Shouldn't the script load in any case?
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
in the form.php work either? Shouldn't the script load in any case?
it looks like there might be a problem with the script itslef and/or its host. Do you get any other error message in the console?
I tried both your first and second solution
and
And they both worked.
You might have other problems in your code
$this->addHeaderItem($html->javascript('https://api-maps.yandex.ru/2.1/?lang=ru_RU'));
and
$al->register( 'javascript', 'yandex-maps', 'https://api-maps.yandex.ru/2.1/?lang=ru_RU', array( 'position' => Asset::ASSET_POSITION_HEADER, 'local' => false ) ); $this->requireAsset('javascript', 'yandex-maps');
And they both worked.
You might have other problems in your code
They do work perfectly well anywhere BUT during adding the block. The script loads a class 'ymaps' and the console tells me the class name is not found. But this only happens during adding the block for the first time. When the block is added (trying twice to add it, ignoring errors) or in the view.php - everything works fine.
I can't figure out how to make the script load during the add.
I can't figure out how to make the script load during the add.
Care to share your code?
@mnakalay, I've sent you a PM with my package
Yes I saw that and the problem is weird. I don't understand why C5 doesn't add the script to the header unless you do it in edit or add function. I'm still thinking about it.
It adds the script in edit but NOT in add - that's the problem
This is what I did and it seems to work.
First, remove all the code you have that tries to load the script. You're not going to use it. And that means in the controller and in the form.php. All of it.
You're going to load the script through JS and then listen to loading event to trigger the call.
In form.php, at the beginning of your JS, add this
When you add your block, it will take a few seconds for the map to appear so you migh want to implement a spinner or a "please wait" message or something.
First, remove all the code you have that tries to load the script. You're not going to use it. And that means in the controller and in the form.php. All of it.
You're going to load the script through JS and then listen to loading event to trigger the call.
In form.php, at the beginning of your JS, add this
loadScript('https://api-maps.yandex.ru/2.1/?lang=ru_RU', function(){ ymaps.ready(init) }); function loadScript(url, callback){ var script = document.createElement('script'); script.type = 'text/javascript'; script.setAttribute('src', url); script.onreadystatechange = callback; script.onload = callback; var head = document.getElementsByTagName('head')[0]; head.appendChild(script, head); }
When you add your block, it will take a few seconds for the map to appear so you migh want to implement a spinner or a "please wait" message or something.
There is a core js method ccm_addHeaderItem for loading a script (or css) from js.
Does pretty much the same as above (not as sophisticated as jQuery script loader);
Does pretty much the same as above (not as sophisticated as jQuery script loader);
@mnakalay, I've removed all script loading code from everywhere and added your code to the form.php. Now the add block form pops up, map controls load but the map itself doesn't, and on hovering it multiplies hundreds of js errors.
I've also tried and added this to the form.php instead:
and I still have the same error as before - the script doesn't load
I've also tried and added this to the form.php instead:
<script type="text/javascript"> ccm_addHeaderItem("https://api-maps.yandex.ru/2.1/?lang=ru_RU", "JAVASCRIPT");</script>
and I still have the same error as before - the script doesn't load
I use script assets in add/edit dialogs in many places with no issues between add and edit.
I don't have time to heIp directly at the moment. For now, a wild speculation - could it be browser security on same-source for scripts? See what happens if you use the same code to load a script from the site rather than a cdn.
I don't have time to heIp directly at the moment. For now, a wild speculation - could it be browser security on same-source for scripts? See what happens if you use the same code to load a script from the site rather than a cdn.
As I mentioned before, the script and whole map load fine in the edit and view. But that's only after the block is added. The script doesn't load nor does the map during the add.
So, basically if I try to add the block, the form doesn't even pop up and I see a js error in the console saying the 'ymaps' is unknown. If I ignore this and add the block again, this time the form pops up but the map is empty (doesn't load obviously, same js error), but I press to save, reload the page and now the map is displayed and if I go to edit the block everything works just fine.
So the issue is only with ADDING the block.
So, basically if I try to add the block, the form doesn't even pop up and I see a js error in the console saying the 'ymaps' is unknown. If I ignore this and add the block again, this time the form pops up but the map is empty (doesn't load obviously, same js error), but I press to save, reload the page and now the map is displayed and if I go to edit the block everything works just fine.
So the issue is only with ADDING the block.
The map seemed to load on block add using my solution. Did that fail for you too?
Yes, that fails to load the map. It loads the form controls but not the map.
I've cleared the form and only left these:
That opens the form but doesn't load the map.
<?php defined('C5_EXECUTE') or die("Access Denied."); ?> <style> #yandex_map { height: 300px; width: auto; } </style> <fieldset> <div class="col-xs-12"> <div class="form-group"> <div id="block_note" class="alert alert-info" role="alert"> <?php echo t('Click on map to set location'); ?> </div> <div id="yandex_map"></div>
Viewing 15 lines of 41 lines. View entire code block.
That opens the form but doesn't load the map.
Well, I don't know what to say, it works for me, on block add.
The only thing I had to modify was to give latitude and longitude default values or else the map would appear but would throw an error because the center was empty.
I'm sending you the package I modified by PM.
The only thing I had to modify was to give latitude and longitude default values or else the map would appear but would throw an error because the center was empty.
I'm sending you the package I modified by PM.
Well, I'm puzzled then. I've just replaced my form with yours and all I got is just a gray rectangle (see attached pic) with hundreds of js errors in the console if I hover over it
I just sent you a video showing you it works on my computer so there's some kind of wizardry at play here...
And what you are showing in that screenshot is what I first got before I gave $latitude and $longitude default values (check at the top of form.php what I added)
Oh, geeeeez, I've copied all but the first php bit. Now it works!!!
And I've just realized I forgot to set those 2 values in the add().
Thank you very very much for your help! It was driving me nuts.
I guess I can submit my package now )))
And I've just realized I forgot to set those 2 values in the add().
Thank you very very much for your help! It was driving me nuts.
I guess I can submit my package now )))
that's the paradox of the PRB. If you had asked this over there we would have said "It is up to you to solve this problem and make it work, we're not here to fix your code for you"
But then in the forum, you get help from the same people... :-)
Naaahhh! I'm joking, I would have helped in the PRB as well because it was an interesting problem that I was curious to fix.
Having said so I strongly suggest you look a little more at your code and clean it up and make sure all your defaults are set and everything is peachy before submitting.
But then in the forum, you get help from the same people... :-)
Naaahhh! I'm joking, I would have helped in the PRB as well because it was an interesting problem that I was curious to fix.
Having said so I strongly suggest you look a little more at your code and clean it up and make sure all your defaults are set and everything is peachy before submitting.
https://documentation.concrete5.org/developers/assets/registering-an...
For blocks, also look at the registerViewAssets() method for requiring assets (terminology is a bit confusing).