/**
*
* Lazy Programmer's function to register the javascript needed and display HTML
* map container
* @param array $afterInit -javascript code to be rendered after init call
* @param string $language -preferred language setting for the results
* @param string $region -top level geographic domain
* @param ClientScript::CONSTANT $position -where to render the script
*/
public function renderMap( $afterInit=array(), $language = null, $region = null, $position = CClientScript::POS_LOAD ){
$this->registerMapScript( $afterInit, $language, $region, $position );
ob_start();
ob_implicit_flush(false);
echo $this->getContainer();
echo ob_get_clean();
}
here is the function getContainer
/**
* returns the Html for the Google map container
* @param Array $options Style options of the HTML container
* @return string $container
* @since 2010-12-22 Yii modified Antonio Ramirez
*/
public function getContainer($styles=array(),$attributes=array())
{
$options = array_merge($this->_htmlOptions, array('id'=>$this->getContainerId()));
if(!isset($options['style'])) $options['style'] = '';
foreach($this->_styleOptions as $style=>$value)
{
$options['style'] .= $style.':'.$value.';';
}
return CHtml::tag('div', $options);
}
The registration of the Javascript code works as expected, but when I try to render the container, it doesnt at all. In order to render two maps, I had to render them from the view and only use registerMapScript according to a map ID.
The object is not an extended Component nor a Widget. It is an object, that is all.
It just renders the first MAP, and if i put ob_clean() it renders the second.
Yeah I know it prevents any code to be echo’ed, and I did that before the layer is rendered, then the first MAP I try to render works, but the second time I try to render another Map with a different object it doesnt.
If I use ob_clean(); at the end, it does return the second Map, so I know I am doing something really wrong in between.
Doesnt work… I am open for suggestions… Do I have to create a widget instead?? I had the same problem with other extension I had and same thing… How do I render contents from a class more than once?
The problem it is not within the JS code as I do have different INIT functions for different Objects. The classes work great IF I WRITE HTML CODE on the view manually. Lets say
<div id="map1"></div>
<div id="map2"></div>
Works great… but why I cannot render those layers from the class? nevertheless, I will double check with js code.
No, not really. I had a look at my previous experiment. Actually the static html-only call works just fine if rendered via multiple calls to renderPartial().
It was the GMap extension widget I couldn’t place in a partial view (separate id’s).
(I went on and tried the GMapMultiplot extension but it didn’t work at all for me, in a quick test.)
Downloaded your EGMap extension from the Yii site. No problem to display two maps in a page using your example code. Will have to try the ‘lazy’ function later.
So no more clues at the moment.
Edit:
Just want to add that I’m not the creator of the extensions mentioned, just tried using them yesterday (and last year). Parenthesis added to slightly irrelevant text about GMapMultiplot. BTW it probably works with Yii 1.0.
It seems it is happening in most of the extensions that we create. Check the following comment from my blog:
thank you very much for this great widget and for share your modifications on it …
I really would like to fix these issues and at least write a wiki. I believe this pitfall is happening to a lot of people. I try to contact somebody from development team, but no one has answered to this question yet, or at least clarify what is the reason in order to code a workaround.
In the meantime I will keep reading the code of Yii but it seems that I do what is correct. I was wondering that if as a widget will work but as you can see on the comment above isnt working either.
If anybody could help on this, will also help the community to develop better extensions.
Found a solution to the problem but has nothing to do with the use ob_… At the end I had to find a Javascript solution and integrate it with the maps. Now you will be able to render as many Maps on the page as wanted with just a simple call: renderMap.
In the meantime I checked your extension and found something… Maybe you already figured this, but it’s not bad to mention it
The DIV container is rendered wrongly… like <div … /> instead of <div …></div>
So in the getContainer the line
return CHtml::tag('div', $options);
should be
return CHtml::tag('div', $options,'',true);
And note that first parameter when creating a new object is the name of the init function… if you want two maps or more… those names MUST be different…
so this works for me (but only with the DIV error (above) fixed)
Thanks! Damn man… I already rewrote! It was that easy? The closing of a tag? Even though I fixed it through JS I will try that my self… gotta see this with my own eyes.
My solution is through Javascript (again)
This is why Iike so much this framework… its support is superb!
About the names, they are all controlled by an autogenerated Id with an static counter. So conflict names only occur by wrongly using setContainerId
I tried the old code with the closing of the tag and it works… nevertheless, the issue made me think about a better approach and functionality, and I have already updated the code. Thank you very much mdomba, that wasn’t easy to catch. I see if the other widgets have the same problem.
EDIT:
I already fixed the INIT JS_FUNCTION before the post. It is all automated as the ID.