Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-23-2013, 05:10 AM   PM User | #1
d'Anconia
Regular Coder

 
d'Anconia's Avatar
 
Join Date: Jan 2010
Location: Tempe, AZ
Posts: 142
Thanks: 15
Thanked 5 Times in 5 Posts
d'Anconia is an unknown quantity at this point
Trouble Passing Variables to Function (Called by setTimeout)

Okay so I am having the following problem. I have gotten AJAX to work and am trying to get Javascript to fade out an old review score and fade in with a new score. The important part right now is that when I try to run it I get the following error:

Code:
Uncaught ReferenceError: preciseResponseAverage is not defined
(anonymous function)
The following is my current code:

Code:
function starSubmitFxn(starNumber) {
    function fadeIn(average, color){
        'use strict';
        var ratingAverage = document.getElementById('rating_average');
        ratingAverage.innerHTML = (average);
        //now time to change the ratings color
        var entityRating = document.getElementById('rating');
        entityRating.style.color = color;
        window.color = color;
    }
    'use strict';
    window.fade('rating');
    //setTimeout("fade('rating')", 1000);
    var ajax = getXMLHttpRequestObject();
    if (ajax) {
                var currentUsername = '<?php echo $current_username; ?>';
                var currentEntityId = <?php echo $entity_id; ?>;
                // Create the Ajax object:
                
                ajax.onreadystatechange = function () {
                    if (ajax.readyState === 4) {
                        //Check the status code:
                        if ( (ajax.status >= 200 && ajax.status < 300) || (ajax.status === 304) ) {
                            
                            //document.getElementById('ajax_status').innerHTML = ajax.responseText;
                            
                            var starResponse = JSON.parse(ajax.responseText);
                                                        
                            var starResponseNumber = parseInt(starResponse["1"].value);
                            var starResponseAverage = (parseInt(starResponse["1"].average));
                            var preciseResponseAverage = starResponseAverage.toPrecision(2);
                            var starResponseColor = starResponse["1"].newColor;
                            
                            //var ratingDiv = document.getElementById('rating');
                            
                            U.removeEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating("<? echo $current_user_review_rows['review_score'] ?>", 'blue'); } );
                            U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(starResponseNumber, 'blue'); } );
                                if (!isNaN(starResponseNumber)) {
                                                                        
                                    //newStarRating(ratingNumber, "blue");//end of newStarRating call
                                        var i = null;
                                        for (i = 1; i <= 10; i++) {
                                        document.getElementById('rating_star_' + i).src = '../images/white_star_17px.png';
                                        } //end of star color reset

                                        var j = null;
                                        for (j = 1; j <= starResponseNumber; j++) {
                                            document.getElementById('rating_star_' + j).src = '../images/blue_star_17px.png';
                                        }
                                    
                                    } //end of response text check
                                if(!isNaN(preciseResponseAverage)) { //if a number is returned, time to fade out / in
                                    
                                    setTimeout("fadeBackIn(preciseResponseAverage, starResponseColor)", 400);
                                    
                                }
                            } //end of Ajax connectivity check
                            else { //if Ajax status text is a failure
                                
                                }
                        } //end of Ajax ready state
                    }; //end of function for execution on ready state change
                    
                var data = 'currentUsername=' + encodeURIComponent(currentUsername) + '&currentEntityId=' + encodeURIComponent(currentEntityId) + '&starNumber=' + encodeURIComponent(starNumber);
                ajax.open('POST', '../resources/star_submit.php?' + data, true);
                ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

                ajax.send(data);
        } //end if ajax object exists
        else {
            
        } //end if it doesn't exist
    } //end of starSubmitFxn
There are some functions defined outside of this function but I don't think those are necessary for me to post right now. The issue seems to be that I'm not sure how to properly send a variable to a function when that function is called via setTimeout. Any help would be appreciated. Thank you.
__________________
Powerful ideas for all lovers of personal and political freedom:
Freedomain Radio
Free Talk Live
d'Anconia is offline   Reply With Quote
Old 01-23-2013, 05:59 AM   PM User | #2
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,465
Thanks: 0
Thanked 499 Times in 491 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
setTimeout expects a function as the first parameter so the string you supply is effectively being wrapped in an anonymous function that is run after the specified time.

The preciseResponseAverage variable is only defined in the anonymous function attached to the onreadystatechange event handler and so that copy has gone out of scope by the time that your string gets converted into a function.

Converting it to a function yourself so that the fields it references are visible before they go out of scope will hopefully create the needed closure.

setTimeout(function() {fadeBackIn(preciseResponseAverage, starResponseColor)}, 400);
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 01-24-2013, 07:01 AM   PM User | #3
d'Anconia
Regular Coder

 
d'Anconia's Avatar
 
Join Date: Jan 2010
Location: Tempe, AZ
Posts: 142
Thanks: 15
Thanked 5 Times in 5 Posts
d'Anconia is an unknown quantity at this point
Yeah I decided the best way to do it was to modify and use a setTimeout function within a for loop. For some reason it seems like it is not going through the loop correctly though. Here is the relevant part of my code:

Code:
    function fade(currentTime, newAverage, newColor) {
        if (currentTime <= 5){
            var currentOpacity = 1.0 - (currentTime * .2);
            document.getElementById('rating').style.opacity = currentOpacity;
            document.getElementById('logo').style.width = "500";
        }
        if(currentTime >= 5){
            var ratingAverage = document.getElementById('rating_average');
            ratingAverage.innerHTML = (newAverage);
            //now time to change the ratings color
            var entityRating = document.getElementById('rating');
            entityRating.style.color = newColor;
            var currentOpacity = currentTime * 2 - 1.0;
            document.getElementById('rating').style.opacity = currentOpacity;
            }
        }   

document.getElementById('rating').style.opacity = 1.0;                 
for (var timer = 0; timer < 10; timer++){
    setTimeout(function(){fade(timer, preciseResponseAverage, starResponseColor)}, 100);
    }
I was hoping for a slow fade but am not getting that. Currently it's not even changing the opacity at all when I click on it, nor the color of the text. In fact I added the logo.style.width = 500 line specifically to test to see whether it's even looping at all and it appears that it's not because the logo on the page is not changing to 500px (whether I include the 'px' or not). It's will change the actual rating itself though...

Edit: Heck I even got it to change the color but when it changes there is no opacity fade at all. It's like Javascript is only executing the final part of the loop or something...

PS For the record I am using Chrome.
__________________
Powerful ideas for all lovers of personal and political freedom:
Freedomain Radio
Free Talk Live

Last edited by d'Anconia; 01-24-2013 at 07:15 AM..
d'Anconia is offline   Reply With Quote
Old 01-24-2013, 07:26 AM   PM User | #4
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
I don't think you understand what this code is doing:
Code:
for (var timer = 0; timer < 10; timer++)
{
    setTimeout(function(){fade(timer, preciseResponseAverage, starResponseColor)}, 100);
}
That code is saying "Repeat 10 times: 100 milliseconds from *RIGHT NOW* call the fade function."

It is *NOT* saying "call the fade function 10 times, each time 100 milliseconds after the last".

So all 10 calls to fade( ) are being made...but they are *ALL* being made at essentially the same time.
So the human eye only sees the result of the last call.

But it would be trivial to have it do that:
Code:
for (var timer = 0; timer < 10; timer++)
{
    setTimeout(
        function(){ fade(timer, preciseResponseAverage, starResponseColor)}, 
        100*(timer+1)
    );
}
You see that?
The first call to fade will be at 100*(0+1) milliseconds.
The second call to fade will be at 100*(1+1) milliseconds.
...
The 10th call to fade will be at 100*(1+9) milliseconds, or 1 full second later.

Is this the best way to do it? Probably not. But it's workable.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.

Last edited by Old Pedant; 01-24-2013 at 07:29 AM..
Old Pedant is offline   Reply With Quote
Old 01-24-2013, 07:32 AM   PM User | #5
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
This doesn't make much sense:
Code:
        if (currentTime <= 5){... }
        if (currentTime >= 5){ ... }
So if currentTime is *exactly* 5, you will do *BOTH* actions. And for the most part, the second one will negate the effects of the first.

Is that *really* what you wanted?

Wouldn't it make more sense to do
Code:
        if (currentTime < 5){... }
        else { ... }
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Old 01-24-2013, 07:35 AM   PM User | #6
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,248
Thanks: 59
Thanked 3,999 Times in 3,968 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
And, yes, you *MUST* specify "px" when changing a style property if you want the number to be interpreted as pixels. MSIE will default to pixels, but other browsers will just ingore the number. Remember, you can use "pt" and "%" and a few other things other than "px", so the browser insists you tell it which.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Reply

Bookmarks

Tags
ajax, settimeout, variables

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:02 PM.


Advertisement
Log in to turn off these ads.