Ajax form wtihin a form? Being in nothingness?

Hi:

This one’s a little wierd. I have a simple form using form_for, it’s a
form for entering tasks. A few fields, no biggie. My submit button is
at the bottom of the page. I need to introduce the concept of sub-task.
The user can have one sub-task, or many sub-tasks. What I would really
like is a link or button that inserts a partial with another small form
for entering these subtasks. The number of subtasks that the user can
enter is variable and theoretically infinite.

Here’s the view:

<% form_for(:task, :url => tasks_path) do |f| %>

Task Name * <%= f.text_field :title %>
Task 1:
Task 2:
Task 3:
<%= text_field_tag('step_1', 'enter Task 1 here', {}) %>
<%= text_field_tag('step_1', 'enter Task 2 here', {}) %>
<%= text_field_tag('step_1', 'enter Task 3 here', {}) %>
<%= form_remote_tag :url => { :action => 'add_new' }, :html => { :id => 'addnew' } %> <%= link_to 'Add More Tasks', :method => 'add_new' %> <%= end_form_tag %>

<%= submit_tag "Create" %>

<% end %>

The controller code is complicated, but right now the “create” action
does what you would expect - simple insert.

I created a new method in the controller “add_new” but didn’t put
anything in it. I would imagine it needs code to add maybe the previous
sub-task.

Finally, i created a partial for the new tasks:

<%= text_field_tag(‘step’, ‘enter Task here’, {}) %>

and the RJS, again pretty standard:

page.insert_html :bottom, ‘addnew’, :partial => ‘add_new’
page.visual_effect :highlight, ‘addnew’

So, that’s it. When I click “add new task” the page refreshes but my
DIV isn’t populated and basically nothing happens.

Any help you can provide would be greatly appreciated.

Mike

Hi Mike,

Mike D. wrote:

What I would really like is a link or button that
inserts a partial with another small form for
entering these subtasks.

When I click “add new task” the page refreshes
but my DIV isn’t populated and basically nothing
happens.

You can’t have a form within a form. The W3C HTML spec says so. I had
the
same issue.

It is possible, quite easy actually, to render multiple forms on one
page.
I render one each for the new tasks, then one (empty) one that looks to
the
visitor like the normal submit button but doesn’t submit anything - just
moves them to another page.

Note that this solution will not degrade gracefully if the visitor has
js
disabled. I decided not to even allow the visitor to visit that portion
of
my site if they don’t have js enabled. The alternative is to redirect
them
a ‘crippled’ version of the page. You’ll need to think through what
your
site needs to do.

Best regards,
Bill

Bill:

It is possible, quite easy actually, to render multiple forms on one
page.
I render one each for the new tasks, then one (empty) one that looks to
the
visitor like the normal submit button but doesn’t submit anything - just
moves them to another page.

Thanks as usual for your help. Here’s what I don’t understand: how
would you actually submit the form on the top with a fake submit button
on the bottom that didn’t do anything? Don’t tell me rails does that
automatically?

In the intervening period since I posted this question, I actually
started using “link_to_remote” which actually looks much better for my
form, becuase i need to inject lots of HTML depending on user controls
and links. So here’s where I’ve landed (from the view, cut down for the
relevant parts):

<%= link_to_remote "Add another task", :update => 'new_task', :url => { :action => 'add_new', :id => '1'} %>

My RJS hasn’t changed (add_new.rjs):

page.insert_html :bottom, ‘new_task’, :partial => ‘add_new’
page.visual_effect :highlight, ‘new_task’

and the partial is just some simple text as, per your suggestion, I’m
building slowly (_add_new.rhtml):

insert complete

Again, the method “new_task” doesn’t have any code it it yet, but it
will be probably to insert the previous task, I would think.

Again, thanks for your continuing help. At this time, we don’t have
plans for no javascript degredation.

Thanks as usual, Bill.

Mike

Bill:

Ok, I understand what you mean now. But here’s my next problem. When I
do the HTML injection, I get javascript jibberish instead of the partial
as it should be. the partial is enclosed. Here’s what’s showing up in
the div on the page after I click the link:

try { new Insertion.Bottom(“new_task”, “insert complete”); new
Effect.Highlight(“new_task”,{}); } catch (e) { alert(‘RJS error:\n\n’ +
e.toString()); alert(‘new Insertion.Bottom(“new_task”, “insert
complete”);\nnew Effect.Highlight(“new_task”,{});’); throw e }

So my HTML is in there somewhere. What am I doing wrong?

Thanks again,

Mike

Hi Mike,

Thanks as usual for your help.

You’re welcome.

Here’s what I don’t understand: how would you
actually submit the form on the top with a fake
submit button on the bottom that didn’t do anything?

You don’t. I use ajax (form_remote_tag, in my case) to submit each of
items
the visitor enters as they enter it.

At this time, we don’t have
plans for no javascript degredation.

Then you probably want to take a real hard look at your approach. In
the
documentation, any method that mentions XMLHttpRequest requires js to be
enabled on the browser if you intend to update anything in the page
you’re
showing the visitor.

hth,
Bill

Sorry. You’ve lost me. Start over.

On Saturday 10 February 2007, Bill W. wrote:

You don’t. I use ajax (form_remote_tag, in my case) to submit each
of items the visitor enters as they enter it.

That won’t work if there are validations that require the presence of
multiple attributes, or does it?

Michael


Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/

Hi Michael,

Michael S. wrote:

That won’t work if there are validations that
require the presence of multiple attributes, or
does it?

Lots of ways to handle it.

Object.save_with_validation(false) will let you handle it in the
database
once everything you need to validate has been entered. You have to
track
what’s been entered, of course, and then either save with or without
validation depending on what you want to do.

hth,
Bill

Bill W. wrote:

Sorry. You’ve lost me. Start over.

You think you’re lost! :slight_smile:

Ok, so, with your help I was able to get the following link_to in my
viewer code to work:

<%= link_to_remote “Add another task”, :update => ‘new_task’,
:url => { :action => ‘add_new’, :id => ‘1’} %>

the div I want to update into is right above this part of the view, so:

<%= link_to_remote "Add another task", :update => 'new_task', :url => { :action => 'add_new', :id => '1'} %>

But! When I click my link, instead of the contents of my partial, as
specified in my RJS, I get the Javascript jibberish inserted into my
div, instead of just the HTML. The jibberish is in my previous post.
My RJS hasn’t changed, looks like:

page.insert_html :bottom, ‘new_task’, :partial => ‘add_new’
page.visual_effect :highlight, ‘new_task’

I know that this is at least somewhat working, becuase when I click the
remote link (add another task) the div is filled with the jibbersh, and
it also highlights, per the RJS.

That’s where I am, is that more clear or is there something else I’m
omitting?

Thanks again for all of your help!

Mike

Matt:

Yep! That did it! Thank you so much!

As being able to see the onion was never enough for me, and I always
need to be able to peel the onion, would this same thing be possible
without the RJS?

Thanks again!

Mike

Mike D. wrote:

<%= link_to_remote “Add another task”, :update => ‘new_task’,
div, instead of just the HTML. The jibberish is in my previous post.
omitting?

Thanks again for all of your help!

Mike

Get rid of the :update in your link_to_remotes. If you are using RJS
then you are telling the page what to update already so this is messing
things up.

Matt M.
blog.mattmargolis.net