views:

604

answers:

3

I was following the example laid out here for implementing AJAX panels in MVC. I'm using VB.NET, but the conversion is pretty straightforward. However, I can't seem to get it to work, and I'm running out of ideas as to why. Here is my code:

HomeController:

Function Index() As ActionResult
    Return View()
End Function

Function Archive() As ActionResult
    Threading.Thread.Sleep(5000)
    Return View()
End Function

Archive.ascx (partial view):

<%@ Control Language="VB" Inherits="System.Web.Mvc.ViewUserControl" %>
Hello World

Index.aspx (view):

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="body" runat="server">
    <% Using Ajax.BeginForm("Archive", "Home", Nothing, New AjaxOptions With {.UpdateTargetId = "resultDiv"}, New With {.id = "reportFormOne"})%>
    <% End Using%>
    <div id="resultDiv">
        <img src="../../Content/images/ajax-loader.gif" alt="" />
    </div>

    <script type="text/javascript" src='<%= Url.Content("~/Scripts/jquery-1.3.2.min.js") %>'></script>

    <script type="text/javascript">

        $get("reportFormOne").onsubmit();

    </script>

</asp:Content>

When I run it, all I see is the ajax-loader animation endlessly. When I run it in debug mode, it never seems to trigger the Archive action. Can anyone see what I'm missing?

UPDATE: Thanks to @Joseph for pointing out that jQuery wasn't loaded. Now it is, but I'm getting "Object expected" on the $get call.

UPDATE 2: Here's what Index.aspx looks like now with the "document ready" code. It's giving me a "Object doesn't support this property or method" error with this configuration.

<script type="text/javascript" src='<%= Url.Content("~/Scripts/jquery-1.3.2.min.js") %>'></script>
<script type="text/javascript" src='<%= Url.Content("~/Scripts/MicrosoftAjax.js") %>'></script>
<script type="text/javascript" src='<%= Url.Content("~/Scripts/MicrosoftMvcAjax.js") %>'></script>

<script type="text/javascript">

    $(document).ready(function() {
        $("#reportFormOne").submit();
    });

</script>

<% Using Ajax.BeginForm("Archive", "Home", Nothing, New AjaxOptions With {.UpdateTargetId = "resultDiv"}, New With {.id = "reportFormOne"})%>
<% End Using%>
<div id="resultDiv">
    <img src="../../Content/images/ajax-loader.gif" alt="" />
</div>

UPDATE 3: Realized it was choking on "onsubmit". Changed it to "submit" and it functioned. However, after changing the delay to 5 seconds, the animated gif did not spin - it just stayed static for 5 seconds, then the whole page was replaced by "Hello World" instead of just replacing the animated gif in the div. AAARRRGGGHHH!

UPDATE 4: Added missing AJAX libraries to the code in Update 2. This still doesn't work correctly, but if I don't use the jQuery submit and instead add a Submit button to the form, it works correctly. Why?

+2  A: 

Are you sure you have jquery loaded? If not then you'll never call your webmethod.

If you do have it loaded I would try putting your script inside document.ready() to make sure it gets executed at the correct time.

something like this:

$(document).ready(function () {
    $("#reportFormOne").submit();
});
Joseph
Wow. You'd think that would be in there, wouldn't you? I assumed it was in Site.Master and it wasn't. I've added it and now I'm getting a javascript error. I've updated the issue. Thanks for pointing out the obvious.
gfrizzle
@gfrizzle You never know =) Also, I would try wrapping that inside a document.ready() just to make sure everything is loaded before you try to execute that jquery script
Joseph
+1  A: 

The AjaxHelper class (Ajax.BeginForm()) uses the Microsoft AJAX libraries. It doesn't look like you're referencing them. Add them to your master page

<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

Alternatively, you can use the jQuery Form plugin. Replace your Ajax.BeginForm() with an Html.BeginForm() and do something like this. In this approach, we'll load the ajax image dynamically, so take out the <img> tag from resultDiv.

    <script type="text/javascript" src="/path/to/jquery.form.js"></script>
    $(function(){

 $("#reportFormOne").ajaxForm({
  target: "#resultDiv",
  resetForm: true,
  beforeSubmit: function() {
     $("<img>").attr("src", "../../Content/images/ajax-loader.gif").appendTo("#resultDiv");
  },
  success: function(data) {
     $("#resultDiv").hide().html(data).fadeIn("fast");
  }
 }); 

});

Also, you should make sure it's an AJAX request in your Archive action. (My VB is rusty. You simply need to check for Request.IsAjaxRequest())

Function Archive() As ActionResult
    Threading.Thread.Sleep(5000)

    If(Request.IsAjaxRequest())
      Return PartialView()
    End If 

    Return View()
End Function
Ben Robbins
Adding the AJAX libraries didn't help - it still returned a new page with just "Hello World". I've also tried your jQuery method, but I'm getting "Object doesn't support this property or method" on the ajaxForm line.
gfrizzle
Oops, my bad - typo in the library names. I'm closer now. It still behaves incorrectly with the right library names, but if I remove the jQuery submit and add a Submit button, it works correctly. Is the jQuery submit happening too quickly?
gfrizzle
A: 

If you have any forms on the partial, try removing them. If it works then, it means they are not being called properly.

The same has happened to me twice. It could be your problem too...

Fabio Milheiro