Форма теряет возможность отправлять POST-запросы после 2 обновлений ajax - PullRequest
4 голосов
/ 29 октября 2010

У меня есть форма включенного объекта:

<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,
    }))

EDIT

Вот тестовая ссылка на этот проект, гдеВы можете видеть, что происходит.'event_core_data' возвращает request.POST для консоли после успешного обновления.

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

Мне также интересно, почему мои виджеты выбора даты исчезают после отправки.Эти вещи как-то связаны друг с другом?


EDIT 2

Я уже пытался использовать .post или .ajax вместо .ajaxSubmit, но безуспешно.

1 Ответ

1 голос
/ 31 октября 2010

Прежде всего, вы делаете что-то немного странное. Вы используете jQuery-плагин, который должен обрабатывать отправку формы через ajax и заполнять поля. Тем не менее, в случае успеха вы заменяете весь HTML-код вашей формы HTML-кодом с сервера, сводя на нет его работу.

Это разрушает ваши виджеты календаря / времени, когда вы инициализируете виджеты при загрузке страницы, говоря им действовать на некоторых элементах страницы, которые вы позже замените.

Но это само по себе не нарушает отправку формы.

Во-первых, вам не нужен плагин для прикрепления событий «вживую», если вы перестанете заменять форму HTML. Во-вторых, вам все равно не нужен плагин для этого, так как кажется, что встроенный метод live() в jQuery должен выполнять эту работу (то есть, если вам действительно нужна эта функция). В-третьих, если вы используете плагины и они, кажется, не работают должным образом, обновитесь до последней версии. Версия, которую вы используете, не поддерживает метод html() в jQuery.

Плагин livequery совершает свою магию, переопределяя все jQuery-методы, которые могут обновлять DOM. Поэтому, когда программист вызывает f.ex, append(), он перехватывает вызов, вызывает для вас append(), а затем проверяет документ на наличие новых или пропавших элементов, соответствующих предоставленному вами селектору. Версия, которую вы используете, не знает о html() и поэтому не перехватывает ее.

Так что он работает в первый раз, когда вы запускаете проверку DOM при загрузке страницы. Когда этот результат возвращается, событие фактически присоединяется к новой кнопке отправки, потому что вызовы html() для установки новой формы и сообщения о завершении внутренне вызывают перехваченные методы. Поэтому вторая подача работает по желанию. Но когда возвращается второй вызов, кеш jQuery используется внутри, не вызывая перехваченных методов. Таким образом, событие не привязывается к кнопке отправки, поэтому оно действует как кнопка отправки обычной формы.

Чтобы исправить, прекратите использовать live-attaching для прослушивания событий, если в этом нет явной необходимости. Если есть, используйте встроенный или, по крайней мере, обновите плагин livequery. Кроме того, не заменяйте всю форму HTML. Опять же, если есть неочевидная причина, каждый раз после установки HTML-кода инициализируйте ваш виджет календаря.

...