Forum: Ruby on Rails form_remote_tag - redirect_to working very weirdly

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Darren E. (Guest)
on 2007-01-27 10:57
Hi

I am probably doing something stupid, but I have something really weird
going on. I am using form_remote_tag (in a page called form), my code
essentially goes:

form_remote_tag
 My code
end_form_tag

Then in the controller, under certain conditions I have a redirect_to

This works fine until the redirect_to

On redirect it shows the contents of the new page (login), but this is
not in the source code! The URL does not change to login (it remains
form) and thus the form does not work.

Basically, I just want the controller to forget all form stuff and
redirect properly.

Does anyone have an idea on this one?

Thanks

Darren





View:

<div id="counties">
   <table border="1" cellpadding="0" cellspacing ="0">
      <tr>
        <td>
        <%= form_remote_tag :update => "counties", :url => { :action =>
"form" } %>
          <select id="form" name="form"
onchange="this.form.onsubmit();">
             <option>Please select</option>
             <%= options_from_collection_for_select @counties, "id",
"county_name", @county_id.to_i%>
          </select>
          <br>
          <select id="form2" name="form2"
onchange="this.form.onsubmit();">
             <%= options_from_collection_for_select @districts, "id",
"district_name", @district_id.to_i%>
          </select>

          <%if (@institutions)%>
            <%for institution in @institutions%>
                <%institution.name%>
            <%end%>
            <br>
            <select id="form3" name="form3"
onchange="this.form.onsubmit();">
                <%= options_from_collection_for_select @institutions,
"id", "name", @institution_id.to_i%>
             </select>
         <%end%>
         <%= submit_tag "Go" %>
         <%= end_form_tag %>
     </td>
  </tr>
</table>
</div>

controller:

def form
  @counties=Countyname.find(:all, :order =>"county_name",
:conditions=>["language_id = ?", session[:language_id]])
  if request.post?
    @county_id=Countyname.find(:first, :conditions => ["county_id = ?",
params[:form].to_i]).id
  end

  @districts=District.find(:all, :order => "district_name",
:conditions=>["county_id = ?", @county_id])
  if request.post?
    @dist=District.find(:first, :conditions => ["id = ? and county_id =
?", params[:form2].to_i, @county_id])
    if (@dist)
      @district_id =@dist.id
    else
      @district_id=District.find(:first, :conditions => ["county_id =
?", @county_id]).id
    end
  end

  if (@district_id && @county_id)
    @places=Place.find(:all, :order => "institution_id", :conditions =>
["district_id = ?", @district_id])
    @institutions=[]
    for place in @places
      @res=Institution.find(:first, :conditions=>["id = ?", place.id])
      @institutions << @res
      if request.post?
        @institution_id=params[:form3]
      end
    end

    if !(@institution_id.nil?) && (@district_id && @county_id &&
!@institution_id.empty?)
      redirect_to(:controller => "login", :action => "login" )
    end
  end
end
Darren E. (Guest)
on 2007-01-27 15:08
OK, finally sorted it, but it's a bit messy.

In the view the :update in the form_remote_tag means that the new screen
after the redirect is rendered in the old window. You can use this to
redirect:

render(:text => "<script>window.location.href =
'http://localhost:3000/login/login'</script>")

Hope this helps someone. If there's a bettewr solution, I would of
course be very interested!

Regards

Darren
Bill W. (Guest)
on 2007-01-27 16:55
(Received via mailing list)
Hi Darren,

Darren E. wrote:
> I am using form_remote_tag
>
> Then in the controller, under certain conditions
> I have a redirect_to
>
> This works fine until the redirect_to

I saw your later post.  Glad you found a way to make it work.  Here's
another.  But first some explanation.

The key to avoiding the problem you're having is understanding the
browser-server request cycle.  It starts, always, with the browser.  In
the
request that the browser sends to the server, the browser tells the
server,
via the message type, what kind of response it expects.  The server is
free
to ignore that and send back anything it wants, but the browser will do
with
that response what it has told the server it will do.  In your case,
because
you've used form_remote_tag which generates an XMLHttpRequest, the
browser
has told the server that it expects an executable response.  redirect-to
doesn't send back an executable (i.e., JS).  It sends back straight
HTML.
The browser gets it, tries to execute it as it told the server that it
would, and you end up with nada.  By putting the render in the :update
option, you've hacked your way into getting the server to send back the
JS
response the server expects.  It's not 'wrong' but that solution won't
lead
you very far.  A more open-ended solution is to use RJS, either in the
controller action or in an RJS view.   In your case, in the controller,
use:

render :update do |page|
  page.redirect_to(:controller => 'login', :action => 'login')
end

hth,
Bill
Darren E. (Guest)
on 2007-01-28 07:08
Hi Bill

The redirect works, but not I have an intermediate screen with an rjs
error:

try { window.location.href = "/login/register"; } catch (e) { alert('RJS
error:\n\n' + e.toString()); alert('window.location.href =
\"/login/register\";'); throw e }

Is there any way to get rid of this error. I would like to use your
method, because it is a lot tidier. In my previous version there was
also script in the intermediate window, but the <script>....</script> go
rid of that.

Thanks a lot for your advice.

Darren



Bill W. wrote:
> Hi Darren,
>
> Darren E. wrote:
>> I am using form_remote_tag
>>
>> Then in the controller, under certain conditions
>> I have a redirect_to
>>
>> This works fine until the redirect_to
>
> I saw your later post.  Glad you found a way to make it work.  Here's
> another.  But first some explanation.
>
> The key to avoiding the problem you're having is understanding the
> browser-server request cycle.  It starts, always, with the browser.  In
> the
> request that the browser sends to the server, the browser tells the
> server,
> via the message type, what kind of response it expects.  The server is
> free
> to ignore that and send back anything it wants, but the browser will do
> with
> that response what it has told the server it will do.  In your case,
> because
> you've used form_remote_tag which generates an XMLHttpRequest, the
> browser
> has told the server that it expects an executable response.  redirect-to
> doesn't send back an executable (i.e., JS).  It sends back straight
> HTML.
> The browser gets it, tries to execute it as it told the server that it
> would, and you end up with nada.  By putting the render in the :update
> option, you've hacked your way into getting the server to send back the
> JS
> response the server expects.  It's not 'wrong' but that solution won't
> lead
> you very far.  A more open-ended solution is to use RJS, either in the
> controller action or in an RJS view.   In your case, in the controller,
> use:
>
> render :update do |page|
>   page.redirect_to(:controller => 'login', :action => 'login')
> end
>
> hth,
> Bill
Phlip (Guest)
on 2007-01-28 17:26
(Received via mailing list)
Darren E. wrote:

> try { window.location.href = "/login/register"; } catch (e) { alert('RJS
> error:\n\n' + e.toString()

What's the error? What does the first alert say about e.toString() ?

--
  Phlip
  http://www.greencheese.us/ZeekLand <-- NOT a blog!!!
This topic is locked and can not be replied to.