Only open closest modal to button - javascript

I have a page which has a random number of items each of which has a button and a modal - as I do not know how many items there will be I am using classes for the button and modal.
When I click any button it loads all the modals whereas I only want it to load the next modal - I have tried to use closest and next but cannot get them to fire.
<div class="social-button-container">
<button type="button" class="social-button">Button</button>
</div>
<div class="socialModal modal fade">
<h2>123</h2>
</div>
<div class="social-button-container">
<button type="button" class="social-button">Button2</button>
</div>
<div class="socialModal modal fade">
<h2>234</h2>
</div>
$(document).ready(function () {
$('.social-button').click(function () {
$('.socialModal').modal();
return false;
});
});
The above code works in that the modals fire but they all do - I tried using:
$(document).ready(function () {
$('.social-button').click(function () {
$('.socialModal').next().modal();
return false;
});
});
but this does nothing at all (none fire)
Also tried:
$(document).ready(function () {
$('.social-button').click(function () {
$(this).next('.socialModal').modal();
return false;
});
});
with the same result - how can I get only the following modal to open on clicking the relevant button?
http://jsfiddle.net/0v0pg7fx/

Your selectors were a bit off, and you probably want to in initialize the modals first.
$('.socialModal').modal({show:false});
$('.social-button').click(function () {
$(this).closest('.social-button-container').next('.socialModal').modal('show');
});
Demo

$(document).ready(function () {
$('.button').click(function () {
$('.Modal').closest().modal();
return false;
});
});

Related

Bootstrap modal hide not working with jquery ajax

I have a modal dialog made with bootstrap, like this:
<div class="modal fade" id="myid">
<div class="modal-dialog">
<div class="modal-content">
Loading...
</div>
</div>
</div>
And I make a javascript function like this:
$(document)
.ajaxStart(function () {
$('#myid').modal('show');
})
.ajaxStop(function () {
$('#myid').modal('hide');
});
But when I call some ajax function the modal appears but no hide. I put console.log in both functions (ajaxStart and ajaxStop) and it was called. when I replace ajaxStop as below, everything works, but not appears right.
$(document)
.ajaxStart(function () {
$('#myid').modal('show');
})
.ajaxStop(function () {
$('#myid').hide();
$('.fade').hide();
});
The main problema is when I call another modal within ajax, then I click in link, loading ajax appears, request is send to server, response returns, modal with data from request appears, but loading modal not hide.
How can I fix it?
You have to set a timeout.
That works for me:
setTimeout(function () { $("#myid").modal("hide"); }, 500);
Can you try binding to the ajax events like this:
$("#myid").bind({
ajaxStart: function() { $(this).show(); },
ajaxStop: function() { $(this).hide(); }
});
Instead of using $('#myid').hide(); in ajaxStop, use $('#myid').modal('hide');
Hide processing does not occur, probably because the closing is done without performing the modal opening operation. This worked for me;
setTimeout(() => {$('#ModalExpeditionSeal').modal('hide')}, 350)
you can use as the following:
$("#myid").modal().hide()

jQuery multiple click handling

I have the code below working to handle clicking a link from a list, showing a screen, and then hiding it when the .back button is pressed.
Is there a cleaner way to handle the click function for any x number of list items?
$(".container").on("click", ".dog-btn", function() {
$(".screen1").css("display","flex")
});
$(".container").on("click", "#back", function() {
$(".screen1").css("display","none")
});
$(".container").on("click", ".cat-btn", function() {
$(".screen2").css("display","flex")
});
$(".container").on("click", "#back", function() {
$(".screen2").css("display","none")
});
$(".container").on("click", ".bird-btn", function() {
$(".screen3").css("display","flex")
});
$(".container").on("click", "#back", function() {
$(".screen3").css("display","none")
});
You can use html5 data attributes to pass screen classes.
HTML CODE
<div class="container">
<button class="flex" data-screen="screen1"> DOG</button>
Back
</div>
JavaScript Code
//Flex Handler
$(".container").on("click", ".flex", function() {
$("."+$(this).data("screen")).css("display","flex")
});
//Back Button Handler
$(".container").on("click", ".back", function() {
$("."+$(this).data("screen")).css("display","none")
});
Hope it helps.
You can have benefits of data-* attributes of HTML5 as its answered here.
But additionally you can put your custom styles in JSON format in data attributes too. So that you don't need to specify it on every control. That would just go with one click handler as below
$('button').on('click',function(){
var target=$(this).data('target'),
css = $(this).data('css');
$(target).css(css);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-css='{"background":"yellow"}'
data-target="#screen1">
click 1
</button>
<button data-css='{"background":"red"}'
data-target="#screen2">
click 2
</button>
<div id="screen1">
screen1
</div>
<div id="screen2">
screen2
</div>
A mockup without jQuery, using event delegation and ES20xx
document.querySelector(".container").addEventListener("click", handleEvents);
document.querySelector("#back").click();
function handleEvents(evt) {
const origin = evt.target;
const screenMap = {
"dog-btn": "screen1",
"cat-btn": "screen2",
"bird-btn": "screen3",
};
if (origin.id && origin.id === "back") {
const screens = `.${Object.entries(screenMap).map(([key, value]) => value).join(",.")}`;
return Array.from(document.querySelectorAll(screens))
.forEach(screen => screen.style.display = "none");
}
if (Array.from(origin.classList).filter(v => /\-btn$/i.test(v)).length) {
return document.querySelector(`.${screenMap[origin.classList]}`)
.style.display = "flex";
}
}
<div class="container">
<div class="screen1">screen 1 DOG</div>
<div class="screen2">screen 2 CAT</div>
<div class="screen3">screen 3 BIRD</div>
<button id="back">#back</button>
<button class="dog-btn">.dog-btn</button>
<button class="cat-btn">.cat-btn</button>
<button class="bird-btn">.bird-btn</button>
</div>

Reload page after a particular modal is closed

I have two modals on a page. I only want one to refresh the parent page once closed. However, even if I add the code to do so both modals refresh the page after closing. Any idea why?
<script>
$(document.body).on('hidden.bs.modal', function () {
$('#myModal').removeData('bs.modal');
});
</script>
<script>
$(document.body).on('hidden.bs.modal', function () {
$('#myModal2').removeData('bs.modal');
location.reload();
});
</script>
Modal 1 call:
<a data-toggle="modal" data-target="#myModal" href="modal_target.cfm?M=#MLink#" class="btn btn-#bg_color#">#CP#</a>
Modal 2 call:
<a data-toggle="modal" data-target="#myModal2" href="modal_AmendCP.cfm?M=#MLink#" title="view details" class="btn btn-primary">#Measure#</a>
Thanks for any help!
Both of your functions are being fired on the same event of modal closing on $(document.body).
You should change it to the be triggered on modal objects only:
<script>
$('#myModal').on('hidden.bs.modal', function () {
$('#myModal').removeData('bs.modal');
});
</script>
<script>
$('#myModal2').on('hidden.bs.modal', function () {
$('#myModal2').removeData('bs.modal');
location.reload();
});
</script>
From the Bootstrap Documentation:
hidden.bs.modal: This event is fired when the modal has finished being hidden from the user (will wait for CSS transitions to complete).
you should select exact modal to add Event Listener.
if selector is "document.body", event will fire for both.
in your code: function called for 'hidden.bs.modal' is only
function () {
$('#myModal2').removeData('bs.modal');
location.reload();
}
it replace
function () {
$('#myModal').removeData('bs.modal');
}
because it is declared later.

Javascript event triggering creating multiple button .on('click)

I'm using HTML slim for the code below.
.page
.paper
button.button.js-copier I copy things
- content_for :js_includes do
javascript:
var startingHtml = $('.page').html();
function initializePlugin() {
$('.js-copier').each(function () {
$(this).on('click', function () {
$('.page').append(startingHtml);
$(document).trigger('page-refreshed');
});
});
}
// Run it right away
initializePlugin();
$(document).on('page-refreshed', initializePlugin);
Is there a way to fix the fact that when I click on the "I copy things" button, it creates multiple copies of the button as it is iterating over all the button from the button that was selected?
Also, is there a better way to write this code. All I'm trying to do is duplicate the button anytime I click on any buttons(first and any new button created buttons)
-Anthony
First change this:
$('.js-copier').each(function () {
$(this).on('click', function () {
...
to this:
$('.page').on('click', '.js-copier', function () {
...
Read this to understand https://learn.jquery.com/events/event-delegation/#event-propagation
Then remove the 'page-refreshed' event because you don't need it:
$(document).trigger('page-refreshed');
...
$(document).on('page-refreshed', initializePlugin);
Demo solution:
var startingHtml = $('.page').html();
function initializePlugin() {
$('.page').on('click', '.js-copier', function () {
$('.page').append(startingHtml);
});
}
// Run it right away
initializePlugin();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page">
<div class="paper">
<button class="button js-copier"> I copy things</button>
</div>
</div>

Reveal: jQuery Modal Plugin Won't Appear

I'm trying to use Reveal by Zurb to display a form, yet when I select the item that triggers the event the screen darkens like Reveal is working, but it will not show the pane. Any ideas? Thanks a lot for the help!
Planner.js
$(function() {
$('.event_list li').click( function(e) {
console.log(this.id);
$('#update_view_content').reveal('http://example.com/user/planner/update/'+this.id);
});
$('#updateForm').live('submit', function() {
var data = $('#updateForm').serialize();
var url = $(this).attr('action');
$.post(url, data);
return false;
});
});
From looking at the documentation online it seems there are no parameters for the reveal() method - the reveal method just shows a div on the screen, so
You would created markup on your page :
<div id="myModal" class="reveal-modal">
<h1>Modal Title</h1>
<p>Any content could go in here.</p>
<a class="close-reveal-modal">×</a>
</div>
then reveal it ...
$('#myButton').click(function(e) {
e.preventDefault();
$('#myModal').reveal();
});
If you want to load something into the div and then reveal i suggest this approach :
$('.event_list li').click( function(e) {
console.log(this.id);
$('#update_view_content').load('http://example.com/user/planner/update/'+this.id,function() {
$('#update_view_content').reveal();
});
});
That should load in the contents and then once the load has completed call the reveal method. untested

Categories