使用两个提交按钮提交jQuery ajax表单

21

我有一个长这样的表单:

<form action="/vote/" method="post" class="vote_form">
    <input type="hidden" name="question_id" value="10" />
    <input type="image" src="vote_down.png" class="vote_down" name="submit" value="down" />
    <input type="image" src="vote_up.png" class="vote_up" name="submit" value="up" />
</form>

当我绑定表单的提交事件($("vote_form").submit())时,似乎无法访问用户点击的是哪个图像。因此,我试图绑定到图像本身的点击事件($(".vote_down, .vote_up").click()),不管我尝试使用以下内容:
  • return false;
  • event.stopPropogation(); 或者
  • event.preventDefault();

因为这些都是表单事件所以它们总是会提交表单。

  1. 我应该将我的$.post()附加到form.submit()事件上吗?如果是这样,如何告诉我用户单击了哪个输入框?或者

  2. 我应该将我的$.post()附加到图像点击事件上吗?如果是这样,如何防止表单也被提交。

这是我的jQuery代码:

$(".vote_up, .vote_down").click(function (event) {
    $form = $(this).parent("form");
    $.post($form.attr("action"), $form.find("input").serialize() + {
        'submit': $(this).attr("value")
    }, function (data) {
        // do something with data
    });
    return false; // <--- This doesn't prevent form from submitting; what does!?
});
8个回答

29
基于 Emmett 的回答,我认为最理想的解决方法就是使用 JavaScript 禁止表单的提交,像这样:
$(".vote_form").submit(function() { return false; });

这完全行得通。

为了完整起见,我在原帖中的某些 JS 代码需要一些改进。例如,我添加到 serialize 函数的方式似乎不起作用。以下方式可以解决:

    $form.serialize() + "&submit="+ $(this).attr("value")

以下是我的完整jQuery代码:

$(".vote_form").submit(function() { return false; });
$(".vote_up, .vote_down").click(function(event) {
    $form = $(this).parent("form");
    $.post($form.attr("action"), $form.serialize() + "&submit="+ $(this).attr("value"), function(data) {
        // do something with response (data)
    });
});

非常感谢您的帮助。这大大缩短了我现有尝试的时间! - mhenrixon
1
为什么不使用$ this.attr("name")来避免硬编码"&submit =" - Bengt
@bngtlrs 我猜是因为这是一个函数调用开销,而这只是不必要的。 - PaulSkinner
1
@PaulSkinner 是的,在这里调用函数是不必要的,但我不会将其称为开销,因为它通常不会被频繁调用。我的赌注是,可重用性将值得省略可能过早的优化。 - Bengt
我正在使用.ajaxForm(),我的自动发送解决方案是.ajaxForm({}).submit();。将在没有提交按钮和自定义事件的情况下发送ajax调用。 - user1954544

4
另一种解决方案是使用隐藏字段,并在单击事件中更新其值。这样可以从JavaScript访问它,以及在服务器端,因为隐藏字段将被提交。

2

您可以在单击图像时触发表单提交。这将与preventDefault()一起使用。

var vote;
$(".vote_up, .vote_down").click(function(event) {
    vote = $(this).attr("class");
    $(".vote_form").trigger("submit");
});

$(".vote_form").submit(function(event) { 
    $form = $(this);
    $.post($form.attr("action"), $form.serialize() + "&submit="+ vote, function(data) {
        // do something with response (data)
    });     
    event.preventDefault();
});

1
我不明白为什么 return falsepreventDefault 没有发挥作用。也许尝试用链接图片替换图像按钮:
<a href="#" class="vote_down"><img src="vote_down.png"/></a>

$('#vote_form > a').click(function(e) {
    e.preventDefault();

    //one way to know which image was clicked
    alert($(this).attr('class'));

    $.post(...
});

您可以通过绑定提交事件来确保表单不会被提交,例如:

$('#vote_form').submit(function() {
    return false;
});

就像我在问题中所说的那样,我已经按照你在第二部分中建议的做了,但我无法访问用户单击的输入。此外,我不想切换到链接图像——虽然这可能适用于Ajax,但我仍希望我的表单对没有JavaScript的用户起作用,就像它目前所做的那样(而使用普通图像则不能)。 - worksology

0

0
尝试在表单中添加onsubmit="return false;",然后使用JavaScript提交表单:
<form action="/vote/" method="post" name="vote_form" class="vote_form" onsubmit="return false;">
    <input type="hidden" name="question_id" value="10" />
    <input type="image" src="vote_down.png" class="vote_down" name="submit" value="down" onclick="imageClicked(this)"/>
    <input type="image" src="vote_up.png" class="vote_up" name="submit" value="up" onclick="imageClicked(this)"/>
</form>

<script>
function imageClicked(img) {
    alert(img.className);
    document.forms["vote_form"].submit();
}
</script>

虽然我并不认为这是一个优雅的解决方案,但它确实帮我找到了一个可行的解决方法,就是添加:$(".vote_form").submit(function() { return false; });(我肯定不想在表单中添加 "onsubmit='return false;' ",因为我希望表单在没有Ajax的情况下正常工作。) - worksology

0

不要求借助表单插件(虽然你应该使用它),而是应该通过处理提交事件来完成。代码将与原始代码非常接近:

$("form").submit(function()) {
  $.post($(this).attr("action"), $(this).serialize(), function(data) {
    // work with the response
  });
  return false;
});

就像我在原始问题中所说的,我可以做到这一点,但是我仍然需要知道用户在此函数中单击了哪个图像输入。不幸的是,event.target == 表单。 - worksology

0
var form = jQuery('#myform');

var data = form.serialize();

// add the button to the form data
var btn = jQuery('button[name=mybuttonname]').attr('value');
data += '&yourpostname=' + btn;

var ajax = jQuery.ajax({
    url: url,
    type: 'POST',
    data: data,
    statusCode: {
        404: function () {
            alert("page not found");
        }
    }
});
... rest of your code ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接