簡體   English   中英

jQuery模態確認對話框未提交表單

[英]jQuery Modal Confirmation Dialog Not Submitting Form

當用戶按下編輯表單上的刪除按鈕時,我試圖彈出一個確認模式。 模式彈出很好,但是當jQuery應該提交表單時,它沒有做任何事情。 我刪除了一個type =“button”,因為當它是類型提交時,模態函數不會阻止進程,它只是立即刪除用戶。

HTML ...

- 編輯 -

(我添加了<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');
    }

當我檢查源代碼時,我發現代碼正在附加新的隱藏元素,但提交似乎並不想觸發。 我錯過了什么步驟?

嘗試不同的方式。


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的

Hokay,所以,這是你的功能:

  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');
    }

這里發生了什么? 第一步,您應該嘗試使用工具來衡量代碼質量。 兩個流行的是JSHintJSLint的 您不需要按照他們所說的內容進行操作,因為這是編寫代碼的唯一方法,但它在查找由於小錯誤而導致的錯誤方面非常有用。 我喜歡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.

哎呀。 看起來你有一個未定義的變量,這意味着它現在是全局的。 全局變量很糟糕,它們會破壞范圍並使代碼以奇怪的方式運行。

我們需要解決這個問題。 您應該始終在本地范圍內聲明局部變量。 這意味着放入一個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;
}
  • 你為什么宣稱自己? 你永遠不會使用它一次。 讓我們擺脫它。
  • 可以使用一種叫做鏈接的東西,它真的取決於你。 有些人討厭它。
  • 你為表單添加了一個全新的輸入,看起來像是一個選擇,我不確定這是明智的。 我建議改變正常輸入的值,或使用其他模式,這可能會導致很多問題,但為了這個問題,我會想象它是出於所有正確的原因而完成的。 但是要小心,如果有人雙擊提交,那么輸入就在那里兩次
  • form是DOM中使用的保留字,你應該避免使用它來避免變量和DOM API之間的混淆。
  • 我們點擊這個表單提交按鈕? 你有很多,jQuery不會猜測並希望最好的。

表格的外觀如何:

w3解釋了什么是形式和事物的目的。

關鍵點:

  • 名稱與值配對
  • 單擊提交按鈕,未單擊提交按鈕。
  • 可以基於NAME和ID屬性來導航DOM

你的形式正在發生一些奇怪的事情。

這是一個javascript了解如何提交的表單: http//jsfiddle.net/YS8uW/2/

這是javascript嘗試提交您的表單(剝離到簡單): http//jsfiddle.net/LfDXh/

這有什么不同?

  • 你到處都有ID。
  • 您使用關鍵字作為名稱

讓我們看看你做過的事情,給出了提交給某事的ID: http//jsfiddle.net/fdLfC/

當我們不使用它作為ID時會發生什么? http://jsfiddle.net/fdLfC/1/

啊。 這太奇怪了。

這就像給它一個提交ID不會讓你調用提交。 一個正確的解釋是,你重寫了它,因為dom在你分配了ID和Name時就做了,它試圖調用元素。

你可以看到這個,如果你打開一個調試器或什么,它會給你一個警告:

TypeError:對象#的屬性'submit'不是函數

遠離使用關鍵詞來表示其他內容,你不會陷入這些奇怪的陷阱。

非常感謝@MattMcDonald將我鏈接到這個資源該資源解釋了如何處理,以及為什么NA​​ME和ID屬性覆蓋了內置的HTML DOM方法。

做我說的其他事情。 免責聲明:每個人都要對我發動戰爭,說你應該做所有這些事情並不是絕對的,我同意,但我認為這篇文章已經足夠長了,我們都同意做這些事情是代碼中的一個進步質量,而不是倒退。 這取決於你最后,但試着避免將東西混合成一個巨大的雜亂的鍋。 考慮一下代碼的執行情況以及代碼的執行情況。

如果您確定它附加隱藏的輸入,那么問題必須是使用重復的ID。 按鈕和隱藏輸入具有相同的ID。 讓它們與眾不同,然后重試。

不要問我它工作的原因,我可以告訴你的是,在完成這個和那個並且撕掉代碼的每個部分之后, 我終於讓它工作了 點擊下面的鏈接查看演示

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

我所做的更改是:從表單中的提交按鈕中刪除idname屬性

例:

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

上面改為下面

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

注意對於JsFiddle演示:當您單擊模態上的刪除用戶時,表單將提交。 jsfiddle將說“錯誤404”,因為它不會找到您發布表單的鏈接。 打開firebug並看到它實際發布到正確的url。

"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');

我發現通過帶有序列化表單值的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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM