1

I'm in the middle of building a multiple modal for my website that I'm working on. I've managed to start with something and currently I'm stuck in trying to make modals trigger separately from one another. It is basically how bootstrap does it by appending a data-attribute I believe. I could have just use bootstrap to solve my problem but I would like to avoid all the code bloat and just built it myself.

Here a sample code that I have been working on. I've managed to make the looping but it seems to open the wrong modal.

    $('.modal-container').insertAfter('.layout-container');

    $('.modal-container').each(function(i) {
        $(this).attr('id', "modal" + (i + 1));

        modal_container_id = $(this).attr('data-modal', "modal" + (i + 1));
    });

    $('.modal-item .modal-btn').each(function(i) {

        var modal_id = $(this).attr('id', "modal" + (i + 1));

        $(modal_id).on('click', function() {
            $(modal_container_id).addClass('show-modal');
            $('body').addClass('lock-scroll');
        });
    })


    //Close Modal
	$('.modal-container .close-modal').on('click', function() {
	    $('.modal-container').removeClass('show-modal');
	    $('body').removeClass('lock-scroll');
	})
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

.layout-container {
  position: relative; }

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  visibility: hidden;
  opacity: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  -webkit-transition: opacity 0.3s ease-in;
  -moz-transition: opacity 0.3s ease-in;
  transition: opacity 0.3s ease-in; }
  .modal-container.show-modal {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity 0.3s ease-in;
    -moz-transition: opacity 0.3s ease-in;
    transition: opacity 0.3s ease-in; }
  .modal-container .modal-body {
    position: absolute;
    max-width: 500px;
    height: 500px;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    margin: auto;
    padding: 20px;
    background-color: #fff; }

/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="layout-container">
    <div class="modal-item">
        <button class="modal-btn">Modal One Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal One
        </div>
    </div>


    <div class="modal-item">
        <button class="modal-btn">Modal Two Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal Two
        </div>
    </div>

</div>

4
  • 1
    We need more of your HTML - we can't see how you have coded your Modals Commented Oct 24, 2017 at 8:01
  • 1
    you have several errors here: first, you give modal1 / modal2 as id to both the opening buttons and the modal div, and every id should be unique, change one of the prefix. Second, you don't select the good element in the click function, but you reuse a previous var $(modal_container_id). Use a selector based on the button id instead Commented Oct 24, 2017 at 8:02
  • When you intent to use id selector prefix # i.e. $('#' + modal_id), However its better to use to DOM traversal method to target the desired element Commented Oct 24, 2017 at 8:05
  • @Satpal basically the way I did is if the ID on the button matches the ID on the .modal-container class it will trigger and show the modal Commented Oct 24, 2017 at 8:07

4 Answers 4

3

If I understood your question. You want to show the respective modal container on button click events. I have simplified the code. Hope it works.

        $('.modal-btn').on('click', function() {
            $(this).next('.modal-container').addClass('show-modal');
            $('body').addClass('lock-scroll');
        });


    //Close Modal
	$('.modal-container .close-modal').on('click', function() {
	    $('.modal-container').removeClass('show-modal');
	    $('body').removeClass('lock-scroll');
	})
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

.layout-container {
  position: relative; }

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  visibility: hidden;
  opacity: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  -webkit-transition: opacity 0.3s ease-in;
  -moz-transition: opacity 0.3s ease-in;
  transition: opacity 0.3s ease-in; }
  .modal-container.show-modal {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity 0.3s ease-in;
    -moz-transition: opacity 0.3s ease-in;
    transition: opacity 0.3s ease-in; }
  .modal-container .modal-body {
    position: absolute;
    max-width: 500px;
    height: 500px;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    margin: auto;
    padding: 20px;
    background-color: #fff; }

/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="layout-container">
    <div class="modal-item">
        <button class="modal-btn">Modal One Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal One
        </div>
    </div>


    <div class="modal-item">
        <button class="modal-btn">Modal Two Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal Two
        </div>
    </div>

</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Hold on what if the .modal-container is outside the .layout-container class hence $('.modal-container').insertAfter('.layout-container'); it needs to be outside
Here .modal-container and .modal-btn both are under same parent. If .modal-container is outside the .layout-container you can use jQuery parent() method to find closest .modal-container.
1

If you make the below changes to your code, it will work fine.

Changes made:

  1. I have commented out the line $(this).attr('id', "modal" + (i + 1)) as it will create duplicate id for modal-container.

  2. Change $(modal_container_id).addClass('show-modal'); to $("[data-modal='" + $(this).attr("id") + "']").addClass('show-modal'); as modal_container_id refers to modal2 because of previous loop.

$('.modal-container').insertAfter('.layout-container');

$('.modal-container').each(function (i) {
	modal_container_id = $(this).attr('data-modal', "modal" + (i + 1));
});

$('.modal-item .modal-btn').each(function (i) {
	var modal_id = $(this).attr('id', "modal" + (i + 1));
	$(modal_id).on('click', function () {
		$("[data-modal='" + $(this).attr("id") + "']").addClass('show-modal');
		$('body').addClass('lock-scroll');
	});
})

//Close Modal
$('.modal-container .close-modal').on('click', function () {
	$('.modal-container').removeClass('show-modal');
	$('body').removeClass('lock-scroll');
})
/* http://meyerweb.com/eric/tools/css/reset/ 
v2.0 | 20110126
License: none (public domain)
*/

	html,
	body,
	div,
	span,
	applet,
	object,
	iframe,
	h1,
	h2,
	h3,
	h4,
	h5,
	h6,
	p,
	blockquote,
	pre,
	a,
	abbr,
	acronym,
	address,
	big,
	cite,
	code,
	del,
	dfn,
	em,
	img,
	ins,
	kbd,
	q,
	s,
	samp,
	small,
	strike,
	strong,
	sub,
	sup,
	tt,
	var,
	b,
	u,
	i,
	center,
	dl,
	dt,
	dd,
	ol,
	ul,
	li,
	fieldset,
	form,
	label,
	legend,
	table,
	caption,
	tbody,
	tfoot,
	thead,
	tr,
	th,
	td,
	article,
	aside,
	canvas,
	details,
	embed,
	figure,
	figcaption,
	footer,
	header,
	hgroup,
	menu,
	nav,
	output,
	ruby,
	section,
	summary,
	time,
	mark,
	audio,
	video {
		margin: 0;
		padding: 0;
		border: 0;
		font-size: 100%;
		font: inherit;
		vertical-align: baseline;
	}

	/* HTML5 display-role reset for older browsers */

	article,
	aside,
	details,
	figcaption,
	figure,
	footer,
	header,
	hgroup,
	menu,
	nav,
	section {
		display: block;
	}

	body {
		line-height: 1;
	}

	ol,
	ul {
		list-style: none;
	}

	blockquote,
	q {
		quotes: none;
	}

	blockquote:before,
	blockquote:after,
	q:before,
	q:after {
		content: '';
		content: none;
	}

	table {
		border-collapse: collapse;
		border-spacing: 0;
	}

	.layout-container {
		position: relative;
	}

	.modal-container {
		position: fixed;
		top: 0;
		left: 0;
		z-index: 100;
		visibility: hidden;
		opacity: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.5);
		-webkit-transition: opacity 0.3s ease-in;
		-moz-transition: opacity 0.3s ease-in;
		transition: opacity 0.3s ease-in;
	}

	.modal-container.show-modal {
		visibility: visible;
		opacity: 1;
		-webkit-transition: opacity 0.3s ease-in;
		-moz-transition: opacity 0.3s ease-in;
		transition: opacity 0.3s ease-in;
	}

	.modal-container .modal-body {
		position: absolute;
		max-width: 500px;
		height: 500px;
		top: 0;
		bottom: 0;
		right: 0;
		left: 0;
		margin: auto;
		padding: 20px;
		background-color: #fff;
	}

	/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="layout-container">
	<div class="modal-item">
		<button class="modal-btn">Modal One Trigger</button>

		<div class="modal-container">
			<button class="close-modal">Close Modal</button>
			Modal One
		</div>
	</div>

	<div class="modal-item">
		<button class="modal-btn">Modal Two Trigger</button>

		<div class="modal-container">
			<button class="close-modal">Close Modal</button>
			Modal Two
		</div>
	</div>
</div>

Comments

1

You can simply use Jquery UI to create modals.

$(document).ready(function(){
		
		$( ".dialog" ).dialog({
			autoOpen: false
		});
		
		$("#modal1Btn").click(function(){
			$( "#dialog1" ).dialog("open" );
		});
		
		$("#modal2Btn").click(function(){
			$( "#dialog2" ).dialog("open" );
		})
	})
  
  <!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

</head>
<body>
 
 <button id="modal1Btn" class="modal-btn">Modal One Trigger</button>
 <button id="modal2Btn" class="modal-btn">Modal Two Trigger</button>
 
<div class="dialog" id="dialog1" title="Basic dialog">
  <p>Dailog 1</p>
</div>

<div class="dialog" id="dialog2" title="Basic dialog">
  <p>Dailog 2</p>
</div>
 
 
</body>
</html>

Comments

1

I've edited your js mantaining the html structure. You only have to elaborate ids before moving the modal outside the container ;)

$('.modal-item').each(function(idx) {
  var $modal = $(this).find('.modal-container'),
    $button = $(this).find('.modal-btn');
  $button.data('modal', '#modal-' + idx);
  $modal.attr('id', 'modal-' + idx);
  $modal.insertAfter('.layout-container');
});

$('.layout-container').on('click', '.modal-btn', function() {
  $($(this).data('modal')).addClass('show-modal');
  $('body').addClass('lock-scroll');
});

//Close Modal
$('.modal-container .close-modal').on('click', function() {
  $('.modal-container').removeClass('show-modal');
  $('body').removeClass('lock-scroll');
})
/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  font: inherit;
  vertical-align: baseline; }

/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
  display: block; }

body {
  line-height: 1; }

ol, ul {
  list-style: none; }

blockquote, q {
  quotes: none; }

blockquote:before, blockquote:after,
q:before, q:after {
  content: '';
  content: none; }

table {
  border-collapse: collapse;
  border-spacing: 0; }

.layout-container {
  position: relative; }

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 100;
  visibility: hidden;
  opacity: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  -webkit-transition: opacity 0.3s ease-in;
  -moz-transition: opacity 0.3s ease-in;
  transition: opacity 0.3s ease-in; }
  .modal-container.show-modal {
    visibility: visible;
    opacity: 1;
    -webkit-transition: opacity 0.3s ease-in;
    -moz-transition: opacity 0.3s ease-in;
    transition: opacity 0.3s ease-in; }
  .modal-container .modal-body {
    position: absolute;
    max-width: 500px;
    height: 500px;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
    margin: auto;
    padding: 20px;
    background-color: #fff; }

/*# sourceMappingURL=style.css.map */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="layout-container">
    <div class="modal-item">
        <button class="modal-btn">Modal One Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal One
        </div>
    </div>


    <div class="modal-item">
        <button class="modal-btn">Modal Two Trigger</button>

        <div class="modal-container">
            <button class="close-modal">Close Modal</button>
            Modal Two
        </div>
    </div>

</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.