change js confirm to a twitter bootstrap modal - javascript

I have some JavaScript that displays a confirm dialog box to the user to confirm their action with passed in variables.
However, I must change the plain confirm dialog to a twitter-bootstrap modal.
I have tried several times, read a lot of SO posts and read the twitter bootstrap docs, but I cannot get it to work as my knowledge of js is not good enough. I am getting stuck on the display of the variables in the twitter bootstrap modal.
I am hoping that some one can help me out by giving me some pointers.
Here is my current js dialog code:
function checkboxUpdated(checkbox, count, label, id) {
if (checkbox.checked) {
$('#menu_entry_' + id).show();
} else {
if (count > 0) {
if (! confirm('{% trans "You have '+ count +' saved '+ label +'.\n\nIf you leave this option un-checked your saved '+ label +' will be deleted only after you update this page.\n\nAre you sure you want to delete your ' + count + ' saved ' + label +'?" %}')) {
checkbox.checked = true;
return;
}
}
$('#menu_entry_' + id).hide();
}
}
EDIT: ADDED CODE OF #menu_entry_ as requested in comment:
{% for id, menu_entry, selected, item_count in menu_entries %}
<li id="menu_entry_{{ id }}" {% if not selected %}style="display:none;"{% endif %}>
<a
{% if id == 4 %}
href="{% url summary_details %}"
{% elif id == 8 %}
href="{% url objective_details %}"
{% elif id == 12 %}
href="{% url leading_employment_details %}"
{% elif id == 16 %}
href="{% url desired_occupation_details %}"
....
{% elif id == 112 %}
href="/"
{% else %}
href="/"
{% endif %}
onclick="showProgressAnimation();">
Note that I need to transform the following js confirm code to twitter bootstrap modal code:
if (! confirm('{% trans "You have '+ count +' saved '+ label +'.\n\nIf you leave this option un-checked your saved '+ label +' will be deleted only after you update this page.\n\nAre you sure you want to delete your ' + count + ' saved ' + label +'?" %}')) {

You can write your own jQuery plugin. First, add the Bootsrap's modal component to your document.
<div class="modal fade" id="confirm" tabindex="-1" role="dialog" aria-labelledby="confirm-label" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="confirm-label"></h4>
</div>
<div class="modal-body">
<p class="message"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default dismiss" data-dismiss="modal"></button>
<button type="button" class="btn btn-primary confirm" data-dismiss="modal"></button>
</div>
</div>
</div>
</div>
Basically, the plugin should display the modal when invoked and trigger a confirm event if the confirmation button is pressed or dismiss otherwise.
$.fn.confirm = function (options) {
var settings = $.extend({}, $.fn.confirm.defaults, options);
return this.each(function () {
var element = this;
$('.modal-title', this).html(settings.title);
$('.message', this).html(settings.message);
$('.confirm', this).html(settings.confirm);
$('.dismiss', this).html(settings.dismiss);
$(this).on('click', '.confirm', function (event) {
$(element).data('confirm', true);
});
$(this).on('hide.bs.modal', function (event) {
if ($(this).data('confirm')) {
$(this).trigger('confirm', event);
$(this).removeData('confirm');
} else {
$(this).trigger('dismiss', event);
}
$(this).off('confirm dismiss');
});
$(this).modal('show');
});
};
An improvement we can make to the code above is to expose the default plugin settings.
$.fn.confirm.defaults = {
title: 'Modal title',
message: 'One fine body…',
confirm: 'OK',
dismiss: 'Cancel'
};
Usage example:
$('#confirm').confirm().on({
confirm: function () {
console.log('confirm');
},
dismiss: function () {
console.log('dismiss');
}
});
See live example here: http://jsfiddle.net/cdog/4q9t9pk5/.
If you don't want to write your own solution you can try existing projects like: https://github.com/nakupanda/bootstrap3-dialog. It looks like what you were looking for. Docs and demos available here: http://nakupanda.github.io/bootstrap3-dialog/.

DEMO
You want to change your function as shown below. Then there's modal markup to add to the page (see demo) and the event listeners shown below:
function checkboxUpdated(checkbox, count, label, id) {
if (checkbox.checked) {
$('#menu_entry_' + id).show();
} else {
if (count > 0) {
//save data to use later
$('#message_p').text( '<the-message-to-show-on-the-modal>' )
.data('elem', '#menu_entry_' + id)
.data('chkbox', checkbox);
//set modal title
$('#title_h4').text( '<Modal Title>' );
//show modal
$('#confirm_modal').modal('show');
}
}
}
$(document).ready(function() {
$('.button-yes').on('click',function() {
var checkbox = $('#message_p').data('chkbox');
checkbox.checked = true;
$('#confirm_modal').modal('hide');
});
$('#confirm_modal').on('hidden.bs.modal', function() {
var elem = $('#message_p').data('elem');
$(elem).hide();
});
});
NOTE: Let us know if you have any questions.

Related

jQuery to close menu when form submitted / prevent function on error + update list with htmx

So what I have is a simple form with couple of fields that is located inside a menu, that slides in when I click button 'btn-openmenu'. I am trying to use htmx to dynamically update the page to show results instantly and also Javascript to control the menu where the form is located.
What I am trying to accomplish is that when the submit button on the form is pushed, it will submit the form and close the menu.
What happens now is that the menu closes okay when the form is submitted. What also can happen is that if the form is not valid and a error pops up, but the menu still closes and the form is never submitted.
Here is the html where form is located form (/items/new-item/):
{% load crispy_forms_tags %}
<form id="createnewitem"
hx-post="/items/new-item/">
{% csrf_token %}
{{ newcoreprocess|crispy }}
<div style="margin-top: 10px;">
<button type="submit" class="btn submit-new">Create item</button>
<a class="btn" id="clear">Clear</button>
</div>
</form>
<script>
$(document).ready(() => {
$('#clear').on('click', function () {
var form = $("#createnewitem");
form[0].reset();
})
})
</script>
<script>
$(document).ready(() => {
$('.submit-new').click(function () {
var pagecontent = $("#content");
var menu = $(".menu");
var buttonSpan = $("#btn_openmenu").find('span');
pagecontent.css('marginLeft', '0');
menu.css('width', '0');
buttonSpan.text('Close');
})
})
</script>
Here is the html where the menu is opened and updated list would be rendered (/items/):
<div class="items-content" id="itemcontent">
<div class="container-fluid">
<div class="row" id="items-list">
{% include 'items/items-list.html' %}
</div>
</div>
<button class="btn" id="btn_openmenu"
hx-get="/items/new-item/"
hx-target="#createitemmenu"
hx-swap="innerHTML">
<i class="fas fa-plus-circle" id="add-item-icon"></i><span class="spanicon" id="add-item-span">Create item</span>
</button>
<div class="menu">
<div class="container-fluid" id="createitemmenu">
</div>
</div>
</div>
<script>
$(document).ready(() => {
$('#btn_openmenu').on('click', function () {
var thisElement = $(this);
var buttonSpan = thisElement.find('span');
var pagecontent = $("#itemcontent");
var menu = $(".menu");
if(buttonSpan.text() === "Close"){
buttonSpan.text('Create item');
menu.css('width', '0');
pagecontent.css('marginLeft', '0');
}
else {
if(buttonSpan.text() === "Create item"){
buttonSpan.text('Close');
pagecontent.css('marginLeft', '20%');
menu.css('width', '20%');
}
}
})
})
</script>
And here is the list (/items/item-list/)
{% if items %}
<nav class="nav processnav flex-column" style="padding-top: 10px;">
{% for item in items %}
<a class="nav-link" href="#">{{ item.order }} {{ item.name }}</a>
{% endfor %}
</nav>
{% else %}
<div class="container-fluid mt-3">
<span>No created items</span>
</div>
{% endif %}
What is working:
menu opens correctly
htmx renders the form in the menu
form can be submitted and if valid, the menu will close
What is not working:
if errors on submit, it still closes the menu
I have tried to edit the function submit-new.click, but whatever I change in that, it stops working at all and this is only function I got to work with valid submit
htmx doesn't render the updated list where new item is created
I have tried to edit the hx-post in the form, but whatever I edit the new item submit stops working and it renders some other content to the place, where the form is located.
I think there are just little things I am missing, but I cannot seem to get it function the way I want. Any help for the issue?

Why Javascript event running multiple times per click?

I wrote a js-class which handles the Ajax-calls when a user clicks on a button. So the user can simply click on open/close and can open/close a entity in my database.
All works fine. The button-icon changes and the popover title and text changes also. The user can click on the buttons again and again and the Ajax does the work and jQuery changes the look - BUT -
When I watch in my debug bar - I see that with every click a additional Ajax call is running. When I click the button 3 times - the same Ajax-call will run 4 times for changing the entity to open/close.
I inspected the handlers. Every time it is only one handler and one #close-course element.
I really don't understand why this Ajax calls get more and more with every click!
Here my js-class:
'use strict';
import $ from "jquery";
(function (window, $) {
class CourseApp {
constructor($wrapper) {
this.$wrapper = $wrapper.find('.js-wrapper');
this.$body = $wrapper
this.iconBtn = this.$wrapper.find('a').blur();
this.$submitCount = 0;
this.$wrapper.on(
'click',
'a',
this.handleOpenCloseAction.bind(this)
);
}
handleOpenCloseAction(e) {
let popover = this.$body.find('.popover')
// prevent popover to close - when open-button is hitted
popover
.on('mousedown', '#open-course', function (e) {
e.preventDefault()
});
// prevent popover to close - when open-button is hitted
popover
.on('mousedown', '#close-course', function (e) {
e.preventDefault()
});
// since open-course-link is clicked - open the course and
// do some action
popover
.on(
'click',
'#open-course',
function (e) {
const $btn = $(e.currentTarget);
let $icon = $btn.find('.icon-lock-open');
if (this.$submitCount === 0) {
this.$submitCount++;
$.ajax({
url: $btn.data('open-course-url'),
method: 'POST',
}).then(function (data) {
$('[data-toggle="popover"]').popover('hide');
this.iconBtn.blur();
this.iconBtn.attr('data-content', data);
this.iconBtn.attr('data-original-title', 'Kurs schließen');
$('.icon-lock').removeClass('icon-lock').addClass('icon-lock-open');
}.bind(this))
this.$submitCount = 0;
}
}.bind(this)
)
// since close-course-link is clicked - close the course and
// do some action
popover
.on(
'click',
'#close-course',
function (e) {
const $btn = $(e.currentTarget);
if (this.$submitCount === 0) {
this.$submitCount++;
$.ajax({
url: $btn.data('close-course-url'),
method: 'POST',
}).then(function (data) {
$('[data-toggle="popover"]').popover('hide');
this.iconBtn.blur();
this.iconBtn.attr('data-content', data);
this.iconBtn.attr('data-original-title', 'Kurs öffnen');
$('.icon-lock-open').removeClass('icon-lock-open').addClass('icon-lock');
}.bind(this))
this.$submitCount = 0;
}
}.bind(this)
)
}
}
window.CourseApp = CourseApp;
})(window, jQuery);
My html:
<td class="col-1 js-wrapper">
<a href="#"
class="btn btn-primary pop"
data-content="{% if entity.open %} {{ popoverContentClose }} {% else %} {{ popoverContentOpen }} {% endif %}" data-toggle="popover" tabindex="0" data-trigger="focus"
title=""
data-original-title="{% if entity.open %} Kurs schließen? {% else %} Kurs öffnen? {% endif %}"
data-placement="left">
{% if entity.open %}
<i class="icon icon-lock-open"></i>
{% else %}
<i class="icon icon-lock"></i>
{% endif %}
</a>
</td>
The popover (is in a twig block):
Möchtest du diesen Kurs wirklich schließen? Die Teilnehmer dieses Kurses müssen somit jeden Kurszugang bestätigen.
<br>
<table class='table popover-table mb-0'>
<tr>
<td class='pl-0 border-top-0'>
<a href='#'
class='btn btn-danger-outline col-md-12 ml-0' id='close-course' data-close-course-url='{{ path('close_course', {'id' : entity.id}) }}'><i class='icon icon-lock'></i>Schließen</a>
</td>
<td class='pr-0 border-top-0'>
<button class='btn btn-primary col-md-12' class='close'
data-dismiss='alert'>{{ 'common.close'|trans }}</button>
</td>
</tr>
</table>

Pass a variable from a function to another in jQuery

I'm a newbie in Javascript world, and I searched a lot for a similar question but never worked for me.
So I'm working with a Bootstrap modal, I have 3 buttons with different names that opens a modal window.
When I close the modal window I want an alert that show me the name of the button I've clicked.
For example, if I click on the button "Email Ted", when I close the modal the alert will say "You haven't sended the message to Ted".
I get the names from the attribute data-name="" in every button.
I also tried to insert the first function in a global variable, but didn't worked; so the code below is an idea to what I want to do.
$(document).ready(function() {
$("#exampleModal").on('show.bs.modal', function(e) {
var button = $(e.relatedTarget);
var recipient = button.data('name');
var modal = $(this);
modal.find('.modal-title').text('New message to ' + recipient);
return String(recipient);
});
$('#exampleModal').on('hidden.bs.modal', function(recipient) {
alert('The message will not be sended to ' + recipient);
});
});
Thanks!
I made a working demo out of what I understand of your question.
Please have a look and ask for what you need to be explained.
$(document).ready(function() {
$("#open").on("click",function(){
$("#exampleModal").modal("show");
});
var recipient="";
$("#exampleModal").on('show.bs.modal', function(e) {
recipient = $("#open").data('name');
var modal = $(this);
modal.find('.modal-title').text('New message to ' + recipient);
return String(recipient);
});
$('#exampleModal').on('hidden.bs.modal', function() {
alert('The message will not be sended to ' + recipient);
});
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<div class="modal" tabindex="-1" role="dialog" id="exampleModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal" data-name="TEST Name">Close</button>
</div>
</div>
</div>
</div>
<button id="open" data-name="John Doh">Open modal</button>
First of all it is important to mention that your snippet is not just general JavaScript, but the way Twitter Bootstrap works. There are no native shown and hidden events.
So you have custom events here. Btw. referring to the bootstrap reference, it should be shown.bs.modal (recognize the missing 'n' in your code) or maybe I am wrong and they made some changes.
You could safe the button name in a variable like so:
$(document).ready(function() {
var recipient = null;
$("#exampleModal").on('shown.bs.modal', function(e) {
var button = $(e.relatedTarget);
var modal = $(this);
recipient = button.data('name');
modal.find('.modal-title').text('New message to ' + recipient);
});
$('#exampleModal').on('hidden.bs.modal', function(recipient) {
if (recipient) {
alert('The message will not be sended to ' + recipient);
recipient = null; // important to reset this var for a second trigger
}
});
});

Want to display Modal pop up with changes in the Edit form in ASP.NET MVC application

I want a Modal to display all the changes made in the Edit form in ASP.NET MVC application. If user has not made any changes then Modal should not appear.
I have written JavaScript code which shows the changes but I do not think that this is the proper way to do this.
I have a Modal which opens on click of Submit button.
My JavaScript Code is:
<script type="text/javascript">
var FirstName = "#Html.Raw(ViewBag.FName)";
var LastName = "#Html.Raw(ViewBag.LName)";
var NameAddress = "#Html.Raw(ViewBag.NameAddress)";
$(document).ready(function () {
$("#btnSubmit").click(function () {
if ($("#FName").val() == FirstName && ("#LName").val() == LastName && ("#Address").val() == NameAddress ) {
alert("There is no value changed in textbox");
}
else {
alert("First Name changed from:" + FirstName + " to " + $("#FName").val());
}
});
});
</script>
Modal to display the changes:
<input type="submit" id="btnSubmit" value="Save" class="btn btn-primary" data-toggle="modal" data-target="#ListofChanges" />
<div id="ListofChanges" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">PhoneBook Details changed from</h4>
</div>
<div class="modal-body">
<ul>
<li>
"#Html.Raw(ViewBag.FName)"
</li>
<li>
"#Html.Raw(ViewBag.LName)"
</li>
<li>
"#Html.Raw(ViewBag.NameAddress)"
</li>
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Please guide me. I got stuck in this. Thank you.
You have to use a modal method to open it up:
<script type="text/javascript">
var FirstName = "#Html.Raw(ViewBag.FName)";
var LastName = "#Html.Raw(ViewBag.LName)";
var NameAddress = "#Html.Raw(ViewBag.NameAddress)";
$(document).ready(function () {
$("#btnSubmit").click(function () {
if ($("#FName").val() == FirstName && ("#LName").val() == LastName && ("#Address").val() == NameAddress ) {
alert("There is no value changed in textbox");
}
else {
$('#ListofChanges').modal('show') // <-- HERE
}
});
});
</script>
Docs here to Modal methods

display a bootstrap modal if checkbox is checked

I have a test page that when a user clicks on a form button, a bootstrap modal appears and displays a yes/no message to the user. It seems to be working OK.
However, I have been trying to change the code so that the bootstrap modal is displayed / triggered when the user checks a checkbox, but I am having trouble understanding the code I have.
I am hoping someone can show me how to adapt my code so the checked checkbox triggers the modal display.
Here is the script code that I have
<script>
// START: photograph remove modal code.
$('a[photograph-remove-confirm]').click(function(ev) {
var href = $(this).attr('href');
if (!$('#photographRemoveConfirmModal').length) {
$('body').append('<div id="photographRemoveConfirmModal" class="modal modal-confirm-small-width hide fade" role="dialog" aria-labelledby="miscConfirmLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true"><icon class="icon-remove"></icon></button><h4 class="modal-title" id="miscConfirmLabel">{% trans "Confirm" %} - {% trans "Remove" %} {% trans "Photograph" %}</h4></div><div class="modal-body"></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">{% trans "Cancel" %}</button> <a class="btn-u btn-u-blue" id="photographRemoveConfirmOK">{% trans "Remove" %} {% trans "Photograph" %}</a></div></div>');
}
$('#photographRemoveConfirmModal').find('.modal-body').text($(this).attr('photograph-remove-confirm'));
$('#photographRemoveConfirmOK').attr('href', href);
$('#photographRemoveConfirmModal').modal({show: true});
return false;
});
// FINISH: photograph remove modal code.
</script>
Here is the template button code that displays the modal when clicked:
{% trans "Test" %}
Here is the template checkbox code that I want to use to trigger the modal:
<input type="checkbox" id="id_remove_photograph" name="remove_photograph" class="checkbox_resize" onchange="remove_photograph_change();"> Remove Photograph</input>
Here is the onchange="remove_photograph_change" function displayed in the checkbox above.
function remove_photograph_change() {
if ($('#id_remove_photograph').is(':checked')) {
// just some code
}
}
I think that the following changes will fix the issue you have.
Change your checkbox code to this:
<input type="checkbox" id="id_remove_photograph" name="remove_photograph" class="checkbox_resize" onchange="remove_photograph_change();" photograph-remove-confirm="Your Photograph will be removed only after you save the form!"> Remove Photograph</input>
Change your modal code to this:
// START: photograph remove modal code.
$('[photograph-remove-confirm]').click(function(ev) {
if (!$('#photographRemoveConfirmModal').length) {
$('body').append('<div id="photographRemoveConfirmModal" class="modal modal-confirm-small-width hide fade" role="dialog" aria-labelledby="miscConfirmLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true"><icon class="icon-remove"></icon></button><h4 class="modal-title" id="miscConfirmLabel">{% trans "Confirm" %} - {% trans "Remove" %} {% trans "Photograph" %}</h4></div><div class="modal-body"></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">{% trans "Cancel" %}</button> <a class="btn-u btn-u-blue" id="photographRemoveConfirmOK">{% trans "Remove" %} {% trans "Photograph" %}</a></div></div>');
}
$('#photographRemoveConfirmModal').find('.modal-body').text($(this).attr('photograph-remove-confirm'));
$('#photographRemoveConfirmModal').modal({show: true});
return false;
});
// FINISH: photograph remove modal code.

Categories

Resources