Reputation: 7895
I am loading another page into an el
via XHR
. The loaded page has js on it that throws an error and fails unless the required dom element is loaded on the page. As it's XHR .ready
et. al. won't work.
I have it working with a 500 ms timeout, but that's not OK; there has to be a better way. With timeout, the dom el doesn't always load and the page fails.
There is a table hard-coded on the page with an id
. The script in the page is a jquery plugin (datatables) and won't init unless the table is loaded.
I've thought about having a function that inits the datatables stuff and calling that repeatedly while
$('#tableID')
is null
but not sure that's correct.
<div id="contactQueue">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="contactsQueueTable">
<thead>
<tr>
<th class="" rowspan="1" colspan="1" style="width: 185px; ">Contact Name</th>
<th class="" rowspan="1" colspan="1" style="width: 148px; ">Bus. Name</th>
<th class="" rowspan="1" colspan="1" style="width: 116px; ">Is Client</th>
<th class="" rowspan="1" colspan="1" style="width: 165px; ">Remove</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<?php echo form_open('',array('id'=>'step2form','name'=>'step2form'));?>
<input type="hidden" name="clientID" value="<?php echo $clientID; ?>">
<?php echo form_close();?>
<script type="text/javascript" charset="utf-8">
console.log(jq('#currentContactsTable'))
while(jq('#currentContactsTable').html()==null){
initXHRPage();
console.log(jq('#currentContactsTable')+' not ready');
}
function initXHRPage(){
//init tables stuffs
}
EDIT;
The issue was something else, kinda. The script for Datatables is being loaded via getScript()
. The element was being loaded normally, but initDatatables()
was firing before getScript()
was done loading, not before the el was loaded.
The solution was to call the initDatatables()
function in the getScript()
success callback:
<script type="text/javascript" charset="utf-8">
var jsf = '/js/jquery.dataTables.js';
jq.getScript(jsf, function(data, textStatus){
console.log('Loaded:'+jsf+" From: <?php echo $this->uri->uri_string(); ?>");
initDatatable();
});
</script>
Upvotes: 0
Views: 1978
Reputation: 7895
This is what I came up with. Thx to respondents for help.
initPage();
function initPage(){
if(jq('#currentContactsTable').length==1){
initDatatable();
}else{
window.setTimeout(function(){
initPage();
},250);
}
}
function initDatatable(){
jq('#currentContactsTable').dataTable( {
//REST OF DATATABLE STUFF...
It may not be super pretty as it still is relying on a timeout, but at least this timeout it a bit more robust...
^^^^ BZZZZZZZZZ
The issue was something else, kinda. The script for Datatables is being loaded via getScript(). The element was being loaded normally, but initDatatables() was firing before getScript() was done loading, not before the el was loaded.
The solution was to call the initDatatables() function in the getScript() success callback:
<script type="text/javascript" charset="utf-8">
var jsf = '/js/jquery.dataTables.js';
jq.getScript(jsf, function(data, textStatus){
console.log('Loaded:'+jsf+" From: <?php echo $this->uri->uri_string(); ?>");
initDatatable();
});
</script>
Upvotes: 0
Reputation: 26633
Have you tried $(el).ready(...)
? That certainly ought to work. If it isn't, something else is going wrong.
Sorry, that should have been $("#your_xhr_loaded_content").ready()...
.
I do this type of thing all the time and it works, I think the key is that I am loading a document.
Main HTML document, index.html:
...
<body>
...
<div id="activity_content">
</div>
...
<script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
main.js:
...
function ruleManagement.loadContent() {
$.ajax({
url: "subdocs/ruleMgmt.html",
cache: false,
success: function(html) {
$("#activity_content").html(html);
}
}
}
ruleManagement.onReady = function(event) {
// Init contents of the rule_management_pane
...
}
HTML Sub-Document, ruleMgmt.html
<div id="rule_management_pane">
<!-- Content here -->
...
</div>
<script type="text/javascript" language="JavaScript">
jQuery("#rule_management_pane").ready(ruleManagement.onReady);
</script>
If I invoke ruleManagement.loadContent()
, then ruleManagement.onReady()
is called after div#rule_management_pane has been successfully loaded. I cannot say for sure that onReady is invoked before div#rule_management_pane is inserted into #activity_content, but I think that is the case.
Upvotes: 2
Reputation: 6011
how I understand your html/js is getting loaded:
rough. ok, here is what i think you need:
<html>
<!---CONTAINER PAGE--->
<head>
<script type="text/javascript">
//this .ready is to register events we need to catch the '#currentContactsTable' load event
$(document).ready(function(){
//ajaxSuccess is a global ajax function, you need to check ajaxOptions object to ensure you have the correct 'ajaxSuccess' you thought you did.
$.ajaxSuccess(function(event, XMLHttpRequest, ajaxOptions){
if (ajaxOptions.url == '/ajax/getCurrentContactsTable.php') {
$('#currentContactsTable').trigger('initDataTables');
}
});
// .live() does not need the element to exist on document.ready()
$('#currentContactsTable').live('initDataTables', function(event){
var dataTables = $(this).datatables({options:here});
});
});
</script>
</head>
<body></body>
</html>
Upvotes: 1