views:

51

answers:

2

I've written a little Ajax-y page, that displays data rows from an ajax request. Each row has a "delete link" to allow the user to delete the row quickly, also via ajax.

My problem is one with the scope of the function--

The "main" page has a function that looks like this:

<script language="javascript" type="text/javascript">
window.addEvent('domready', function() {

    function getRows(){
        var myurl = 'myajaxurl.php';
            var req = new Request({
            async:false,
            method: 'get',
            url: myurl,
            data: {'id':'<?php echo $id; ?>'},
            evalScripts:true,
            onSuccess: function(response) {
                $('my_rows_div').set('html',response);
            }
        }).send();
    }

    function deleteRow(rowid){
        alert(rowid);
    }
});    

The data being returned by the 'getRows' function is just some html rows, and it looks like this:

<tr><td>data</td><td><a onclick="deleteRow(1)" href="javascript:void(0);">delete</a></td></tr>
<tr><td>data</td><td><a onclick="deleteRow(2)" href="javascript:void(0);">delete</a></td></tr>

So far so good-- but when I render the page and click the "delete" link, I get the js error that "deleteRow is not defined".

I know this probably has something to do with scope, but I don't quite understand how this works. How can I reference the "parent" page's deleteRow function from within the returned ajax data?

Thanks!

+4  A: 

The "global scope" of a page is the "window" object. When you add event handlers from HTML attributes, the global scope is used by default. Do this:

<script language="javascript" type="text/javascript">
window.addEvent('domready', function() {

function getRows(){
        var myurl = 'myajaxurl.php';
            var req = new Request({
            async:false,
            method: 'get',
            url: myurl,
            data: {'id':'<?php echo $id; ?>'},
            evalScripts:true,
            onSuccess: function(response) {
                $('my_rows_div').set('html',response);
            }
        }).send();
    }

    window.deleteRow = function(rowid){
        alert(rowid);
    }
});  
Sam Day
Hi Sam-- thanks for the reply. I tried that, and the error is now "missing ; before statement"
julio
@julio: I botched up the code snippet first time. Note the change: `window.deleteRow = function(rowid) {`
Sam Day
My bad Sam, missed a paren in your snippet. That works! Thanks a lot for your help.
julio
@julio: Welcome! :)
Sam Day
Actually, the `window.` is not needed since all variables declared without a `var` are global.
slebetman
Although not strictly necessary, I think it's not a bad practice since it makes things a little more readable.
Sam Day
+1  A: 

Move the deleteRow function outside of the getRows function, and move both functions outside of the event handler.

In general, Javascript functions should be defined in global scope (or namespaced); not nested inside other functions.

SLaks
Hi Slaks-- it's not nested, if it looks that way it's due to my fault in formatting. The deleteRow is inside the domready block, but it's not part of the getRows function. Thanks
julio
I'm not sure if I understand why the two functions are defined inside the domready block. It isn't the definition of the functions that must wait until the dom is ready - it would be the execution of the functions that would matter.
Brian