2

I need to get the row number out of a JavaScript function:

function cap_check(){
    var row;

    $('td').change(function(){ 
        row = $(this).parent().parent().children().index($(this).parent());  
        alert(row);
    }); 

    alert(row);
}

Within the function, row is correctly alerted. Outside of the function, it is undefined.

Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
Kanchana Randika
  • 550
  • 2
  • 12
  • 27
  • 1
    could you please include the html that goes with this code – mcgrailm Jun 07 '11 at 14:59
  • take a look at this post. it is the same. http://stackoverflow.com/questions/2611980/return-value-from-nested-function-in-javascript – JAiro Jun 07 '11 at 14:59
  • @JAiro: No, it's not the same. – Marcel Korpel Jun 07 '11 at 15:03
  • What do you expect? When the function `cap_check` is called, it does not mean that the `change` event handler is triggered immediately. Meaning, `row = $(this).parent()....` will be executed some time later after `cap_check` already returned. – Felix Kling Jun 07 '11 at 15:04

4 Answers4

2

There's no way that calling cap_check will ever alert anything other than undefined. A function is not a static object. When you call a function, it creates a new instance on the internal stack. row will be initialized as undefined and a new click handler will be bound to td elements (also not likely to be useful - as another duplicate event handler will be bound each time you call cap_check).

Most likely, you want something like this:

var cap_check=(function() {
    var row;
    $('td').change(function(){ 
        row = $(this).parent().parent().children().index($(this).parent());  
        alert(row);
    }); 
    return function() {
       alert(row);
    };
}());

This is a self-executing function. When the script runs, the part of the function BEFORE the "return" is executed immediately, creating your event binding once, and returning a function that references the original function instance. This creates a closure which means that the function maintains a reference to the objects of it's parent (in this case, the row variable). So your event handler, and the function returned as cap_check, now will always refer to the same instance of row.

So - now any code that calls cap_check will always return the same value assigned as a result of the change event.

Fiddle:

http://jsfiddle.net/RagUe/5/

(Note that I changed the event to "click" instead of "change" to make it easily testable).

Jamie Treworgy
  • 23,934
  • 8
  • 76
  • 119
  • I'm having trouble understanding how and why this works--is there some reading or YouTube watching material I can look at to better understand the mechanisms or concepts at work here? I'm not getting what happens when you wrap the function and other things in parens (doesn't that make a tuple?), or what is happening when the function returns a function, etc. – Addem Feb 20 '17 at 01:34
0

$('td').change(function(){ })

Change allows you to pass a callback that will run whenever the value changes.

So just by attaching the callback it wont run it. It will only run when the value changes. Since the rest of the function runs before the value changes the value of row is undefined.

Simply place the rest of the script in the callback

Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 1
    He already has the callback, he just needs to keep the rest of the function within it's scope – Swift Jun 07 '11 at 15:01
  • Thanks for the quick responses guys.I tried that but it effects to some other onChange triggering in the rest of the code.That's why I need to take the value out from the jq function. Thanx – Kanchana Randika Jun 07 '11 at 15:05
0

Shouldn't you keep the remainder of the function within the change function?

function cap_check(){
     var row;
             //-----------------------Jquery current table row  
     $('td').change(function(){ 
           row = $(this).parent().parent().children().index($(this).parent());  

           //rest of script here
         }); 

 }
Swift
  • 13,118
  • 5
  • 56
  • 80
-1

Your row inside the function is in a completely different scope then the row outside.

So when you are outside of the change() function row is undefined, but as soon as change is triggered, row gets a value

function cap_check(){
    var row;

    $('td').change(function(){ 
        row = $(this).parent().parent().children().index($(this).parent());  
        alert(row); //only has a value on change
    }); 

    alert(row); //undefined
}
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • @Raynos, whatever do you mean? – Naftali Jun 07 '11 at 15:06
  • That is a too broad generalization. JavaScript is not asynchronous. Only event handlers (sort of) and Ajax. Passing a function as parameter does not imply anything about when the function will be executed. – Felix Kling Jun 07 '11 at 15:06
  • If it's wrong do you have any other alternative ideas to get the job done to make this script function. – Kanchana Randika Jun 07 '11 at 15:24
  • Yes you are correct Naal :). I mean is there any other way to get the job done.I mean to make the below code separate from the jq change function along with the row value. – Kanchana Randika Jun 07 '11 at 15:39
  • 1
    @Ceylo: You have not explained us what `cap_check` is supposed to do. We can only help you if we know which problem you are trying to solve. – Felix Kling Jun 07 '11 at 15:41