开发者

jQuery not calling form .submit() when using Ajax on IE

I am using a jQuery plugin that does some magic during the .submit of a form (creates a hidden string and writes it to an <input type="hidden"> item). On IE this works well if I submit the form via POST, but if I use Ajax, then the .submit callback is never called. Here is an example of the flow:

<script type="text/javascript">
    (function (jQuery) {
        jQuery.fn.createHidden = function () {
            // 1. What I want to have called
            $(this).submit(function () {
                var hiddenText = $(document.createElement('input'));
                hiddenText.attr('name', 'hidden');
                hiddenText.attr('type', 'hidden');
                hiddenText.val('1');
                $(this).append(hiddenText);
                alert("1");
            });
            // 2. What I came up with as a workaround
            $(this).parents('div.FormWrapper').submit(function () {
                var form = this.children('form');
                if (form && form.tagName == "FORM") {
                    var hiddenText = $(document.createElement('input'));
                    hiddenText.attr('name', 'hidden');
                    hiddenText.attr('type', 'hidden');
                    hiddenText.val('2');
                    $(form).append(hiddenText);
                    alert("2");
                }
            });
        };
    })(jQuery);
</script>

<script type="text/javascript">
    $(document).ready(function () {
        $(".form").createHidden();
    });
</script>

<div class="FormWrapper">
@*using (Html.BeginForm("About", "Home", FormMethod.Post, new { @class = "form", @id = "form" }))*@
@using (Ajax.BeginForm("About", "Home", new AjaxOptions { UpdateTargetId = "myReply", HttpMethod = "post" }, new { @class = "form", @id = "form" }))
{
    <div class="ExposedData">
        @Html.TextBox("data", "", new { @class = "dat开发者_运维问答a" })
        <input type="submit" value="Button" />
        <span id="myReply"></span>
    </div>
}
</div>  
// MVC HomeController.cs
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public string About(string hidden)
    {
        return hidden;
    }
}

When using Http POST on IE, I see alerts 1 & 2, but when using Ajax I only see alert 2. Firefox only shows 1. Chrome, Safari and Opera show 1 & 2.

Is there a better way of fixing this so it works on all browsers? Could this be related to the jquery.unobtrusive-ajax.js I'm using in MVC3?

I've tried $('form').ajaxStart(), AjaxOptions{OnBegin=...}, <form onsubmit=...> but they didn't do the trick as most get called after the controller is visited, and hence the hiddenText is not included in the form.


You should try the jQuery froms plugin - works in all browsers.

And maybe get rid of the idea that a form has to submit, AJAX requires no forms.

Hidden inputs inside forms are not really recommend, can be easily manipulated.

Edit:

Including a plug-in into a plug-in is probably not the best way...

I'd rather recommend to use the native $.ajax function, here's a real-world example I just wrote:

$('li.sheet').unbind().bind('click', function() {
    $.id = $(this).attr('id');
    if($(this).next('div.edit').length == 0){
        $.ajax({
                url: 'ajax_handler.php?mode=form&sheet='+$.id,
                success:function(r){
                    $('li#'+$.id).after(r);
                    $('li#'+$.id).next('div.edit').toggle(200);
                }
        });
    }
    else {
        $(this).next('div.edit').toggle(200, function(){
            $(this).remove();
        });
    }
});


If all you want to do is include more data in the ajax request then I recommend using the data paremeter:

$.ajax(...,
       data: {
           hidden: function() { ...build string here...  } 
       });


It looks like your second alert comes from trying to catch a submit event on a div. That is definitely going to be a weird, inconsistent event.

What could be happening is that your createHidden is being attached to the form after the unobtrusive-ajax is being attached. So, when you submit, it'll call unobtrusive-ajax first, which most likely stops propagation of the event to other functions.

Try taking of unobtrusive-ajax and submitting again, see if your function fires. If so, you'll have to try to figure out how to attach createHidden first or use something other than unobtrusive-ajax.


I was hoping I would find a way of using Ajax.BeginForm() and not have to touch the external plugin I'm using, but at the end I followed the advice given, and this is what came out of it:

<script type="text/javascript">
    $(document).ready(function () {
        $('.form').createHidden();
        $('.form').unbind('submit.plugin').bind('submit.mything', function (event) {
            event.preventDefault();
            $.ajax({
                url: '/Home/About',
                data: { hidden: $('.form').getHidden() },
                success: function (reply) { $('#myReply').html(reply); }
            });
        });
    });

    (function (jQuery) {
        jQuery.fn.createHidden = function () {
            jQuery.fn.getHidden = function () {
                return 'message';
            };
            $(this).bind('submit.plugin', function () {
                // let it do whatever it does...
            });
        };
    })(jQuery);
</script>

@using (Html.BeginForm("About", "Home", FormMethod.Post, new { @class = "form", @id = "form" }))
{
    @Html.TextBox("data", "", new { @class = "data" })
    <input type="submit" value="Button" />
}
<div id="myReply"></div>
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜