Bootstrap modal, strange behavior (duplicate informations) - javascript

I'm using Laravel 5.5, Bootstrap 3.7 and jQuery.
When I open the modal and close it directly, then when I do an action in the modal it performs two times the opening function.
If I open and close it (directly) three times, then when I do an action in the modal it performs four times the opening function.
Finnaly, if I open and close it (directly) X times, then when I do an action in the modal it performs X+1 times the opening function.
It performs the function for all the old openings and for the last opening.
HTML :
#foreach(... as $seance)
...
<div class="row">
<button class="btn btn-primary bouton-reservation" data-toggle="modal" data-target="#reservationModal-{{ $seance->id_seance }}"</button>
</div>
</div>
</div>
<div class="modal fade reservationModal" id="reservationModal-{{ $seance->id_seance }}" data-seance='{{ $seance->id_seance }}' role="dialog" aria-labelledby="reservationModal-{{ $seance->id_seance }}" aria-hidden="true">
// modal content with a form.
</div>
#endforeach
JS :
$(document).ready(function () {
...
$(document).on('shown.bs.modal', '.reservationModal', function (e) {
// JS content
});
$(document).on('hidden.bs.modal', '.reservationModal', function(e) {
// JS content
});
});
I hope the problem is explained quite clearly ...
The problem can not come from the fact that I use $(document).on('shown.bs.modal', '#reservationModal', function (e) { instead of $('#reservationModal').on('shown.bs.modal', function (e) {?
Exemple
On this exemple, I close 2 times the modal, and when I choose Nico on the select after a third opening, my JS append 3 times my data.
Append starts when I click on the button Ajouter, however, I only click once and not three.
Futhermore, when I delete the info with the X on the right side, all info disappears.
Thank's for help !

Related

JavaScript one() event handling chaining causes strange errors

I need your help. I'm currently writing some code to handle a modal behavior like clicking on buttons. For catching multiple events once, I already posted this question:
JavaScript event handling code get's called multiple times
There it said to use the jQuery .one() function to only catch one click when opening the popup and clicking one button multiple times. This works great for one button but when I use two buttons, I came up with another error.
First I've changed my event handling to accept multiple events:
jQuery(document).ready(function($) {
$('button').click(function() {
openConfirmationRemodal().one({
confirmation: function() {
console.log('Confirmation');
},
cancellation: function() {
console.log('Cancellation');
}
});
});
});
When I click on a button, my popup opens with two buttons:
When I click now the Nein button, the popup closes and the console logs Cancellation. When I open the popup again now and click the Ja button, Confirmation get's logged but twice. I really don't understand this and how to fix this..
If I do this the opposite way, the error is the same but just in a different order:
Here you have a working example. Somehow the action in die example get's triggered twice (initially). This is different to the normal progress in my browser but I think this depends on the snippet functionality:
jQuery(document).ready(function($) {
$('button').click(function() {
openConfirmationRemodal().one({
confirmation: function() {
console.log('Confirmation');
},
cancellation: function() {
console.log('Cancellation');
}
});
});
});
function openConfirmationRemodal() {
let remodal = $(`[data-remodal-id=test]`);
remodal.remodal().open();
return remodal;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/remodal#1.1.1/src/remodal.js"></script>
<button>Open Pop-Up</button>
<div class="remodal" data-remodal-id="test">
<button data-remodal-action="close" class="remodal-close"></button>
<h1>Remodal</h1>
<p>
Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
</p>
<br>
<button data-remodal-action="cancel" class="remodal-cancel">Cancel</button>
<button data-remodal-action="confirm" class="remodal-confirm">OK</button>
</div>
The issue is because you re-bind the events every time you click the 'Open' button. To fix this define the modal and events just once, when the page loads, and then call open() on the modal when the button is clicked. Try this:
let $remodal = $(`[data-remodal-id=test]`);
let modal = $remodal.remodal();
$remodal.on({
confirmation: function() {
console.log('Confirmation');
},
cancellation: function() {
console.log('Cancellation');
}
});
jQuery($ => {
$('button').click(function() {
modal.open();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/remodal#1.1.1/src/remodal.js"></script>
<button>Open Pop-Up</button>
<div class="remodal" data-remodal-id="test">
<button data-remodal-action="close" class="remodal-close"></button>
<h1>Remodal</h1>
<p>
Responsive, lightweight, fast, synchronized with CSS animations, fully customizable modal window plugin with declarative configuration and hash tracking.
</p>
<br>
<button data-remodal-action="cancel" class="remodal-cancel">Cancel</button>
<button data-remodal-action="confirm" class="remodal-confirm">OK</button>
</div>

Show confirm dialog with two buttons from javascript using bootstrap

First of all, I am newbie in web programming. Now I am maintaining an ASP.NET MVC application.
I have a view (cshtml) from which I would like to show a modal window in the center of the screen. I would like a modal window like typical confirm dialog in javascript, but I want to put a title, a text, and two buttons, ok and cancel. From my javascript function (which is placed in my ASP.NET MVC view (cshtml)), in this case, onInvoice, I need to do some things depending on the button clicked on the modal window.
For example:
function onInvoice() {
if (some_condition_happens){
// At this point I want to show/call modal window by passing title and text
// Now I read which button was clicked in the modal window
if (ok_button_is_pressed)
{
// Do something when button ok is clicked in the modal window
}
else if (cancel_button_is_pressed) {
// Do something when button cancel is clicked in the modal window
}
}
}
I have searched in the web and I have found an example using bootstrap here. Also posted here. I post here:
Javascript code:
$('button[name="remove_levels"]').on('click', function(e) {
var $form = $(this).closest('form');
e.preventDefault();
$('#confirm').modal({
backdrop: 'static',
keyboard: false
})
.on('click', '#delete', function(e) {
$form.trigger('submit');
});
});
view:
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script>
<form action="#" method="POST">
<button class='btn btn-danger btn-xs' type="submit" name="remove_levels" value="delete"><span class="fa fa-times"></span> delete</button>
</form>
<div id="confirm" class="modal hide fade">
<div class="modal-body">
Are you sure?
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-primary" id="delete">Delete</button>
<button type="button" data-dismiss="modal" class="btn">Cancel</button>
</div>
</div>
But I do not know where to put above code, javascript function and view within my ASP.NET MVC project structure. My ASP.NET MVC project is organized in areas as well. I would like to put the above view code in somewhere accessible from other views (cshmtl).Furthermore I would like above modal window to be parametrized, title and text basically. Also I do not know how to read response from modal window back to my javascript function onInvoice, and then depending on which button, ok or cancel was clicked do one thing or another. Finally,since modal window will be parametrized, how can I pass title and text to?

How do I get click event of model form button?

On my django web app, I have a webpage and when a button is clicked a modal form is opened. On this form there are a few fields and a save button. When the save button is pressed, I want to do something, like printing an alert. Here is what I tried:
Model form code:
<div class="container-content">
<div class="infor-experience col-lg-2 more_info">
{% if request.user|isEmployer %}
<div class="add-to-list">{% include "layout/addtolistmodal.html" %}</div>
<div class="connect-now bottom">{% include "layout/bidmodal.html" %}</div>
{% endif %}
<!-- more code below here -->
Javascript block in same HTML file as modal above:
<script type="text/javascript">
// Add to short list handler
$('.add-to-list').on('click', '.submit', function(e) {
alert("TEST");
})
</script>
Basically, what I want to do is when the user clicks save on the add-to-list modal, print the alert "TEST".
From my understanding the reason its not working is because it cannot find '.add-to-list' but what I should use instead?
Just attach your click event to already present element which seems to be div.infor-experience, since your modal html gets appended after DOM load. Also, make sure your script renders in web browser if you have provided any conditions for them to render.
$('.infor-experience').on('click', '.submit', function(e) {
alert("TEST");
})
It might be that positioning of your script. At the time of its execution the DOM may not be ready or exist yet.
You could wrap your DOM related codes like so:
$(document).ready(init);
function init(){
$('.add-to-list').on('click', '.submit', function(e) {
alert("TEST");
})
}
Try this instead
$(document).ready(function () {
$('.add-to-list').on('click', '.submit', function(e) {
alert("TEST");
});
});
you should add the code under $(document).ready() so that it waits for whole DOM to load and then attaches the method instead doing so before loading of DOM.

pass HTML link id to js AJAX function through modal plugin

I have over 1.5 million dynamically created (php/html/js) web pages that contain lists of up to 300 people, to whom I need to allow visitors to send messages by using a popup form that is triggered by link next to each person's name. I'm using the PopEasy jquery modals plugin http://thomasgrauer.com/popeasy/ .
All these modals/forms are identical, except for a unique recipient ID associated with each link that needs to be passed through to the AJAX code that fires to save the message to that person's record when the modal's form's Send Message btn is clicked (e.g. "1001', '1002' in the examples below).
For each page, I could dynamically create up to 300 form DIVs, one for each link, but would rather find a clever way to transfer the recipient ID with just one modal/form DIV, to cut down the bandwidth. I should be ok, if I can reference the ID of the link from within the AJAX code (as the "u" var in the example below).
Ideas?
(my competencies: js: "barely any" / html and php: "average".
Here is the code that works for just two links/divs/forms:
<a id="1001" class="modalLink" href="#modal_1001">Send msg</a>
<a id="1001" class="modalLink" href="#modal_1002">Send msg</a>
// the plugin uses the class to fire, and the href to know which of several DIVs of
// that class to use; if the a#id isn't needed, I can strip the "modal_" part out of
// the href to save having to parse it
<div id="modal_1001" class="modal">
<form method="post" action="">
<textarea>(write your msg here)</textarea>
<button type="button" onclick="storeMsgAjax(1001,1234)">Send message</button>
</form>
Close Form
</div>
<div id="modal_1002" class="modal">
<form method="post" action="">
<textarea>(write your msg here)</textarea>
<button type="button" onclick="storeMsgAjax(1002,1234)">Send message</button>
</form>
Close Form
</div>
And here is the js modal plugin function:
$(document).ready(function(){
$('.modalLink').modal({
trigger: '.modalLink', // id or class of link or button to trigger modal
olay:'div.overlay', // id or class of overlay
modals:'div.modal', // id or class of modal
animationEffect: 'slideDown', // overlay effect | slideDown or fadeIn | default=fadeIn
...(other options)...
close:'.closeBtn' // id or class of close button
});
});
And here is the AJAX code:
function storeMsgAjax(s,u)
{
var m = document.getElementById("msgtxt").value;
var url = "http://ifinallyfoundu.com/storeMsg.php?s="+s+"&m="+m+"&u="+u+"&t=" + Math.random();
xmlHttp2 = GetXmlHttpObject();
if (xmlHttp2 == null) {alert("Browser does not support HTTP Request"); return;}
xmlHttp2.onreadystatechange = function()
{
if (xmlHttp2.readyState == 4 && xmlHttp2.status == 200)
{
var formSaveResults = xmlHttp2.responseText;
document.getElementById("modal_"+s).innerHTML = formSaveResults+'<br><br>Close Form' ;
}
}
xmlHttp2.open("GET", url, true);
xmlHttp2.send(null);
}
Looks like I can add an onclick script to each link to put the ID in the innerHTML of a hidden page element, which should be accessible to the AJAX routine. I'm sure there is probably a more elegant solution, but this seems to work.

How to get Twitter Bootstrap Modal's invoker element?

I have got a a element for invoking modal:
<a class="btn" data-toggle="modal" data-target="#myModal" href="http://some-url" >Launch Modal</a>
And, say this is my modal:
<div class="modal hide" id="myModal">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3>Modal header</h3>
</div>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
Close
Save changes
</div>
</div>
I can bind functions to events fired by modal:
$('#myModal').on('hidden', function () {
// do something…
})
My question is: How can i access the a element -which invoked the modal- from my event subscriber function?
It was solved in Bootstrap 3.0.0 thanks to event.relatedTarget.
$('#your-modal').on('show.bs.modal', function (e) {
var $invoker = $(e.relatedTarget);
});
You have to listen to:
$('[data-toggle="modal"]').on('click', function() {
$($(this).attr('href')).data('trigger', this);
});
$('.modal').on('show.bs.modal', function() {
console.log('Modal is triggered by ' + $(this).data('trigger'));
});
You can of course replace show.bs.modal with shown.bs.modal or any other event they fire.
Note that this is for Bootstrap 3.0.0. If you're using 2.3.2 you need to get rid of .bs.modal (I think).What I like about this solution: you do not have to remember who is this, self, that and other proxy calls workarounds.Of course, you have to test if the href attribute is not a real link (the dynamic modal loading option).
The modal element has a data object named modal that saves all the options that are passed. You can set a 'source' data attribute on the element that triggers the modal, set it to the ID of the source, and then retrieve it later from the options variable.
The trigger would be:
<a id="launch-modal-1" class="btn" data-toggle="modal" data-target="#myModal" href="http://some-url" data-source="#launch-modal-1">Launch Modal</a>
In the event callback, get the modal data object, and look at the source option:
$('#myModal').on('hidden', function () {
var modal = $(this).data('modal');
var $trigger = $(modal.options.source);
// $trigger is the #launch-modal-1 jQuery object
});
Currently it's not available out-of-box. There is a feature request for it and a work-around if you want to edit the bootstrap-modal code yourself.
See here
I had a situation where I had to bind some data related to the "invoker", just like you said.
I've managed to solve it by binding a "click" event to it and working with the data like this:
The invoker
<img id="element" src="fakepath/icon-add.png" title="add element" data-toggle="modal" data-target="#myModal" class="add">
The JS to catch data related to the invoker (Just some code example)
$('#element').on('click', function () { // Had to use "on" because it was ajax generated content (just an example)
var self = $(this);
});
Like this, you can handle the data related to your invoker anyway you want.

Categories