簡體   English   中英

如何使用Bootstrap Modals和按鈕進行可重復使用的確認控件?

[英]How could I make a reusable confirmation control using Bootstrap Modals and buttons?

目前,我試圖讓用戶通過打開Bootstrap模式以及為不同的功能使用這些相同的模態來確認某些內容。 在這個問題中,我將使用“計算器”類型的元素作為附加功能的示例。 現在看來,除非我添加JQuery的$target.off();否則確認將無效$target.off(); to targetModal.on("hidden.bs.modal", function (e) {});

當我添加這段JQuery代碼時,它會導致我在此頁面上使用的任何其他功能(關於Bootstrap模式)也會中斷,這意味着我需要為這些功能添加其他代碼。 我不希望這種情況發生。 如何在不為這些功能添加其他功能的情況下保持其他功能正常工作的同時,如何使這些確認正常工作?

會發生什么:

  1. 當選擇“否”時,按鈕(顯然為“否”)應該保持相同的顏色,但是相反的按鈕(“是”按鈕)應該變為灰色並且“確認?” 按鈕應該禁用(如果還沒有)。 此外,如果可以看到<button class="btn btn-warning pending">Pending</button> ,則應該隱藏它。
  2. 選擇“是”時,按鈕(“是”)應該保持相同的顏色,但是相反的按鈕(“否”按鈕)應該變成灰色並且“確認?” 按鈕應該啟用。
  3. 什么時候“確認?” 單擊按鈕,它應該填充與確認相關的任何模態並打開給定的模態。
  4. 如果確認期間退出/關閉模態而未完成確認, WillClose()函數WillClose() (其反過來應將給定確認控件的待定按鈕文本更改為“再次嘗試”)。
  5. 成功執行確認后(通過單擊給定模態中的“確認”按鈕),模式應隱藏/消失(並重置內部內容)並執行ConfirmModal()函數(這反過來應禁用給定確認的所有按鈕)控制並將待處理按鈕文本更改為“已確認”。
  6. 這些確認中的任何一個都應該彼此獨立地工作。

怎么了:

除非我將$target.off()添加到模態(例如targetModal.off() ),否則確認元素會觸發彼此的掛起按鈕。 但是,執行后者會導致其他功能“中斷”。 我的意思是,無論在“模態”中“填充”,“插入”或“克隆”(無論你想稱之為什么),它都將被放置在模態中多次(就像模態不會重置,有道理嗎?)。

我怎么能做以下工作?

 //Fields: //Yes selector const positiveSelector = ".positive"; //No selector const negativeSelector = ".negative"; //Confirm? selector const confirmSelector = ".init-confirm"; //Pending selector const pendingSelector = ".pending"; //calTrigger selector const calcTriggerSelector = ".calc-trigger > button"; //Yes elements const positiveNodes = document.querySelectorAll(positiveSelector); //No elements const negativeNodes = document.querySelectorAll(negativeSelector); //Confirm? elements const confirmNodes = document.querySelectorAll(confirmSelector); //Pending elements const pendingNodes = document.querySelectorAll(pendingSelector); //calcTrigger elements const calcTriggerNodes = document.querySelectorAll(calcTriggerSelector); //Modal const targetModalSelector = "#bs-modal-xl"; const targetModal = $(targetModalSelector); const $modalInit = targetModal.html(); //Eventlisteners: positiveNodes.forEach(node => node.addEventListener("click", function () { EnableConfirmBtn(this); })); negativeNodes.forEach(node => node.addEventListener("click", function () { DisableConfirmBtn(this); })); confirmNodes.forEach(node => node.addEventListener("click", function () { OpenConfirmModal(this); })); calcTriggerNodes.forEach(node => node.addEventListener("click", calcTrigger)); //Reset modal when closing targetModal.on("hidden.bs.modal", function () { targetModal.html($modalInit); }); //Methods: function EnableConfirmBtn(ele) { ele.classList.add("btn-success"); ele.parentNode.querySelectorAll(negativeSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.removeAttribute("disabled")); } function DisableConfirmBtn(ele) { ele.classList.add("btn-warning"); ele.parentNode.querySelectorAll(positiveSelector).forEach(node => node.classList.remove("btn-success")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.setAttribute("disabled", "")); } function OpenConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "inline-block"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Pending"); $(targetModalSelector + " .modal-body").html($(".clone-one").clone()); $(targetModalSelector + " .clone-one").show(); $(targetModalSelector + " h4.modal-title").text(""); $(targetModalSelector + " .modal-content .modal-footer").html(""); targetModal.modal(); targetModal.on("click", ".clone-one", function () { targetModal.modal("hide"); ConfirmModal(ele); }); targetModal.on("hidden.bs.modal", function (e) { WillClose(ele); //Make use of targetModal.off(); here? <-- //targetModal.off(); targetModal.html($modalInit); }); } function ConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Confirmed"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger", "btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-success")); ele.parentNode.querySelectorAll(confirmSelector).forEach(node => node.style.display = "none"); ele.parentNode.querySelectorAll(".btn-group > button").forEach(node => node.setAttribute("disabled", "")); } function WillClose(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Try again"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-warning")); } function calcTrigger() { ModalHandler($(".calc").clone(), "", "", true, true); $(targetModalSelector + " .calc").show(); targetModal.modal(); document.querySelectorAll(targetModalSelector + " .calc #number-one-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "1"); })); document.querySelectorAll(targetModalSelector + " .calc #number-two-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "2"); })); document.querySelectorAll(targetModalSelector + " .calc #number-three-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "3"); })); //I would not want to be using something like this: //Reset modal when closing //targetModal.on("hidden.bs.modal", function () { //targetModal.off(); //targetModal.html($modalInit); //}); } //Modal handling (not required when not using Modal): function ModalHandler(content, title, footer = "", bigCloseBtn = false, emptyFooter = false) { $(targetModalSelector + " h4.modal-title").text(title); $(targetModalSelector + " .modal-body").html(content); if (footer != "" && footer != undefined) { $(targetModalSelector + " .modal-footer").html(footer); } if (bigCloseBtn) { $(targetModalSelector + " .modal-content .modal-header button.close").css("float", "right"); $(targetModalSelector + " .modal-content .modal-header button.close").addClass("btn btn-lg btn-danger"); //$(".modal .modal-content .modal-header button.close").html("close"); $(targetModalSelector + " .modal-content .modal-header button.close").removeClass("close"); } if (emptyFooter) { $(targetModalSelector + " .modal-content .modal-footer").html(""); } } 
 #foo-container { padding: 5px; } .pending { display: none; } .clone-one, .calc { display: none; } .calc { width: 100%; } .calc button, .calc .result-container { margin-top: 3px; margin-bottom: 3px; } .calc [class*="col-"] { padding-left: 3px; padding-right: 3px; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body&hellip;</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <div id="calc" class="calc"> <form> <div class="row"> <div class="col-xs-9"> <div class="result-container"> <input type="text" class="form-control" disabled> </div> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="x" id=""> <span class="glyphicon glyphicon-remove"></span> </button> </div> </div> <div class="row"> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="1" id="number-one-btn"> 1 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="2" id="number-two-btn"> 2 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="3" id="number-three-btn"> 3 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="" id="number-one-btn"> <span class="glyphicon glyphicon-arrow-left"></span> </button> </div> </div> </form> </div> <div class="container"> <div id="foo-container"> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="calc-trigger"> <button class="btn btn-lg btn-default"> Calc trigger </button> </div> </div> <div class="clone-one"> <button type="button" class="btn btn-lg btn-success">Clicky</button> </div> </div> 

的jsfiddle

我只是在尋找一種盡可能少的代碼的解決方案。 如果給出的示例可以重寫為更小,請告訴我。

編輯:我知道上面提供的代碼添加了多個事件監聽器,我點擊某些控件導致問題。 這就是為什么我正在尋找一個(盡可能簡單)解決方案,使所有這些控件獨立工作,同時保持腳本不引人注目,並保持上面提供的代碼格式。

現在的問題 :當你使用時

targetModal.on("hidden.bs.modal", function (e) {
  WillClose(ele);
  //Make use of targetModal.off(); here? <--
  //targetModal.off();
  targetModal.html($modalInit);
});

OpenConfirmModal函數內部,每次打開對話框時都會附加一個新的事件處理程序。 這導致以下情況:

  1. 打開對話框並附加事件處理程序。
  2. 對話框關閉,執行一個事件處理程序。
  3. 打開對話框並附加另一個事件處理程序。
  4. 對話框關閉,執行兩個事件處理程序。
  5. 打開對話框並附加另一個事件處理程序。
  6. 對話框關閉,執行三個事件處理程序。

等等。 確認也有類似的問題。 我已修改代碼只是添加一個控制台日志來演示這一點 - 打開和關閉會使越來越多的日志進入控制台:

 //Fields: //Yes selector const positiveSelector = ".positive"; //No selector const negativeSelector = ".negative"; //Confirm? selector const confirmSelector = ".init-confirm"; //Pending selector const pendingSelector = ".pending"; //calTrigger selector const calcTriggerSelector = ".calc-trigger > button"; //Yes elements const positiveNodes = document.querySelectorAll(positiveSelector); //No elements const negativeNodes = document.querySelectorAll(negativeSelector); //Confirm? elements const confirmNodes = document.querySelectorAll(confirmSelector); //Pending elements const pendingNodes = document.querySelectorAll(pendingSelector); //calcTrigger elements const calcTriggerNodes = document.querySelectorAll(calcTriggerSelector); //Modal const targetModalSelector = "#bs-modal-xl"; const targetModal = $(targetModalSelector); const $modalInit = targetModal.html(); //Eventlisteners: positiveNodes.forEach(node => node.addEventListener("click", function () { EnableConfirmBtn(this); })); negativeNodes.forEach(node => node.addEventListener("click", function () { DisableConfirmBtn(this); })); confirmNodes.forEach(node => node.addEventListener("click", function () { OpenConfirmModal(this); })); calcTriggerNodes.forEach(node => node.addEventListener("click", calcTrigger)); //Reset modal when closing targetModal.on("hidden.bs.modal", function () { targetModal.html($modalInit); }); //Methods: function EnableConfirmBtn(ele) { ele.classList.add("btn-success"); ele.parentNode.querySelectorAll(negativeSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.removeAttribute("disabled")); } function DisableConfirmBtn(ele) { ele.classList.add("btn-warning"); ele.parentNode.querySelectorAll(positiveSelector).forEach(node => node.classList.remove("btn-success")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.setAttribute("disabled", "")); } function OpenConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "inline-block"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Pending"); $(targetModalSelector + " .modal-body").html($(".clone-one").clone()); $(targetModalSelector + " .clone-one").show(); $(targetModalSelector + " h4.modal-title").text(""); $(targetModalSelector + " .modal-content .modal-footer").html(""); targetModal.modal(); targetModal.on("click", ".clone-one", function () { targetModal.modal("hide"); console.log("hiding") ConfirmModal(ele); }); targetModal.on("hidden.bs.modal", function (e) { WillClose(ele); console.log("closing"); //Make use of targetModal.off(); here? <-- //targetModal.off(); targetModal.html($modalInit); }); } function ConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Confirmed"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger", "btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-success")); ele.parentNode.querySelectorAll(confirmSelector).forEach(node => node.style.display = "none"); ele.parentNode.querySelectorAll(".btn-group > button").forEach(node => node.setAttribute("disabled", "")); } function WillClose(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Try again"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-warning")); } function calcTrigger() { ModalHandler($(".calc").clone(), "", "", true, true); $(targetModalSelector + " .calc").show(); targetModal.modal(); document.querySelectorAll(targetModalSelector + " .calc #number-one-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "1"); })); document.querySelectorAll(targetModalSelector + " .calc #number-two-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "2"); })); document.querySelectorAll(targetModalSelector + " .calc #number-three-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "3"); })); //I would not want to be using something like this: //Reset modal when closing //targetModal.on("hidden.bs.modal", function () { //targetModal.off(); //targetModal.html($modalInit); //}); } //Modal handling (not required when not using Modal): function ModalHandler(content, title, footer = "", bigCloseBtn = false, emptyFooter = false) { $(targetModalSelector + " h4.modal-title").text(title); $(targetModalSelector + " .modal-body").html(content); if (footer != "" && footer != undefined) { $(targetModalSelector + " .modal-footer").html(footer); } if (bigCloseBtn) { $(targetModalSelector + " .modal-content .modal-header button.close").css("float", "right"); $(targetModalSelector + " .modal-content .modal-header button.close").addClass("btn btn-lg btn-danger"); //$(".modal .modal-content .modal-header button.close").html("close"); $(targetModalSelector + " .modal-content .modal-header button.close").removeClass("close"); } if (emptyFooter) { $(targetModalSelector + " .modal-content .modal-footer").html(""); } } 
 #foo-container { padding: 5px; } .pending { display: none; } .clone-one, .calc { display: none; } .calc { width: 100%; } .calc button, .calc .result-container { margin-top: 3px; margin-bottom: 3px; } .calc [class*="col-"] { padding-left: 3px; padding-right: 3px; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body&hellip;</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <div id="calc" class="calc"> <form> <div class="row"> <div class="col-xs-9"> <div class="result-container"> <input type="text" class="form-control" disabled> </div> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="x" id=""> <span class="glyphicon glyphicon-remove"></span> </button> </div> </div> <div class="row"> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="1" id="number-one-btn"> 1 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="2" id="number-two-btn"> 2 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="3" id="number-three-btn"> 3 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="" id="number-one-btn"> <span class="glyphicon glyphicon-arrow-left"></span> </button> </div> </div> </form> </div> <div class="container"> <div id="foo-container"> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="calc-trigger"> <button class="btn btn-lg btn-default"> Calc trigger </button> </div> </div> <div class="clone-one"> <button type="button" class="btn btn-lg btn-success">Clicky</button> </div> </div> 

可以使用.off來避免這種情況,但這並不是最好的主意,因為它實際上使代碼更加笨拙。

  • 在調用.off您只需指定一個事件,但是,這將刪除該事件的所有處理程序。 targetModal.off("hidden.bs.modal"); 將適用於一個簡單的情況,但你可以從其他地方添加一個正常工作的第二個處理程序(它不會不斷重新添加),這也將被消滅。
  • 如果使用要刪除的特定處理程序調用.off ,則需要對處理程序的引用。 這更有用,但更尷尬 - 您的代碼實際上看起來像這樣:
var handler = function (e) {
//  ^^^^^^^------------------------------------------------------------------ <-   
  WillClose(ele);                                  //                          |
  targetModal.off("hidden.bs.modal", "*" handler); // `handler` references -> -^
//                                    ^--------------
  targetModal.html($modalInit);//                   |  these need to match because 
}//                                                 |  .off() requires a second parameter
//                                                  |  parameter to use the handler ref
targetModal.on("hidden.bs.modal", "*", handler);//  |  this mandates that .on() also
//                                 ^ ----------------  uses the second parmeter

相反,使用.one它的組合.on同一個隱含的.off -它會附着回調函數作為事件處理程序,然后執行一次之后將其刪除。 這樣你就不必自己打電話給.off

以下是使用.one的代碼 - 現在,如果重復打開和關閉對話框,您只需在控制台中輸入一個日志,而不是根據打開對話框的次數獲得n + 1:

 //Fields: //Yes selector const positiveSelector = ".positive"; //No selector const negativeSelector = ".negative"; //Confirm? selector const confirmSelector = ".init-confirm"; //Pending selector const pendingSelector = ".pending"; //calTrigger selector const calcTriggerSelector = ".calc-trigger > button"; //Yes elements const positiveNodes = document.querySelectorAll(positiveSelector); //No elements const negativeNodes = document.querySelectorAll(negativeSelector); //Confirm? elements const confirmNodes = document.querySelectorAll(confirmSelector); //Pending elements const pendingNodes = document.querySelectorAll(pendingSelector); //calcTrigger elements const calcTriggerNodes = document.querySelectorAll(calcTriggerSelector); //Modal const targetModalSelector = "#bs-modal-xl"; const targetModal = $(targetModalSelector); const $modalInit = targetModal.html(); //Eventlisteners: positiveNodes.forEach(node => node.addEventListener("click", function () { EnableConfirmBtn(this); })); negativeNodes.forEach(node => node.addEventListener("click", function () { DisableConfirmBtn(this); })); confirmNodes.forEach(node => node.addEventListener("click", function () { OpenConfirmModal(this); })); calcTriggerNodes.forEach(node => node.addEventListener("click", calcTrigger)); //Reset modal when closing targetModal.on("hidden.bs.modal", function () { targetModal.html($modalInit); }); //Methods: function EnableConfirmBtn(ele) { ele.classList.add("btn-success"); ele.parentNode.querySelectorAll(negativeSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.removeAttribute("disabled")); } function DisableConfirmBtn(ele) { ele.classList.add("btn-warning"); ele.parentNode.querySelectorAll(positiveSelector).forEach(node => node.classList.remove("btn-success")); ele.parentNode.parentNode.querySelectorAll(confirmSelector).forEach(node => node.setAttribute("disabled", "")); } function OpenConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.style.display = "inline-block"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Pending"); $(targetModalSelector + " .modal-body").html($(".clone-one").clone()); $(targetModalSelector + " .clone-one").show(); $(targetModalSelector + " h4.modal-title").text(""); $(targetModalSelector + " .modal-content .modal-footer").html(""); targetModal.modal(); targetModal.one("click", ".clone-one", function () { //one --------^ targetModal.modal("hide"); console.log("hide") ConfirmModal(ele); }); targetModal.one("hidden.bs.modal", function (e) { //one --------^ WillClose(ele); console.log("will close") targetModal.html($modalInit); }); } function ConfirmModal(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Confirmed"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger", "btn-warning")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-success")); ele.parentNode.querySelectorAll(confirmSelector).forEach(node => node.style.display = "none"); ele.parentNode.querySelectorAll(".btn-group > button").forEach(node => node.setAttribute("disabled", "")); } function WillClose(ele) { ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.textContent = "Try again"); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.remove("btn-danger")); ele.parentNode.querySelectorAll(pendingSelector).forEach(node => node.classList.add("btn-warning")); } function calcTrigger() { ModalHandler($(".calc").clone(), "", "", true, true); $(targetModalSelector + " .calc").show(); targetModal.modal(); document.querySelectorAll(targetModalSelector + " .calc #number-one-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "1"); })); document.querySelectorAll(targetModalSelector + " .calc #number-two-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "2"); })); document.querySelectorAll(targetModalSelector + " .calc #number-three-btn").forEach(node => node.addEventListener("click", function () { document.querySelectorAll(targetModalSelector + " .calc .result-container input").forEach(node => node.value += "3"); })); //I would not want to be using something like this: //Reset modal when closing //targetModal.on("hidden.bs.modal", function () { //targetModal.off(); //targetModal.html($modalInit); //}); } //Modal handling (not required when not using Modal): function ModalHandler(content, title, footer = "", bigCloseBtn = false, emptyFooter = false) { $(targetModalSelector + " h4.modal-title").text(title); $(targetModalSelector + " .modal-body").html(content); if (footer != "" && footer != undefined) { $(targetModalSelector + " .modal-footer").html(footer); } if (bigCloseBtn) { $(targetModalSelector + " .modal-content .modal-header button.close").css("float", "right"); $(targetModalSelector + " .modal-content .modal-header button.close").addClass("btn btn-lg btn-danger"); //$(".modal .modal-content .modal-header button.close").html("close"); $(targetModalSelector + " .modal-content .modal-header button.close").removeClass("close"); } if (emptyFooter) { $(targetModalSelector + " .modal-content .modal-footer").html(""); } } 
 #foo-container { padding: 5px; } .pending { display: none; } .clone-one, .calc { display: none; } .calc { width: 100%; } .calc button, .calc .result-container { margin-top: 3px; margin-bottom: 3px; } .calc [class*="col-"] { padding-left: 3px; padding-right: 3px; } 
 <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <div class="modal" id="bs-modal-xl" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body&hellip;</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div> <div id="calc" class="calc"> <form> <div class="row"> <div class="col-xs-9"> <div class="result-container"> <input type="text" class="form-control" disabled> </div> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="x" id=""> <span class="glyphicon glyphicon-remove"></span> </button> </div> </div> <div class="row"> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="1" id="number-one-btn"> 1 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="2" id="number-two-btn"> 2 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="3" id="number-three-btn"> 3 </button> </div> <div class="col-xs-3"> <button type="button" class="btn btn-default btn-block" value="" id="number-one-btn"> <span class="glyphicon glyphicon-arrow-left"></span> </button> </div> </div> </form> </div> <div class="container"> <div id="foo-container"> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="confirmation-box"> <div class="btn-group btn-group-lg" role="group" aria-label="..."> <button type="button" class="btn btn-success positive">Yes</button> <button type="button" class="btn btn-warning negative">No</button> </div> <button type="button" class="btn btn-lg btn-danger init-confirm" disabled>Confirm?</button> <button type="button" class="btn btn-lg btn-danger pending" disabled>Pending</button> </div> <br /> <div class="calc-trigger"> <button class="btn btn-lg btn-default"> Calc trigger </button> </div> </div> <div class="clone-one"> <button type="button" class="btn btn-lg btn-success">Clicky</button> </div> </div> 

暫無
暫無

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

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