表格失去了在2次ajax更新后发送POST请求的能力

时间:2010-10-29 15:39:16

标签: jquery ajax django django-forms xmlhttprequest

我有一个包含对象的表单:

<form method="post" class="object_form" id="event-core-form" action="{% url save_event_core_data event.id %}" enctype="multipart/form-data">
    {{ form.as_p }}
    <p>
        <input class="object-submit" id="object-data-save" type="submit" value="Save data">
    </p>
</form>

点击“提交”按钮后,我正在运行这个脚本,它通过ajax提交我的表单,更新数据,并应该返回更新的表单,将其插回到它的位置:

$("#object-data-save").livequery("click", function(e) {
    e.preventDefault();
    $(this).parents("form:first").ajaxSubmit({
        data: {"action": action},
        "success": function(data) {
            data = JSON.parse(data);
            $("#core-data").html(data["html"]);
            $("#message").show();
            $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>');
            setTimeout(function(){
                $("#message").fadeOut("slow", function () {
                    $("#message").hide();
                });

            }, 1500);                
        }
    });
    return false;
});

并运行以下功能:

def event_core_data(request, event_id):
    template_name="management/core_event.html"    
    event = Event.objects.get(pk=event_id)
    form = EventForm()

    if request.method == "POST":
        form = EventForm(instance=event, data=request.POST)
        message = _("Error saving data")
        if form.is_valid():
            form.save()
            message = _(u"Data saved.")

        html =  render_to_string(template_name, RequestContext(request, {
            "form" : form,
            "event" : event,
        }))

        result = simplejson.dumps({
            "html" : html,
            "message" : message,
        }, cls = LazyEncoder)

        result = HttpResponse(result)
        logging.debug(result)
    else:
        form = EventForm(instance=event)
        result = ""
        try:
            result = render_to_string(template_name, RequestContext(request, {
                "form" : form,
                "event" : event,
            }))
        except:
            pass

    return result

保存后,一切都按预期工作。但在第三次更新后,我的表单未插入父模板中。相反,我被重定向到编辑功能的url,表单呈现为原始html。另外,我在firebug中注意到,当我被重定向时 - 没有发送POST并且我的javascript中的虚拟'警报'没有被触发。 这是显示初始状态的函数(如果它有任何帮助):

def manage_event(request, event_id,):
    template_name = 'management/edit_event.html'

    try:
        event = Event.objects.get(pk=event_id)
    except DoesNotExist:
        url = reverse("manage_events")
        return HttpResponseRedirect(url)

    return render_to_response(template_name, RequestContext(request, {
        "core_data" : event_core_data(request, event_id),
        "event" : event,
    }))

修改

这是该项目的测试链接,您可以在其中查看正在进行的操作。 'event_core_data'在成功更新后将request.POST返回到控制台。

http://ntt.vipserv.org/manage/events/2

我也想知道为什么我的日期选择器小部件在提交后消失了。那些东西是以某种方式连接在一起的吗?


编辑2

我已经尝试过使用.post或.ajax而不是.ajaxSubmit但没有运气。

1 个答案:

答案 0 :(得分:1)

首先,你做的事情有些奇怪。你使用一个jQuery-plugin,它应该通过ajax处理表单提交并重新填充字段。不过,一旦成功,您将使用服务器中的HTML替换表单的所有HTML,否定其工作。

这会破坏您的日历/时间小部件,因为您在页面加载时初始化小部件,告诉他们对某些页面元素执行操作,您稍后会替换这些元素。

但这本身并不会破坏表单提交。

首先,如果您停止替换表单HTML,则不需要用于附加事件“live”的插件。其次,你真的不需要一个插件,因为看起来jQuery中的内置live()方法应该完成这项工作(也就是说,如果你确实需要这个功能)。第三,如果您使用插件并且它们似乎无法正常工作,请更新到最新版本。您正在使用的版本不支持jQuery中的html()方法。

livequery-plugin通过覆盖任何可能更新DOM的jQuery方法来实现其魔力。因此,当程序员调用f.ex,append()时,它会拦截调用,为您调用append(),然后检查文档中是否有与您提供的选择器匹配的新元素或消失元素。您使用的版本不知道html(),因此不会拦截它。

因此,当您在页面加载时启动DOM检查时,它会首次运行。返回该结果时,事件实际上附加到新的提交按钮,因为调用html()来设置新表单和完成消息在内部调用截获的方法。因此,第二次提交按预期工作。但是当第二次调用返回时,内部使用jQuery缓存,而不是调用任何截获的方法。因此,事件不会附加到提交按钮,使其充当常规表单提交按钮。

要修复,如果没有明显的需要,请停止使用实时附加进行事件监听。如果有,请使用内置的或至少更新您的livequery插件。另外,不要替换整个表单HTML。同样,如果存在非明显原因,请在每次设置HTML后重新初始化日历窗口小部件。