[英]How to implement a reusable confirmation dialog with Bootstrap modals and jQuery?
[英]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模式)也會中斷,這意味着我需要為這些功能添加其他代碼。 我不希望這種情況發生。 如何在不為這些功能添加其他功能的情況下保持其他功能正常工作的同時,如何使這些確認正常工作?
會發生什么:
<button class="btn btn-warning pending">Pending</button>
,則應該隱藏它。 WillClose()
函數WillClose()
(其反過來應將給定確認控件的待定按鈕文本更改為“再次嘗試”)。 ConfirmModal()
函數(這反過來應禁用給定確認的所有按鈕)控制並將待處理按鈕文本更改為“已確認”。 怎么了:
除非我將$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">×</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body…</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>
我只是在尋找一種盡可能少的代碼的解決方案。 如果給出的示例可以重寫為更小,請告訴我。
編輯:我知道上面提供的代碼添加了多個事件監聽器,我點擊某些控件導致問題。 這就是為什么我正在尋找一個(盡可能簡單)解決方案,使所有這些控件獨立工作,同時保持腳本不引人注目,並保持上面提供的代碼格式。
現在的問題是 :當你使用時
targetModal.on("hidden.bs.modal", function (e) {
WillClose(ele);
//Make use of targetModal.off(); here? <--
//targetModal.off();
targetModal.html($modalInit);
});
在OpenConfirmModal
函數內部,每次打開對話框時都會附加一個新的事件處理程序。 這導致以下情況:
等等。 確認也有類似的問題。 我已修改代碼只是添加一個控制台日志來演示這一點 - 打開和關閉會使越來越多的日志進入控制台:
//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">×</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body…</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">×</span></button> <h4 class="modal-title">Modal title</h4> </div> <div class="modal-body"> <p>One fine body…</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.