# Form\_remote\_tag

**URL:** <https://www.ruby-forum.com/t/form-remote-tag/83646>\
**Category:** Rails\
**Created:** [January 28, 2007, 7:32am UTC](https://www.ruby-forum.com/t/form-remote-tag/83646 "2007-01-28T07:32:35Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![darrenevans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@darrenevans](https://www.ruby-forum.com/u/darrenevans)\
**Post date:** [January 28, 2007, 7:32am UTC](https://www.ruby-forum.com/t/form-remote-tag/83646/1 "2007-01-28T07:32:35Z")

</div>

Hi

This is along the same lines as my previous question (form\_remote\_tag -  
redirect\_to working very weirdly), but different enough to deserve a  
different posting I think.

After updating a form using form\_remote\_tag the view re-renders the  
layout. You end up with cascading headers, footers etc going down the  
page. I know how to turn layouts off, but I would like to add a  
condition to that, so that somehow it doesn’t repeat.

Can I do this from my controller somehow? What I want to say is  
something like:

“Render the layout of the page ‘form’, but if updating the page through  
the div ‘form’, then do not re-render the layout”

Thanks

Darren

---

<div class="post-metadata">

**Author:** ![darrenevans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@darrenevans](https://www.ruby-forum.com/u/darrenevans)\
**Post date:** [January 28, 2007, 8:09am UTC](https://www.ruby-forum.com/t/form-remote-tag/83646/2 "2007-01-28T08:09:29Z")

</div>

Try putting your result in an entirely different div, this way you  
won’t need to write any logic.

On Jan 28, 1:32 am, Darren E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![darrenevans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@darrenevans](https://www.ruby-forum.com/u/darrenevans)\
**Post date:** [January 28, 2007, 8:17am UTC](https://www.ruby-forum.com/t/form-remote-tag/83646/3 "2007-01-28T08:17:56Z")

</div>

Hi

Thanks for the reply. That doesn’t work though (I changed it to form\_new  
to test), maybe I am doing something stupid?

Any help would be really appreciated.

Darren

View:

| \<%= form\_remote\_tag :update =\> "form\_new", :url =\> {:action =\> "form" }, :complete =\> evaluate\_remote\_response%\> \<%= options\_from\_collection\_for\_select @counties, "id", "county\_name", @county\_id.to\_i%\> \<%if !(@districts.empty?)%\>   
 \<%= options\_from\_collection\_for\_select @districts, "id", "district\_name", @district\_id.to\_i%\> \<%end%\>

```
      <%if (@institutions)%>
        <%for institution in @institutions%>
            <%institution.name%>
        <%end%>
        <br>
         <select id="form3" name="form3" 

```

onchange=“this.form.onsubmit(); return false;”\>  
\<%= options\_from\_collection\_for\_select @institutions,  
“id”, “name”, @institution\_id.to\_i%\>  
  
\<%end%\>  
\<%= submit\_tag “Go” %\>  
\<%= end\_form\_tag %\>

 |

Controller:

def form  
@counties=Countyname.find(:all, :order =\>“county\_name”,  
:conditions=\>[“language\_id = ?”, session[:language\_id]])  
if (params[:username])  
session[:user\_suggested]=(params[:username])  
session[:password\_suggested]=(params[:password])

redirect\_to(:controller =\> ‘login’, :action =\> ‘login’)  
return  
end

if request.post?  
@county\_id=Countyname.find(:first, :conditions =\> [“county\_id = ?”,  
params[:form1].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 (params[:form1] && params[:form2])  
@places=Place.find(:all, :order =\> “institution\_id”, :conditions =\>  
[“district\_id = ?”, @district\_id])  
@institutions=[]  
@institution\_display=1  
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?)  
session[:institution\_id]=@institution\_id  
session[:district\_id]=@district\_id  
session[:county\_id]=@county\_id  
session[:institution\_name]=Institution.find(:first, :conditions =\>  
[“id= ?”, session[:institution\_id]]).name  
session[:district\_name]=District.find(:first, :conditions =\> [“id=  
?”, session[:district\_id]]).district\_name  
session[:county\_name]=Countyname.find(:first, :conditions =\> [“id=  
?”, session[:county\_id]]).county\_name  
#render(:text =\> “”)  
render :update do |page|  
page.redirect\_to(:controller =\> ‘login’, :action =\> ‘register’)  
end

```
end

```

end  
end

Theron Parlin wrote:

> Try putting your result in an entirely different div, this way you  
> won’t need to write any logic.
> 
> On Jan 28, 1:32 am, Darren E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![darrenevans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@darrenevans](https://www.ruby-forum.com/u/darrenevans)\
**Post date:** [January 28, 2007, 3:54pm UTC](https://www.ruby-forum.com/t/form-remote-tag/83646/4 "2007-01-28T15:54:49Z")

</div>

Darren E. wrote:

> Thanks for the reply. That doesn’t work though (I changed it to form\_new  
> to test), maybe I am doing something stupid?

One code review coming up.

> Darren
> 
> View:
> 
> | \<%= form\_remote\_tag :update =\> "form\_new", :url =\> {:action =\> "form" }, :complete =\> evaluate\_remote\_response%\>
> 
> I never use :update any more. I always use RJS in the action to point  
> to the specific variables that need an update.
> 
> Further, I think that updating the entire DIV containing a FORM is bad  
> luck. Of course it will work, but I would rather the browser can  
> preserve the original FORM’s context, at least so the user doesn’t  
> lose their focus and selection at submit time.
> 
> You are allow to update things other than DIVs, you know!
> 
> > ```
> > <select id="form1" name="form1"
> > 
> > ```
> > 
> > onchange=“this.form.onsubmit();”\>  
> > \<%= options\_from\_collection\_for\_select @counties, “id”,  
> > “county\_name”, @county\_id.to\_i%\>
> 
> That will submit the FORM each time the user changes a value. This is  
> bad usability, and it would repaint the FORM, destroying the user’s  
> context before they can select the value they actually want. Submit  
> buttons are sometimes good things; they help the user decide and then  
> commit in two steps.
> 
> > ```
> > <%for institution in @institutions%>
> > <%institution.name%>
> > 
> > ```
> 
> That has to mean \<%= institution.name %\>, right?
> 
> > ```
> > <%end%>
> > 
> > ```
> 
> I had forgotten Ruby supports a for command. You should practice using  
> @institutions.each do, because it provides tighter scope, and leads to  
> more elaborate iterations, such as .insert, .reject, .map(&:name),  
> etc.
> 
> > ```
> > <br>
> > 
> > ```
> 
> I always write XHTML.   
> . And my test cases use assert\_xpath which  
> demand XHTML (for short segments of the HTML.)
> 
> You do _have_ test cases, don’t you?
> 
> > ```
> > <select id="form3" name="form3"
> > 
> > ```
> > 
> > onchange=“this.form.onsubmit(); return false;”\>  
> > \<%= options\_from\_collection\_for\_select @institutions,  
> > “id”, “name”, @institution\_id.to\_i%\>  
> >   
> > \<%end%\>  
> > \<%= submit\_tag “Go” %\>
> 
> Why you have submit tags built into the select items, _and_ a submit  
> button? Those onchange handlers might not do what you think.
> 
> > ```
> > <%= end_form_tag %>
> > 
> > ```
> 
> That thing is deprecated. I suspect one should use . That leads  
> to the lamentable situation where a \<%%\> starts a block and a \</\> ends  
> it, but I suspect the form\_ tags also take do…end blocks, so \<% end  
> %\> might work there if you put a do up top.
> 
> > ```
> > </td>
> > 
> > ```
> 
> |
> 
> Controller:

This action is way too long. You should write tests for all of it, and  
then refactor it to pull all the model-specific stuff out to the  
model, or to helpers. For example…

> def form  
> @counties=Countyname.find(:all, :order =\>“county\_name”,  
> :conditions=\>[“language\_id = ?”, session[:language\_id]])

That could be @counties = county\_list(), where a helper hides the ugly  
stuff and gives it a useful name.

> if (params[:username])  
> session[:user\_suggested]=(params[:username])  
> session[:password\_suggested]=(params[:password])
> 
> redirect\_to(:controller =\> ‘login’, :action =\> ‘login’)  
> return  
> end

You have several little actions here masquerading as one big action.  
Split them up into multiple actions, give each one a name and a guard  
clause enforcing how the browser must call it, and make each action as  
short and sweet as possible.

The guard clause for that username action could be

return if request.xhr?

for example, to prevent Ajax from calling it (if that’s what you mean).

And the Joy of Ruby is how close you can get these expressions to  
normal English. Enforce that wherever you can, including in your  
variable name selections. Upgrade username to user\_name.

> if request.post?

Again, this is another action hiding inside this one. its guard clause  
would be return unless request.post?

> ```
> @district_id =@dist.id
> 
> ```
> 
> else  
> @district\_id=District.find(:first, :conditions =\> [“county\_id =  
> ?”, @county\_id]).id  
> end  
> end

I don’t think every single one of your variables needs a @.

> ```
> end
> 
> ```
> 
> end

I suspect this would work, off the top of my head:

institutions = Institution.find(places.map(&:id))

There is some variation on find() that takes an array of ids, so don’t  
call find() in a loop if you can just pass that array in.

> ?", session[:county\_id]]).county\_name  
> #render(:text =\> “”)

I never use the session object, and you have a “latent model” here.  
You should pull all those variables out of the session and put them  
into a model, with a good name that reveals its intent.

> render :update do |page|  
> page.redirect\_to(:controller =\> ‘login’, :action =\> ‘register’)  
> end

render :update is incompatible with the :update option in the  
form\_remote\_tag.

Next, you are redirecting to paint a complete page, with its layout  
and everything. Rails doesn’t care that you are pushing the result  
into a DIV in another page!

> end  
> end  
> end

Try moving all the DIV’s contents into a partial, with a name better  
than \_form.rhtml, and then \<% render :partial =\> ‘form’ %\> inside the  
calling RHTML.

Then leave in the :update tag, for now, and replace this render with  
render :partial =\> ‘form’

After that works, look up the system to pass variables into a partial,  
so you can take out lots of session and @.

The reason we all like Rails here is we have experience with Brand X,  
where all forms and actions are completely crammed with sickeningly  
irrelevant details. Rails leads us to write forms and actions that  
really do look like the ones in the Agile Web D. with Rails  
books - very short, completely readable, with almost no administrivia  
and paperwork just to get something done. You should spend a little  
time learning more Ruby, and then seeing how small you can make all  
this code, before adding more features to it.

–  
Phlip  
[http://c2.com/cgi/wiki?ZeekLand](http://c2.com/cgi/wiki?ZeekLand) ← NOT a blog!!

---

<div class="post-metadata">

**Author:** ![darrenevans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/87869e/32.png) [@darrenevans](https://www.ruby-forum.com/u/darrenevans)\
**Post date:** [February 10, 2007, 10:16pm UTC](https://www.ruby-forum.com/t/form-remote-tag/83646/5 "2007-02-10T22:16:21Z")

</div>

Phlip,

Thanks for your comments, they were mostly correct and useful.

You should try to appreciate the concept of a forum more before you next  
make a post. The idea is (at least it should be) that it is help space  
that anyone needing help can get advice.

It strictly not be about egos, it’s about a community where people can  
help each other in a friendly way. We are not all Ruby buffs and that’s  
why we ask questions…

Darren
