JQuery Модальное диалоговое окно подтверждения не отправляет форму

Я пытаюсь выставить подтверждение, когда пользователь нажимает кнопку удаления в форме редактирования. Модальные всплывают хорошо, но когда jQuery должен отправлять форму, это ничего не делает. Я удаляю как тип = "button", потому что когда он имеет тип отправки, модальная функция не удерживает процесс, и он просто удаляет пользователя сразу.

HTML...

- EDIT -

(я добавил теги <form>)

<form action="/admin/edit-user" enctype="application/x-www-form-urlencoded" method="post" name="edit_user_form" id="edit_user_form">
...
<p><input type="submit" value="Save" name="submit" id="submit"/></p>
<p><input type="submit" value="Cancel" name="cancel" id="cancel"/></p>         
<p><input type="button" value="Delete User" name="delete_btn" id="delete_btn" onclick="confirmDeleteUser();"/></p>
...
</form>

...

<div id="dialog-modal" title="Confirm Delete User">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0 0;"></span> Are you sure you wish to delete this user?</p>
<p>To continue editing, click cancel.</p>
</div>

Javascript:

   function confirmDeleteUser()
    {    
        $('#dialog-modal').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,

            buttons: {
                "Cancel": function() {
                    $(this).dialog("close");
                    return false;
                },
                "Delete User": function() {
                    var self = $(this);
                    var form = $('#edit_user_form');
                    tmpElm = $('<input type="hidden" />');
                    tmpElm.attr('name', 'delete');
                    tmpElm.attr('id', 'delete');
                    tmpElm.val(true);
                    tmpElm.appendTo(form);
                    form.submit();
                    return true;
                }
            }
        });
        $('#dialog-modal').dialog('open');
    }

Когда я проверяю исходный код, я вижу, что код правильно добавляет новый скрытый элемент, но подчинение просто похоже не хочет запускать. Какой шаг мне не хватает?

Ответ 1

Попробуйте по-другому.


HTML

Ваш html имеет следующее: onclick="confirmDeleteUser();"

Почему? jQuery должен сделать это проще для вас, не сложнее.

Ваш HTML должен быть чистым и не вызывающим функциями (за исключением крайне экстремальных обстоятельств, с которыми вы вряд ли столкнетесь). Почему бы не использовать библиотеку jQuery для привязки события к элементу, вместо того, чтобы смешивать вызовы функций javascript в ваш HTML? Вы должны делать что-то подобное в тегах <script> после утверждения документа.

$("#delete_btn").click(function(e){
    /*Code that runs on click of the "delete_btn" ID tag*/
});

Если вы не знакомы с селекторами и событиями jQuery, тогда начните читать здесь.

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


CSS

Вы также сделали это: style="float:left; margin:0 7px 0 0;" в теге HTML? Это зло, чувак. Просто зло. Как я буду поддерживать этот код через пять месяцев?

Вместо этого используйте CSS.

В ваших тегах или файле CSS вам нужна запись, например:

.dialogAdjust {
    float: left;
    margin: 0 7px 0 0;
}

Затем в вашем HTML вы скажете:

<span class="ui-icon ui-icon-alert dialogAdjust"></span>

И теперь вы можете настроить это на свое сердце. Лучше, если вы можете сделать класс в диалоге div, а не отдельные элементы HTML, и в этом случае вы абсолютно можете.


JavaScript

Хокай, вот, вот твоя функция:

  function confirmDeleteUser()
    {    
        $('#dialog-modal').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,

            buttons: {
                "Cancel": function() {
                    $(this).dialog("close");
                    return false;
                },
                "Delete User": function() {
                    var self = $(this);
                    var form = $('#edit_user_form');
                    tmpElm = $('<input type="hidden" />');
                    tmpElm.prop('name', 'delete');
                    tmpElm.prop('id', 'delete');
                    tmpElm.val(true);
                    tmpElm.appendTo(form);
                    form.submit();
                    return true;
                }
            }
        });
        $('#dialog-modal').dialog('open');
    }

Что здесь происходит? На первом этапе вы должны попробовать и использовать инструмент для измерения качества кода. Два популярных: JSHint и JSLint. Вам не нужно следить за тем, что они говорят, что это единственный способ написать свой код, но он очень полезен в поиске ошибок из-за небольших ошибок. Мне нравится JSHint, поэтому мы будем запускать это через.

И вот вывод:

Errors:

Line 17 tmpElm = $('<input type="hidden" />');
'tmpElm' is not defined.
Line 18 tmpElm.attr('name', 'delete');
'tmpElm' is not defined.
Line 19 tmpElm.attr('id', 'delete');
'tmpElm' is not defined.
Line 20 tmpElm.val(true);
'tmpElm' is not defined.
Line 21 tmpElm.appendTo(form);
'tmpElm' is not defined.

К сожалению. Похоже, у вас есть переменная undefined, то есть теперь она глобальная. Глобальные переменные являются плохими, они ломают область действия и могут сделать вашу функцию кода странным образом.

Нам нужно это исправить. Вы всегда должны объявлять локальные переменные в локальной области. Это означает, что var tempElm; находится в верхней части функции "Удалить пользователя".

Уберите эту оболочку, она вам не понадобится. Ваш код должен создавать объект диалога и код при загрузке документа и открывать диалоговое окно при нажатии. Что происходит в вашем исходном коде, создавая диалог и открывая его каждый раз, когда вы нажимаете эту кнопку. В чем проблема? Вы продолжаете создавать объект, даже если он создан. Вы создаете тот же объект снова и снова и снова. В этой реализации вы не заметите этого, но ваш дизайн будет перенесен в места, где он будет, если вы не заметите этого сейчас.

Итак, как это выглядит? В тэге <head> вы должны увидеть что-то вроде этого:

<script>

    /*
        This makes all the code inside
        run when the window is done loading, 
        not before, which may cause issues.
    */
    $(window).load(function(){    


        /*
            This sets up the dialog 
            as you've described before
        */
        $('#dialog-modal').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,

            buttons: {
                "Cancel": function() {
                    $(this).dialog("close");
                    return false;
                },
                "Delete User": function() {
                    var self = $(this);
                    var form = $('#edit_user_form');
                    //We've added the var infront of tepElem
                    var tmpElm = $('<input type="hidden" />');
                    tmpElm.prop('name', 'delete');
                    tmpElm.prop('id', 'delete');
                    tmpElm.val(true);
                    tmpElm.appendTo(form);
                    form.submit();
                    return true;
                }
            }
        });

        /*
            This is the part where I talked 
            about selectors and events in the HTML
        */
        $("#delete_btn").click(function(e){
            $('#dialog-modal').dialog('open');
        });
    });
</script>

При обращении за помощью используйте инструмент jsFiddle для отправки JavaScript, чтобы облегчить другим людям помощь.

Здесь jsFiddle изменений, которые мы сделали до сих пор. Потратьте немного времени на изучение того, как использовать его, если вы много работаете в JavaScript и хотите быстро протестировать.

Вот почему я хотел, чтобы вы изучили jsFiddle:

Вы не дали нам достаточно кода для успешной работы, что привело к тому, что я написал эту огромную статью о качестве кода и о том, как задавать вопросы, вдвойне, когда вы публикуете награду.

Если вам нужна помощь, не заставляйте людей работать с ней очень тяжело. Вы не получите хорошую помощь, если кто-то не будет полностью сумасшедшим.

jsFiddle требует, чтобы вы опубликовали фактический рабочий код (или нерабочий код), который позволяет нам увидеть, есть ли проблема с form.submit(), например, какие-либо странные атрибуты или свойства элемента формы или любое количество других проблем что вы можете отказаться от того, что вы исключили.

Итак, давайте посмотрим, что нарушает вашу функцию "Удалить пользователя".

function() {
    var self = $(this);
    var form = $('#edit_user_form');
    tmpElm = $('<input type="hidden" />');
    tmpElm.prop('name', 'delete');
    tmpElm.prop('id', 'delete');
    tmpElm.val(true);
    tmpElm.appendTo(form);
    form.submit();
    return true;
}
  • Почему вы объявили себя? Вы никогда не используете его один раз. Давайте избавимся от этого.
  • Вы можете использовать что-то называемое цепочкой, это действительно зависит от вас. Некоторые люди ненавидят это.
  • Вы добавляете новый ввод в форму для чего-то похожего на выбор, я не уверен, что это мудро. Я бы предложил изменить значение обычного ввода или использовать другой шаблон, это может привести к множеству проблем, но, ради вопроса, я подумаю, что это сделано по всем правильным причинам. Однако будьте осторожны, если кто-то дважды щелкнет submit, этот ввод там два раза.
  • form - это слово, зарезервированное для использования в DOM, вы должны избегать использования этого, чтобы избежать путаницы между вашей переменной и DOM API.
  • Какую кнопку отправки формы мы нажимаем здесь? У вас много, и jQuery не собирается догадываться и надеяться на лучшее.

Как должны выглядеть формы:

w3 объясняет, какие формы и цель вещей.

Ключевые моменты:

  • Имена соединены со значениями
  • Кнопка отправки нажата, кнопки отправки, которые не нажаты, не являются.
  • DOM можно перемещать на основе атрибутов NAME и ID

Что-то странное происходит в вашей форме.

Здесь форма, которую javascript понимает, как отправить: http://jsfiddle.net/YS8uW/2/

Здесь javascript пытается отправить вашу форму (разделившись на голые кости): http://jsfiddle.net/LfDXh/

Что здесь изменилось?

  • У вас есть идентификаторы повсюду.
  • Вы используете ключевые слова для имен

Давайте посмотрим на что-то, что вы сделали, с учетом идентификатора: http://jsfiddle.net/fdLfC/

И что происходит, когда мы не используем это как идентификатор? http://jsfiddle.net/fdLfC/1/

Ааа. Так что странно.

Это, как дать ему идентификатор submit, не позволит вам называть submit. Правильное объяснение заключается в том, что вы переписали его, потому что dom сделал это, когда вы назначили этот идентификатор и имя, пытаясь вызвать этот элемент.

Вы можете видеть это, если вы открываете отладчик или что-то в этом роде, оно дает предупреждение о том, что:

TypeError: свойство 'submit' объекта # не является функцией

Не используйте ключевые слова для обозначения чего-то другого, и вы не попадете в эти странные ловушки.

Большое спасибо @MattMcDonald за ссылку на этот ресурс, в котором объясняется, как справиться с и почему атрибуты NAME и ID переписывают встроенные методы HTML DOM.

Сделайте то, что я сказал. Отказ: все, кто собирается вести войну со мной, заявляют, что не абсолютны, что вы должны делать все это, я согласен, но я думаю, что этот пост достаточно длинный, и мы все согласны с тем, что делать это - шаг вперед по качеству кода, а не назад.. Это до вас в конце, но старайтесь избегать смешивания вещей в огромный беспорядочный банк. Подумайте о выполнении вашего кода и о том, как это происходит.

Ответ 2

Если вы уверены, что добавляет скрытый ввод, проблема должна заключаться в использовании дублирующего идентификатора. Кнопка и скрытый ввод имеют одинаковый идентификатор. Сделайте их разными и повторите попытку.

Ответ 3

Не спрашивайте меня, почему это сработало, все, что я могу вам сказать, - это сделать это и это, и разрывать каждую часть вашего кода, , наконец, я заставил его работать. нажмите ссылку ниже, чтобы увидеть демонстрацию

http://jsfiddle.net/praveen_prasad/KaK5A/4/

Сделанные изменения: удалены атрибуты id и name из кнопок отправки из формы

Пример:

<input type="submit" value="Save" name="submit" id="submit"/>

изменено выше ниже

<input type="submit" value="Save" />

Примечание. Для демонстрации JsFiddle:, когда вы нажмете кнопку "Удалить пользователя" на модальной форме, отправьте форму. jsfiddle скажет "Ошибка 404", так как он не найдет ссылку, которую вы публикуете в своей форме. Откройте firebug и посмотрите, что его фактическая публикация для исправления URL.

Ответ 4

"Delete User": function() {
    var self = $(this);
    var form = $('#edit_user_form');
    tmpElm = $('<input type="hidden" />');
    tmpElm.attr('name', 'delete');
    tmpElm.attr('id', 'delete');
    tmpElm.val(true); // HERE ----------------
    tmpElm.appendTo(form);
    form.submit();
    return true;
}

В указанном месте не должно быть:

tmpElm.value(true);

или

tmpElm.attr('value', 'true');

Ответ 5

Мне кажется, что я не смущаюсь обращаться с моими формами при подтверждении через jQuery ajax с сериализованными значениями формы. Он имеет дополнительное преимущество в том, чтобы избегать нежелательной формы с помощью кнопок внутри тегов <form>. Таким образом, это будет выглядеть примерно так:

<form id="edit_user_form">
...
<button id="submit_btn">Submit</button><br />
<button id="cancel_btn">Cancel</button><br />            
<button id="delete_btn">Delete</button>
...
</form>

И затем javascript:

$('#delete_btn').click(function() {

    $('#dialog-modal').dialog({
            autoOpen: false,
            width: 400,
            modal: true,
            resizable: false,
            buttons: {
                "Cancel": function() {
                    $(this).dialog("close");
                    return false;
                },
                "Delete User": function() {
                    $.ajax({                                                                                    
                url: "/admin/edit-user",
                type: "POST",
                            data: $('#edit_user_form).serialize(),
                error: function(XMLHttpRequest, textStatus, errorThrown)  {
                    alert("An error has occurred: " + errorThrown);
                },
                success: function(){
                        //Notify of success, redirect, etc.
                        }
                });
                }
            }
    });

});

Таким образом, он все еще отправляется через POST. Теперь это может происходить асинхронно (или нет). Вы можете "делать что-то" с успехом, не меняя страницы, или, альтернативно, перенаправлять по мере необходимости. Я использую страницу "диспетчера" для отправки в объектно-ориентированную инфраструктуру, которая затем возвращает выход обратно диспетчеру PHP, который должен быть json_encoded, и повторяется как строка для вызова AJAX для успешного использования. Используя этот шаблон, я должен иметь только одну страницу, которая выплескивает простой текст, а остальное может находиться в моих классах OO, которые не могут быть вызваны непосредственно ajax без серьезного сглаживания (используя xajax)