1

Seems like this should be a really simple oversight on my part, but I can only find articles dealing with one aspect of this problem, not the combination.

1) I have an index.php page acts as the anchor for the site and additional 'pages' (essentially different content loaded into a container ) are loaded using the javascript below:

$(document).ready(function() {
    $('#content').load('resources/wxCurrent.php');
    // Navigation content load
    $('#navigation a').click(function() {
        var page = $(this).attr('href');                         
        $('#content').load('resources/' + page + '.php');       
        return false;
    });
});

This is working fine.

2) I am looking to execute additional javascript (ultimately Jquery / ajax queries to php pages) on elements defined within the pages called via 1). For testing I have setup a simple form on a php page:

<form name="adminCmdForm" id="adminCmd" method="post" action="resources/admin.php">
<input type="text" name="authcode" placeholder="Auth Code" />
<input type="text" name="command" placeholder="Command" />
<input type="submit" value="runAdminCmd" />
</form>

and can access this form when calling using the javascript in 1). I have then created a simple event handler for the submit event of the form:

$('#adminCmd').submit(function() {  
    alert('1');
});

If I access the php page on which the form resides directly, I can get this event handler to fire and trigger the alert (if I include the tags in the php page).

Issue:- When I use the javascript loader in 1) to call the page and then try to submit the form, the php loads directly and the event handler appears to be not triggered.

I have tried different forms of playing with this - however I acknowledge that my javascript skills are very poor. I am assuming that my event handler needs to change to cater for the fact that the event is firing from within a different object, but cannot even be sure if this is possible.

For Clarity: index.php -> wxInfo.php (contains form) loaded into container div -> form submit -> admin.php

Thanks in advance for any help or direction on relevant documentation / tutorials on this.

MJJ_76a
  • 21
  • 3
  • http://stackoverflow.com/questions/1317080/jquery-ajax-load-java-script-not-executing may help – Mardoxx Sep 11 '14 at 16:16
  • Can you please show the complete html of the loaded page? – iCollect.it Ltd Sep 11 '14 at 16:26
  • 1
    @MJJ_76a: Do you have the binding code wrapped inside a `$(document).ready(){...}` or similar? I'm guessing if the page is loaded asynchronously the code might execute before the content is on the page. -- Another thing to look at is to make sure you don't have more than a single element on the page with `id="adminCmd"` as that causes problems when the script executes as `$('#adminCmd)` will only bind to the first occurrence of an element with the id of `adminCmd`. That's all I can think of. – Nope Sep 11 '14 at 16:31
  • where is the script? In file loaded on main page? Or Within ajax loaded files? – charlietfl Sep 11 '14 at 16:40
  • @Mardoxx - thanks, that article helped – MJJ_76a Sep 11 '14 at 20:04
  • @FrançoisWahl - Whilst I didn't understand what you meant, it did lead me down the right path. Thanks. – MJJ_76a Sep 11 '14 at 21:04
  • @charlietfl - originally I had loaded the script once on the main page. In my answer below these are split out. – MJJ_76a Sep 11 '14 at 21:05
  • just important to understand that if elements don't exist when you apply event handlers, you need to use `event delegation` – charlietfl Sep 11 '14 at 21:19

2 Answers2

1

Thanks to the pointers provided above, I have solved the problem and expanded the function to utilise an ajax call which is working. I had hoped to find a more elegant solution to the issue, so any pointers would be great.

1) index.php file - Contains the main divs and site layout etc with references to query and my own javascript file

2) myNav.js - my own javascript file that contains the following:

$(document).ready(function() {
    $('#content').load('resources/wxCurrent.php');
    // Navigation content load
    $('#navigation a').click(function() {
        var page = $(this).attr('href');
        $('#content').load('resources/' + page + '.php');
        return false;
    });
});

This handles the navigation calls

3) (a)page.php - that contains the form and javascript as follows

<div id="adminInterface">
    <h4>Admin interface</h4>
    <div id="adminCmds">
        <form name="adminCmdForm" id="adminCmd" method="post" action="resources/admin.php">
        <input type="text" name="authcode" placeholder="Auth Code" />
        <input type="text" name="command" placeholder="Command" />
        <input type="submit" value="runAdminCmd" />
        </form>
    </div>
    <h4>Results</h4>
    <div class="adminResponse"></div>
</div>
<script>
$(document).ready(function() {
    $.getScript('scripts/wxInfo.js');
});
</script>

by using the suggested ready() to await the loading of the DOM, then by using .getScript() to call

4) wxInfo.js - Javascript file that contains the event handler for the form:

var res = {
    adminloader: $('<div />', { class: 'loader' }),     
    admincontainer: $('.adminResponse')             
}
// Event Handler 
$('#adminCmd').submit(function() {                              
    $.ajax({                                                
        url: 'resources/admin.php',                 
        beforeSend: function() {                    
            res.admincontainer.append(res.adminloader); 
        },
        success: function(data) {       
            res.admincontainer.html(data);      
            res.admincontainer.find(res.adminloader).remove();
        }
    });
    return false;
});

And this all works fine.

I dont understand why the navigation continued to work regardless of war happened to my event handler - given that this is also driven by javascript, I am failing to understand the difference, probably because I think in server side (php) terms rather than in these event driven constructs

I had wanted to have all javascript for my site within a single js file, however the content.load default event always fires if I use the same js file.

Any suggestions to make this more elegant?

Thanks for the help on this one.

MJJ_76a
  • 21
  • 3
  • 1
    As a side note: While your way seems to work perfectly well you can also make use of the revealing module pattern with namespacing in your js file instead of using `getScript`. You can then call an initialization method or similar on it. You can even pass context to the initialization method, i.e: `yourApp.moduleName.admin.initialize('adminInterface')`. That way, if you happen to load more than one file you have no risk of global namespace pollution and/or accidentally overwriting variables and methods and won't clash with selectors if passing context, etc.. – Nope Sep 12 '14 at 11:45
  • oh an +1 for posting the solution that worked for you, making it useful to future users with similar issues. You should also be able to accept your own answer in a few days. – Nope Sep 12 '14 at 11:47
0

You can use a custom event with the complete callback of the .load() function.

Think in the following, you can only run yours scripts after the new HTML you're inserting at the page is completed loaded in inserted at the DOM, think in this like jquery .ready event for you content.

In the "resources/page.php" you change your scripts to use the custom event, lets name it contentready:

<script>
$(document).one('contentready', function(){
$('#adminCmd').submit(function() {  
    alert('1');
});
});
</script>

Then you change your main page load content code a bit:

   $('#navigation a').click(function() {
        var page = $(this).attr('href');                         
        $('#content').load('resources/' + page + '.php', function(){
               //trigger your customer event now that your HTML is loaded in the page
              $(document).trigger('contentready');
        });       
        return false;
    });

This way your new event handler will only be attached when the new HTML is complete loaded into the page DOM.

Luizgrs
  • 4,765
  • 1
  • 22
  • 28
  • thanks for the pointers and suggested code. This did partially work, however a point to note is that the return false in the content loader needed to move else the standard event still fires. This did not resolve the problem but was of great help. Will post solution that I have found below. – MJJ_76a Sep 11 '14 at 20:10