开发者

MVC 2.0 Ajax: auto-submit on dropdown list causes normal postback

开发者 https://www.devze.com 2023-02-06 23:09 出处:网络
I am trying to add Ajax functionality to my MVC application. I want a form to post back asynchronously. Here\'s the form code:

I am trying to add Ajax functionality to my MVC application. I want a form to post back asynchronously. Here's the form code:

using (Ajax.BeginForm("SetInterviewee", "Date", routeValues, new AjaxOptions { UpdateTargetId = "divInterviewee" }))

and I want it to automatically post back when a dropdown list selected value changes:

<%= Html.DropDownList("interviewees", Model.interviewees.intervieweeLists.intervieweesList, "-- select employee --", new { @class = "ddltext", style = "width: 200px", onchange = "this.form.submit();" })%>

However, when I try this out, the program posts back normally, not a partial postback as I was expecting. Here's what I think the problem is: onchange = "this.form.submit();" in the dropdown list.

I think that this somehow causes a normal postback instead of the asynchronous postback.

Here's what MVC generates for HTML for the form tag:

<form action="/SetInterviewee/2011-1-26/2011-1/visit" method="post" onclick="Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEven开发者_C百科t(event));" onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: &#39;divInterviewee&#39; });">

I think that with "this.form.submit()" the "onsubmit" event handler is not being called. The thing is, I don't understand why. Wouldn't "onsubmit" catch any event that submits the form?

UPDATE: I went to jquery, thusly:

        $(function () {
        $('#interviewees').change(function () {
            var form = $('#intervieweeForm');
            $.ajax({
                url: form.attr('action'),
                type: form.attr('method'),
                data: form.serialize(),
                success: function (result) {
                    $('#selectedInterviewee').val(result);
                }
            });
        });
    });

This is causing many problems, among them:

-- It still does not seem to do an asyncrhonous postback. In my controller action method, I have the following code: "if (Request.IsAjaxRequest())" which returns false.

-- I can't seem to do model binding any more. My route looks like :

http://localhost:1986/Interviews/2011-2-25/2011-2/visit

but the route that apparently ends up being sent is

http://localhost:1986/SetInterviewee/2011-2-25/2011-2?
Count=5&Keys=System.Collections.Generic.Dictionary`2+KeyCollection
[System.String,System.Object]
&Values=System.Collections.Generic.Dictionary`2+ValueCollection
[System.String,System.Object]

causing the model binding not to work -- "visit" is supposed to be a "mode" parameter, but it's not there so "mode" defaults to "phone", which upsets the whole applecart.

It is the serialize command that is causing this? I don't understand why it would append it to the querystring when the method is POST.

There are other things -- among them, the fact that my action must return a ViewResult, so how can I possibly just return a string, which is all I need using ajax ... but I will defer that concern until I get the routing/binding thing straightened out!

UPDATE: "SetInterviewee" is indeed the correct route to post to, but the routeValues parameter should copy the route values from the current view -- I would think. Here's the code for the form:

RouteValueDictionary routeValues = ViewContext.RouteData.Values;
using (Html.BeginForm("SetInterviewee", "Date", routeValues, FormMethod.Post, new { id = "intervieweeForm" }))


So I know this is quite an old question, but I've been messing around with a similar issue and seem to come to a workaround that might prove useful in the future.

Inside your form, add a submit button. Something like:

<input type="submit" name="submit" value="save" style="display: none;" />

Make sure that you have specified the name attribute as it seems to matter in this case. Here is the code I have an it is currently working with full model binding:

<% using (Ajax.BeginForm("SaveStatus", "Finding", new { FindingId = Model.FindingId },
       new AjaxOptions {
           HttpMethod = "Post",
           InsertionMode = InsertionMode.Replace,
           UpdateTargetId = "StatusWindow",
           OnBegin = "function(){ jQuery('#SaveStatusForm').block({ Message: 'Saving' }); }",
           OnComplete = "function(){ jQuery('#SaveStatusForm').unblock(); }",
           OnFailure = "HandleMSAjaxFail",
       }, new { id = "SaveStatusForm" })) { %>
<div>
    <%: Html.DropDownListFor(Status => Status.SelectedTagId, Model.AvailableStatuses, null, new Dictionary<string, object> { { "onchange", "jQuery('#SaveStatusForm').submit();" } })%>
    <input type="submit" name="submit" value="save" style="display: none;" />
</div>
<% } %>

Granted this is my code and not tied to your example, but you can get the idea from what is going on. Originally I had the dropdownlist just doing a submit and when it fired I was getting all sorts of quirky responses - including a full synchronous postback. When I added the submit button, the MS ajax code seems to work beautifully. Give it a shot!


I would recommend you to use jquery and get rid of all Ajax.* helpers and MSAjax scripts.

So:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

<% using (Html.BeginForm("SetInterviewee", "Date", routeValues, FormMethod.Post, new { id = "myform" })) { %>
    ...
<% } %>

<%= Html.DropDownList(
    "interviewees", 
    Model.interviewees.intervieweeLists.intervieweesList, 
    "-- select employee --", 
    new { id = "interviewees", @class = "ddltext", style = "width: 200px" }
)%>

and then in a separate javascript file:

$(function() {
    $('#interviewees').change(function() {
        var form = $('#myform');
        $.ajax({
            url: form.attr('action'),
            type: form.attr('method'),
            data: form.serialize(),
            success: function(result) {
                 $('#divInterviewee').html(result);
            }
        });
    });
});

Now we have successfully separated HTML markup from javascript. It is unobtrusive javascript.

0

精彩评论

暂无评论...
验证码 换一张
取 消