Forum: Ruby on Rails Baffling AJAX issue

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.
Ryan E. (Guest)
on 2006-03-16 20:13
Ok, I've got some link_to_remote stuff working elsewhere just fine, but
this time it's doing something very screwy. Here's the view code to
create a link to remotely toggle a boolean value on a record:

<td class="contact_active">
<%= link_to_remote "<div id='contact_active_#{cm.id}'><span
class='#{cm.active}'>#{cm.active}</span></div>", { :update =>
"contact_active_#{cm.id}", :url => {:action => "toggle_contact_method",
:id => cm.id} } %>
</td>

There's quite a mess of embedded tags and quotes there, but I think it's
all correct and it does generate the correct html initially. The span
element inside the div is what's getting replaced. The remote call
renders a string containing a span element with the toggled value and a
css class reference to match:

def toggle_contact_method
 cm = ContactMethod.find(params[:id])
 cm.toggle('active')
 render_text "<span class='#{cm.active}'>#{cm.active}</span>"
end

However, for some reason in the replacement an extra anchor tag is being
generated.

Original:
<div id="contact_active_12"><span class="true">true</span></div>
After AJAX replacement:
<div id="contact_active_12"><span
class="false"><a>false</a></span></div>

I have no idea where the hell it gets that extra anchor tag, so any
insightful observations would be appreciated.
Gareth R. (Guest)
on 2006-03-16 20:20
You can't update DOM elements in a table. I have made this sort of thing
work by embedding a table within the table. It wasnt pretty but is was
the best I could come up with at the time.

Anyone else got any suggestions?

G
Ryan E. (Guest)
on 2006-03-16 22:40
Gareth R. wrote:
> You can't update DOM elements in a table.

Well, that's a really crappy, arbitrary limitation. I don't know how
that explans the output, though. In any case, does anybody have any more
suggestions for how to make something like this work? Am I going to have
to build the tables out of css blocks?
Cody S. (Guest)
on 2006-03-16 23:05
Ryan, can you run the template, view source and past the output HTML
here for us to take a look at?
Jodi S. (Guest)
on 2006-03-16 23:18
(Received via mailing list)
hey Ryan - I feel your pain!

I have faced the same issue - autocompletes just not working (no
feedback, nothing), divs not updating etc.

For this reason I've been rolling over my tables to divs. I've got
more than 25 really huge entry screens, and it sucks, so I'm just
transitioning in.

In the end I'm much happier - the code is cleaner and tables are a
little easier for me now.

Since  having moved to divs, I'm not experiencing any flakiness with
prototype or sc.ript.uclo.us (sp? always get that one wrong)

Here's the usage:

<div class="striped_table">

<div class="even_row">
	<div class="column">&nbsp;</div>
	<div class="column">
	</div>
	<BR clear="all"/>
</div>

<div class="odd_row">
	<div class="column">&nbsp;</div>
	<div class="column">
	</div>
	<BR clear="all"/>
</div>

</div>

------- CSS --------
div.striped_table {
	position:relative;
	z-index:1;
	font-family: "lucida grande", verdana, sans-serif;
	font-size: 9pt;
	width: 100%;
}

div.striped_table div.even_row {
   width: 100%;
   background-color: #edf3fe;
   padding-bottom: 5px;
   padding-top: 5px;
}
div.striped_table div.odd_row {
   width: 100%;
   background-color: #fff;
   padding-bottom: 5px;
   padding-top: 5px;
}
div.striped_table div.title_row {
	width: 100%;
	font-family: "lucida grande", verdana, sans-serif;
	font-size: 9pt;
	text-transform:uppercase;
	text-decoration:none;
	background-color: #fff;
	padding-bottom: 5px;
	padding-top: 5px;
}
div.striped_table div.selected {
   background-color: #FFFFCC;
   padding-bottom: 5px;
   padding-top: 5px;
}
div.striped_table .column {
   width: 0%;
   padding:0px;
   float:left;
}
------- CSS --------
Andrew G.berg (Guest)
on 2006-03-16 23:28
(Received via mailing list)
I seem to have had more success with this than I should.  Indeed, I
banged my head against a wall the other day trying to figure out why
a link (for cancelling) was working, but a form submit (for editing)
was not.  I ultimately discovered that the problem was utterly and
completely me, I mispelled the token :update in the form_remote_tag,
but not in the link_to_remote.

Most of what I was doing was straightforward replacements of existing
DOM elements, in particular, TR tag elements.  I have noticed some
pretty freaky things happening with different browsers on insertions
and deletions.  However, given the last experience, I still don't
doubt that the problem is me.
Ryan E. (Guest)
on 2006-03-17 00:00
Thanks, Jodi! I'm probably going to try something like that.

Andrew: Still being relatively new to this I initially suspected that I
did something wrong, but I sure can't see anything wrong with my code in
this case. It seems pretty straightforward to me: I tell the
link_to_remote to replace the div, my very simple remote function
returns a span with a value in it, and somehow an <a> tag also gets
stuck in the response. Crazy.

Cody: the page is quite large including all the form selectors and
stuff. I really shouldn't post it here. That one before-and-after
element I pasted is really the only relevant portion of the output, I
just didn't paste the whole table that contains it (just a simple
3-column table with usually 1-5 rows).
Chris H. (Guest)
on 2006-03-17 13:53
(Received via mailing list)
that's not true.  i currently do much the same thing...

<td><input type="checkbox" id="active_flag_<%= user.id -%>"
name="active_flag_<%= user.id -%>" value="<%= user.id -%>" <%=
user.active?
? "checked" : "" -%> onclick="activate_user(this)"/>&nbsp;<label
id="user_<%= user.id -%>_label" for="active_flag_<%= user.id %>"><%=
user.active? ? "Active" : "<b>Inactive</b>" -%></label></td>

and mine's even more disturbing than Ryan's example! :)

anyways, i update the label tag in that mess.  clicking on the checkbox
calls a js function:

function activate_user(cb) {
    var status = (cb.checked) ? "1" : "0";

    data = "id=" + cb.value + "&af=" + status
    var myAjax = new Ajax.Request('/admin/users/activate',
                                    {method: 'post',
                                    parameters: data});
}

this js calls the activate action and the view is an rjs template

if @params[:af] == "1"
    page.visual_effect :highlight, "user_#{@params[:id]}", { :startcolor
=>
"'#aaffaa'" }
    page.replace_html "user_#{@params[:id]}_label", "Active"
else
    page.visual_effect :highlight, "user_#{@params[:id]}", { :startcolor
=>
"'#ffaaaa'" }
    page.replace_html "user_#{@params[:id]}_label", "<b>Inactive</b>"
end

so what happens here, is when a box is checked/unchecked, the user
account
gets activated/inactivated on the backend, the label next to the
checkbox
gets changed to Active/Inactive and the row in the table gets
highlighted
green/red.  works fine.

Chris
Ryan E. (Guest)
on 2006-03-17 19:09
Thanks for the ideas, Chris. I don't really want to run edge rails but
I'm going to try using the rjs templates plugin and see if doing the
update that way makes any difference. Would be nice if the fix is that
easy. :)
Ryan E. (Guest)
on 2006-03-17 20:41
I've got it working so here's the solution, in case anyone else runs
into this. I switched to an rjs template to do the update and it didn't
fix the problem but I'm still using it after I fixed the problem
elsewhere. What I had to do was simplify the updated element. If there
is no div or span or anything inside the link and I replace the whole
link on remote update, then it works.

Here's the generated source:

<div id="contact_active_13">
<a href="#" onclick="new
Ajax.Request('/contacts/toggle_contact_method/13', {asynchronous:true,
evalScripts:true}); return false;">false</a>
</div>

The view code that generates it:

<div id="contact_active_<%= cm.id %>">
<%= link_to_remote cm.active, :url => {:action =>
"toggle_contact_method", :id => cm.id} %>
</div>

And the rjs template:

page.replace_html "contact_active_#{@contact_method.id}",
link_to_remote( @contact_method.active, :url => {:action =>
"toggle_contact_method", :id => @contact_method.id} )

I might throw that link_to_remote part into a partial and add a css
class to the anchor the way I was trying to do it with an embedded span
before, but anyway that's the basic setup that is working for me.
This topic is locked and can not be replied to.