Topic: [AJAX form] embedding forms

Hi Railsforum members,

I want to be able to create new categories on the fly.
My question is how it should be embedded.

I've numbered two layouts in my attached image.

http://img201.imageshack.us/img201/5836/forumembeddingia6.th.gif

I would think with layout one that I'd be able to add categories but would when I select a category would it carry over with the other form when I hit edit at the bottom?

With layout 2 the ajax form would be embedded in the regular form but is that legal?

How should I proceed?

Re: [AJAX form] embedding forms

OmenKing wrote:

I would think with layout one that I'd be able to add categories but would when I select a category would it carry over with the other form when I hit edit at the bottom?

Depends how you handle the AJAX. If you have the AJAX result update an element inside the other form (add a hidden field or something) then that hidden field will be submitted in the form.

OmenKing wrote:

With layout 2 the ajax form would be embedded in the regular form but is that legal?

Nope, forms can't be nested.

Actually there's a 3rd option which is probably what you want. Only use one form. AJAX does not require a form. The trick is to override the onchange attribute of the select menu. You can then use remote_function to call the action you want.

<%= select ..., :onchange => remote_function(...) %>

Last edited by ryanb (2007-03-10 21:23:32)

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

That third option looks interesting.

I've decided to break up the form as per layout 2.

But I'm getting an error when I try to create the category

http://img207.imageshack.us/img207/3488/createcategoryfb6.th.gif

_category.rhtml

<%= form_remote_tag :url => {:action => :create_category}, :update => 'ajax' %>
    <div class="name"><label for="category_name">Category Name</label><%= text_field 'category', 'name', :maxlength => 35  %></div><!-- name -->
    <%= submit_tag 'Create Category' %>
<% end_form_tag %>

I've added two functions to add the category.
I think I'll be moving these functions to their own controller after I get them working.
notes_controller
    def new_category
      @category = Category.new
        render :partial => "category", :layout => false
    end
   
    def create_category
    @category = category.new(params[:category])
    if @category.save
      flash[:notice] = 'Category was successfully created.'
    end
    end

Re: [AJAX form] embedding forms

Ruby is case sensitive, you need to capitalize Category in the create_category action:

@category = Category.new(params[:category])

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

Funny, I was going to post this exact thread just now... good thing I searched!

AJAX does not require a form. The trick is to override the onchange attribute of the select menu. You can then use remote_function to call the action you want.

Could you elaborate on this a bit? I fail to see how OmenKing's last example adheres to this solution since it appears he is nesting a remote form inside a standard one.

Re: [AJAX form] embedding forms

Certainly. It depends slightly on how you are generating the select menu. Here's how you would do it with the "collection_select" helper method:

<%= collection_select :note, :category_id, @categories, :id, :name, {}, {:onchange => '...'} %>

The reason we need that empty hash near the end is because the first hash is for specifying options and the second hash is for specifying HTML attributes. we want an HTML attribute so the end result will look something like this:

<select id="note_category_id" name="note[category_id]" onchange="...">
...

The onchange attribute can accept some javascript which will be triggered when a menu is selected. What you want the javascript to do is call another controller action AJAXy style. In that case you would want to use remote_function:

<%= collection_select :note, :category_id, @categories, :id, :name, {}, {:onchange => remote_function(...)} %>

The remote_function method takes roughly the same parameters as link_to_remote and form_remote_tag. The primary difference is how the AJAXyness is triggered: by a change of the field vs. clicking a link or submitting a form.

Overall, this allows you to add AJAX without adding another form so you only need one form tag.

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

Hmm...

Pardon my denseness but I'm still not getting it.

The tricky part seems to be in getting the select input to update its options to show the added category, so I can continue filling out the main form.

I am using clientside toggle to show the form, and once that is shown I click the Save New Category button, which I would liek to do 2 things:

1. Add a category to DB
2. Update the select list to show the new category

Just for reference, here is how I ma creating my select list:

<%= f.select :category_id, [['Choose Category', '']] + @categories.collect {|cat| [cat.name, cat.id]} %>

Am I even going about this the right way?

Last edited by pimpmaster (2007-03-11 15:38:04)

Re: [AJAX form] embedding forms

It's possible, AJAX doesn't require a form (you just need to have something trigger javascript). If you want a link to do that, you can use link_to_remote.

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

Dude you are ridiculously fast! I was updating my post to clarify and I see you already posted a response.

Thanks for the pointer... I will be investigating link_to_remote 4 sure

Re: [AJAX form] embedding forms

pimpmaster wrote:

The tricky part seems to be in getting the select input to update its options to show the added category, so I can continue filling out the main form.

The easiest way to solve this is rebuild the select menu. If you are using RJS it's as simple as re-rendering the div surrounding the select menu (move the select menu into a partial and render that).

pimpmaster wrote:

I am using clientside toggle to show the form, and once that is shown I click the Save New Category button

If you want a button, check out submit_to_remote

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

I think that third option makes more sense now.

I was using basecamp today and noticed how simple they made it to add a category:

http://img401.imageshack.us/img401/1305/categoryqj2.gif

You get a single text-field/alert-box popup to enter it your new field.

I think I've been going around it the long way.

Last edited by OmenKing (2007-03-11 22:02:37)

Re: [AJAX form] embedding forms

I'm trying to use a check box with remote_function to change a div.

<%= check_box_tag 'disable', '1', false, {:onclick => remote_function(:update => "note_mark", :url => { :action => :disable_div})

When the box is checked:
<div class="note">
a bunch of things are in here
</div>

When the box isn't checked:
<div class="note disable" id="note">
  a bunch of things are in here
</div>

How can I write the function in the controller to just change the div tag.
I just need to effect the attribute called 'class' and change a value of a checkbox tag

Anyway I can go about doing this without having to create a brand new partial template?

Re: [AJAX form] embedding forms

OmenKing wrote:

Anyway I can go about doing this without having to create a brand new partial template?

Yep, no need  to use AJAX for this - it doesn't rely on anything server side. In fact, you'll get better performance by keeping it all client side.

A dab of Javascript will solve your problem. Just insert it as a string into the onclick attribute instead of doing remote_function. Something like this will work I think:

if (this.checked) {
  $('note').className = 'note'
} else {
  $('note').className = 'note disabled'
}

Untested.

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

Is there a clean way to generate Javascript code?
I keep hearing about RJS but I don't know too much about it.
I'm guessing its the ruby way to generate javascript.

Re: [AJAX form] embedding forms

Yeah, RJS is a possibility. However, it is primarily designed to be used on the server side. It also doesn't handle javascript "if" conditions very prettily, so I think you are better off with plain javascript here.

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

thanks ryanb

Re: [AJAX form] embedding forms

Hi, I've got the same problem with an embedded remote form, with one difference: There are multiple fields that need to be submitted by a button.
To illustrate the situation: I have a model "House" wich has_many rooms. So I have a list of rooms on the edit page for every house and a form at the bottom of the list to add new rooms dynamically, storing name and size in the DB. After adding the list gets updated.

How do I submit these form values to the controller and rebuild the list if I can't use a nested remote form?

Re: [AJAX form] embedding forms

You could use submit_to_remote for submitting the form to another action when adding a room. Although it does submit all form fields, the action will only handle the room specific fields so it shouldn't matter.

On a related note, see this tutorial for a slightly different way to do this.

Railscasts - Free Ruby on Rails Screencasts

Re: [AJAX form] embedding forms

This is great, thanks!

Re: [AJAX form] embedding forms

Hey folks, sorry to throw a fourth person's situation into here but I'm trying to do something very similar to OmenKing's query, and I'm pretty sure the answer's in this thread but I'm still stuck.

Here's my situation:

- I have one large form to update an item.
- Within it I have several drop down boxes for things such as category.
- I want to give each of these some sort of mechanism of updating the category list on the fly.
- These lists might actually require two fields to be submitted when a new entry is added.

So, taking the category drop down as the example, I originally wanted to nest another form to do this but soon discovered that I couldn't nest the forms. I have since separated them and have proven that they both work independently, so I'm happy that my actions are ok.

I'm a bit lost as to how best to approach this, is there some sort of js attribute I can use that will allow me to call the action and submit the two text fields?  I've seen forms with multiple submit buttons before, but maybe they were laid out internally so they were separate forms?

I have some idea about updating the select box afterwards - either having it doing periodic updates, or maybe being able to trigger a calback of somesort to have it update itself.

All this client side stuff is confusing the hell out of me!

Tia,

Jon

I can't stop thinking about Rails. Can't sleep, can't eat, can't concentrate on work. It must be love.