views:

525

answers:

2

I have a table with each row as an ascx. This control consists of a Ajax form which includes cells which might have inputs. Here is the ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Models.Dinner>" %>


    <%  using (Ajax.BeginForm("ViewAll", new AjaxOptions
        {UpdateTargetId = "Dinner" + Model.DinnerID, InsertionMode = InsertionMode.InsertAfter, OnSuccess = "jsfunction"
        })) {%>

            <%= Html.Hidden("ID", Model.DinnerID)%>
            <td><input type="submit" value="Save" /></td>
            <td><strong>'<%=Model.Title%>'</strong></td>
            <td><%=Model.EventDate.ToShortTimeString()%> on <%=Model.EventDate.ToShortDateString()%></td>
            <td><%=Model.Address%></td>
            <td><%= Html.TextBox("HostedBy", Model.HostedBy)%></td>       
            <td><%= Html.ActionLink("Edit", "Edit", new { id = Model.DinnerID })%></td>

    <%} %>

After a submit, I complete my processing and send back the updated ascx to replace the existing one. However this ascx gets constructed a little different than the original which causes it to render incorrectly

This is what the original ascx looks like in FF:

<tr id="Dinner5">
<form onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.insertAfter, updateTargetId: 'Dinner5', onSuccess: Function.createDelegate(this, jsfunction) });" method="post" action="/NerdDinner/Dinners/ViewAll"/>
<input id="ID" type="hidden" value="5" name="ID"/>
<td>
</td>
<td>
</td>
<td>12:00 AM on 2/2/2010</td>
<td>ZSA2</td>
<td>
</td>
<td>
</td>
</tr>

This is what the returned control (ajaxContext.get_data()) looks like:

<tr id="Dinner1">
<form onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: 'Dinner1' });" method="post" action="/NerdDinner/Dinners/ViewAll">
<input id="ID" type="hidden" value="1" name="ID"/>
<td>
</td>
<td>
</td>
<td>12:00 AM on 1/1/2010</td>
<td>ZSA1</td>
<td class="red-back">
</td>
<td>
</td>
</form>
</tr>

Notice the latter does not contain any tds directly under tr but the form encloses all tds and so nothing is rendered. In IE, I get an error saying 'htmlfile: Unknown runtime error' in MicrosoftAjax.js.

I'm sure I'm missing something basic here. Any help would be appreciated. Thanks.

A: 

A few things. This code from your original snippet doesn't look quite right as the input is outside of the form. If you notice the end of the form tag is self closing in this case.

<form onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.insertAfter, updateTargetId: 'Dinner5', onSuccess: Function.createDelegate(this, jsfunction) });" method="post" action="/NerdDinner/Dinners/ViewAll"/>
<input id="ID" type="hidden" value="5" name="ID"/>

In your code below it appears as though you're explicitly telling the form to encapsulate all of the td's, note the positioning of the curly braces for the BeginForm method.

<%  using (Ajax.BeginForm("ViewAll", new AjaxOptions
    {UpdateTargetId = "Dinner" + Model.DinnerID, InsertionMode = InsertionMode.InsertAfter, OnSuccess = "jsfunction"
    })) {%>

        <%= Html.Hidden("ID", Model.DinnerID)%>
        <td><input type="submit" value="Save" /></td>
        <td><strong>'<%=Model.Title%>'</strong></td>
        <td><%=Model.EventDate.ToShortTimeString()%> on <%=Model.EventDate.ToShortDateString()%></td>
        <td><%=Model.Address%></td>
        <td><%= Html.TextBox("HostedBy", Model.HostedBy)%></td>       
        <td><%= Html.ActionLink("Edit", "Edit", new { id = Model.DinnerID })%></td>

<%} %>

I'm not quite sure what you're trying to accomplish but hopefully this gets you started in the right direction.

How about using a nested table? This should help it in Firefox.

<td>
<%  using (Ajax.BeginForm("ViewAll", new AjaxOptions
    {UpdateTargetId = "Dinner" + Model.DinnerID, InsertionMode = InsertionMode.InsertAfter, OnSuccess = "jsfunction"
    })) {%>

        <%= Html.Hidden("ID", Model.DinnerID)%>
        <table><tr>
        <td><input type="submit" value="Save" /></td>
        <td><strong>'<%=Model.Title%>'</strong></td>
        <td><%=Model.EventDate.ToShortTimeString()%> on <%=Model.EventDate.ToShortDateString()%></td>
        <td><%=Model.Address%></td>
        <td><%= Html.TextBox("HostedBy", Model.HostedBy)%></td>       
        <td><%= Html.ActionLink("Edit", "Edit", new { id = Model.DinnerID })%></td>
        </tr>
        </table>
<%} %>
</td>
r-dub
I do not know why the original snippet has the form with a self closing tag. This is how Firebug showed the ascx.And yes, I am telling the form to encapsulate td's as they might contain some input elements.I tried moving the form out of tr instead of within tr but that didn't work either.
Try a nested table and see if that works in Firefox.
r-dub
Ya, I figured I cannot place a form inside a tr directly. My next option is to have each tr contain a single td which encloses a table inside a form. The nested table would consist of 1 row only. I am reluctant to take this approach however, as this may make sorting of the overall table quite cumbersome. Any thoughts about this?
I'd try not to get too caught up with having to use forms. You can post whatever you need with AJAX requests so there really isn't any need to have a form for each row.
r-dub
OK, how would I post input elements using AJAX request without using in AJAX form in MVC?Thanks for all your answers, r-dub. Its keeping my hopes alive...
Look at the Adapting the URL Dynamically section of http://www.aspnetpro.com/articles/2009/06/asp200906de_f/asp200906de_f.asp, it shows you how to make a normal ajax call without a form using Ajax.ActionLink(). Good luck
r-dub
A: 

Interesting- i ran into this EXACT problem just a few minutes ago.

Apparently, IE8 does not like to update elements, only divs.

this blog post got me on the right path, and i just used a div as my updatetargetid rather than the i was originally using. it's ugly now, but at least it works. i need to figure out how to make it look a little nicer.

hope this helps some!

Jamie M