Reputation: 113
First, my apologies to anyone who reads this. I've run into a fair number of JS issues, and this is the most intractable I've ever seen. I'll do my best to give a clear description, but I may have to revise it.
I have the following page loading within an inline frame in SugarCRM:
<head>
<link rel="stylesheet" href="style/style.css" />
</head>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="js/index_controller.js"></script>
<table class="form_text" style="width: 100%; height: 100%;" cellpadding="5">
<tr>
<td><iframe id="map_frame"
style="width: 100%; height: 100%; overflow-y: hidden; border: solid 1px #DDDDDD"
scrolling="no"
src="map.php?<?php
foreach ( $_REQUEST as $key => $value ) {
echo $key . "=" . $value . "&";
}?>"></iframe>
</td>
...
</td>
</tr>
</table>
</div>
<script type="text/javascript">
parent.$("iframe").each(function(iel, el) {
if(el.contentWindow === window) {
var to_remove = $(el).parent().prev();
$(to_remove).remove();
$(el).css("border", "none");
}
});
$(document).ready(function(){
updateMap();
});
</script>
</body>
And in the iframe in that page, I have this:
<head>
<link rel="stylesheet" href="style/style.css" />
<!--[if lte IE 8]>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.ie.css" />
<!--[endif]-->
<link rel="stylesheet"
href="http://cdn.leafletjs.com/leaflet-0.4/leaflet.css" />
<script src="js/jquery-1.9.1.js"></script>
</head>
<body>
<script type="text/javascript" src="../include/DashletContainer/Containers/DCMenu.js"> </script>
<script type="text/javascript" src="js/arrayList.js"></script>
<script type="text/javascript" src="js/custom_map_controls.js"></script>
<div id="map" style="height: 100%"></div>
<form action="../index.php" method="post" name="DetailView"
id="formDetailView">
<input type="hidden" name="module" value=""> <input type="hidden"
name="record" value=""> <input type="hidden" name="return_action"> <input
type="hidden" name="return_module"> <input type="hidden"
name="return_id"> <input type="hidden" name="module_tab"> <input
type="hidden" name="isDuplicate" value="false"> <input type="hidden"
name="offset" value="1"> <input type="hidden" name="action"
value="EditView"> <input type="hidden" name="sugar_body_only"> <input
type="hidden" name="prospect_id" value="">
</form>
<script type="text/javascript" src="js/map_icons.js"></script>
<script type="text/javascript" src="js/map_controller.js"></script>
<script src="js/leaflet-0.4.5.js"></script>
</body>
the leaflet-0.4.5.js
script, when evaluated, creates a globally available object known as L, which gives access to all the Leaflet mapping framework's functions. In my map_controller.js, I add some special features to L.Map, the function for creating the actual map objects. This works fine in Chrome, and it works fine in Firefox when I load the page directly in a browser tab. But when I load it as intended, in a SugarCRM page inside an inline frame, I get the error "L.insert function name here is not defined" in the JS console. If I refresh just the iframe without reloading the entire SugarCRM page, the map then appears as expected. I'm working around this now by catching the exception and forcing the page to reload when it occurs, but I'd really like to know why this is happening in the first place. I've rewritten the map controller so all the functions that use L are contained inside a $(document).ready() function (using jQuery for that) and tried putting the leaflet script tag at the top of the body on the page where it's supposed to load, and still no luck.
Upvotes: 1
Views: 432
Reputation: 35074
Your problem is using $(document).ready
on the parent page.
That will run as soon as the HTML parser is done parsing the parent. But it's then reaching inside the iframe and depending on various scripts inside the iframe having been loaded, which they may well not be at that point yet. It's a race between the HTTP response for the toplevel page and the HTTP responses for the scripts in the subframe, basically.
The right way to do this is to run the initialization from onload or at least from a point where DOMContentLoaded (which is what $(document).ready
hooks into) has fired on the child.
Upvotes: 1