Topic: Totally Lost, Need Help! JS Question.

Hi guys, sorry about the vague title, but I don't even know what javascript technology/method I should be using for this one.  Here goes:

I've got this site I am working on, when you load a specific page, it is supposed to count down 16 seconds, and at the end of those 16 seconds, I am going to make an ActiveRecord call.  The seconds need to be displayed as they count down. 

Right now I am using a small text field to display an integer counting down from 16 so that I can access it through the DOM.  Right now it is written in normal JS, but I don't know how to have rails recognized that the counter is done so it can make the activerecord call.

Someone suggested using an inner_html call so that I don't need to place it in a text box.  I've also heard that I should use RJS, hpricot, and jQuery. 

I'm pretty lost here, I know how to make simple ajax updates to a page, but that's really it for JS.  If anyone could just start me on the right path to what I should be reading, that would be very much appreciated.

Re: Totally Lost, Need Help! JS Question.

In the code you use for the countdown timer add something like the following:

if (countdown == 0){
  <%= remote_function :update => 'some_div_that_will_change', :url => {:controller => 'my_controller', :action => 'some_action'} %>
}

Last edited by danger (2007-07-26 14:26:21)

Re: Totally Lost, Need Help! JS Question.

Cool, so I can use regular rails calls from inside normal javascript code?

This is what I have in the header of the page:

    <script type="text/javascript" charset="utf-8">
        <!--
        var time_till_point = 16;
       
        function setTimeSinceArriving(start_time, update_time)
        {
            if (start_time == 0)
            {
                start_time = getCurrentMillisecs();
            }

            var millisecs = getCurrentMillisecs();
            var milliSecondsOnPage = millisecs - start_time;
            var secondsOnPage = Math.round(milliSecondsOnPage / 1000);
           
            if (secondsOnPage < 17)
            {
                document.seconds_form.the_second.value = (time_till_point - secondsOnPage);
                setTimeout("setTimeSinceArriving(" + start_time + "," + update_time + ")", update_time);
            }
           
        }
       
        function getCurrentMillisecs()
        {
            var now = new Date();
            var millisecs = now.getTime();
            return millisecs;
        }
        // -->
    </script>


And in the body tag I have:
<body onLoad="setTimeSinceArriving(0, 500)">

Note, this is the first time I've really done any javascript, I am sure there is a much better (simpler) way to go about this.

Also, is straight javascript what I should be using?

Last edited by dishkuvek (2007-07-26 14:40:45)

Re: Totally Lost, Need Help! JS Question.

Javascript is the only solution for updating things in the browser without a refresh so you're using the right tool there.

And yes, you can use <% %> tags for putting ruby code into any of your templates - but only if they're under /app/views/.  The files in public/javascript/ dont' work that way.

Re: Totally Lost, Need Help! JS Question.

So I shouldn't put it in a .js file, I should just keep in it my view?  Does it matter what view subdirectory it's in?

Re: Totally Lost, Need Help! JS Question.

doesn't matter what directory it's under, as long as it's under /app/views somewhere.

Re: Totally Lost, Need Help! JS Question.

Thank you for taking the time to answer my questions, you've been a huge help!

Re: Totally Lost, Need Help! JS Question.

You're worth it :-)

Re: Totally Lost, Need Help! JS Question.

Aww, thanks man.  One more question, can I also use javascript variables inside the rails code?

For example:

<script>
if (javascriptVar < 17)
{
  <%= remote_funtion :update => 'div', {:action => 'change', :with => javascriptVar} %>
}
</script>

Re: Totally Lost, Need Help! JS Question.

Everything between the <%= %> tags will get executed by ruby.  Whatever ruby spits out is what Javascript will execute.

Buy rails lets you put javascript hidden into the remote_function call - so you can do this:

<script>
if (javascriptVar < 17)
{
  <%= remote_funtion :update => 'div', {:action => 'change', :with => "'param_name'=javascriptVar"} %>
}
</script>

and in your controller you can ask for params[:param_name] and get what was inside 'javascriptVar'

Re: Totally Lost, Need Help! JS Question.

I've tried a bunch of stuff so far, and I've gotten none of it to work.

First, I tried this:

<script>
var sampleVar = 17;

<%= remote_function :update => 'div', :url => {:action => 'change', :sample => 'sampleVar'} %>
</script>


Looking in firebug, I see a call being made to: http://localhost:3000/controller/change?sample=sampleVar

So it's just passing sampleVar as a string, which is what it looks like it should do.

Now I am trying something like you've given:

<script>
var sampleVar = 17;

<%= remote_function :update => 'div', :url => {:action => 'change'}, :with => "'sample'=sampleVar"} %>
</script>


When this goes through, I find a warning in firebug: invalid assignment left-hand side, and then the highlighted line is the ajax output of the above remote_function.

Here it is:

new Ajax.Updater('div', '/controller/change', {asynchronous:true, evalScripts:true, parameters:'sample'=sampleVar})

In both cases, I kinda get the feeling that those JS variables are not being processed as anything but strings.

Any ideas?  Thank you again.

Last edited by dishkuvek (2007-07-26 17:49:28)

Re: Totally Lost, Need Help! JS Question.

I got it!

First I didn't have single quotes on the =, and I seem to have needed a + in there.  So it looks like this:

<%= remote_function(:update => 'div', :url => {:action => 'change'}, :with => "'sample='+sampleVar") %>

Again, thank you so much for your help!

Re: Totally Lost, Need Help! JS Question.

Congratulations!

Re: Totally Lost, Need Help! JS Question.

I am looking to do this exact same thing (display a countdown timer to the user and when it hits 0 then call the controller). Would you mind posting your complete solution to this issue?

Thanks =~ Jeremiah