7 Replies - 8583 Views - Last Post: 17 June 2014 - 06:48 PM

#1 RandomlyKnighted   User is offline

  • D.I.C Lover
  • member icon

Reputation: 119
  • View blog
  • Posts: 1,384
  • Joined: 14-January 10

Click event not working with dynamic content

Posted 16 June 2014 - 08:44 AM

I'm working on a modal plugin. So far I've got 3 buttons in my HTML. The first two buttons work fine and are just there to test the plugin as I go along. With the third button, however, I can't seem to get the click event to work. When the page loads it dynamically creates the modal and appends it to the end of the body. During this process it also gives the button a class of modal-show. As you can see the modal-show click event is the one that's not working with the dynamic content. I was originally using the .click() event method but I read online that it doesn't work with dynamic content because the content is not there when the page is originally loaded. Any help I can get is greatly appreciated.

index.html
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>jQuery Modal Plugin</title>
		<link rel="stylesheet" href="style.css">
	</head>
	<body>		
		<div class="container">
			<button class="modal-show" data-modal-id="modal1">Click Here to Open Modal #1</button>
			<br /><br />
			<button class="modal-show" data-modal-id="modal2">Click Here to Open Modal #2</button>
			<br /><br />
			<button id="jQueryModal" data-modal-id="gwModal">Click Here to Load An External Page</button>
			
			
			<!--
			 //
			 // 
			 //		Add modals after this point
			 //
			 //
			 -->			
			
			
			<div id="modal1" class="modal">
				<div class="modal-header">
					<h4>Modal Window Heading 1</h4>
					<button class="close">&times;</button>
				</div>
				<div class="modal-body">
					<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Voluptatum, eligendi, doloremque fuga ullam dolore asperiores nemo expedita officia magni eius error repudiandae culpa earum vel quaerat voluptatem molestiae! Esse, cupiditate?</p>
				</div>
			</div>
			
			<div id="modal2" class="modal">
				<div class="modal-header">
					<h4>Modal Window Heading 2</h4>
					<button class="close" aria-hidden="true">&times;</button>
				</div>
				<div class="modal-body">
					<h3>Heading 3</h3>
					<h4>Heading 4</h4>
					<h5>Heading 5</h5>
					<h6>Heading 6</h6>
				</div>
			</div>
	
		</div>
		
		<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
		<script type="text/javascript" src="modal.js"></script>
		<script type="text/javascript" src="script.js"></script>
	</body>
</html>



style.css
.modal-backdrop
{
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.5);
	position: absolute;
	top: 0;
	left: 0;
	z-index: 10;
	display: none;
}

.modal
{
	width: 400px;
	background-color: #FFFFFF;
	box-shadow: 0 0 10px #000000;
	border-radius: 10px;
	overflow: hidden;
	position: relative;
	top: 50%;
	left: 50%;
	margin-top: -200px;
	margin-left: -200px;
	z-index: 11;
	display: none;
}

.modal-header 
{
	min-height: 15px;
	padding: 5px 15px;
	border-bottom: 1px solid #E5E5E5;
}

.modal-body > p,h1,h2,h3,h4,h5,h6
{
	padding: 0px 15px;
}

.modal-footer
{
	min-height: 15px;
	padding: 5px 15px;
	border-top: 1px solid #E5E5E5;
}

button.close
{
	-webkit-appearance: none;
	padding: 0;
	cursor: pointer;
	background: transparent;
	border: 0;
}

.close
{
	position: absolute;
	top: 2%;
	right: 2%;
	font-size: 21px;
	font-weight: bold;
	line-height: 1;
	color: #000000;
	text-shadow: 0 1px 0 #FFFFFF;
	filter: alpha(opacity=20);
	opacity: .2;
}

.close:hover, .close:focus
 {
	color: #000000;
	text-decoration: none;
	cursor: pointer;
	filter: alpha(opacity=50);
	opacity: .5;
}



script.js
$('#jQueryModal').modal(
	{
		url		: 	'dig_deeper.jpg'
	});



modal.js
(function($)
{
	$.fn.modal = function(userOptions)
	{
		var defaultOptions = 
		{
			url			: 	null
		}

		options = $.extend({}, defaultOptions, userOptions);
		
		$(this).addClass('modal-show');
		var modalID = $(this).data('modal-id');
		buildModal($(this), modalID);
	};
	
	function buildModal(element, id)
	{
		//	Create the modal window container
		var modalWindow = document.createElement('div');
		$(modalWindow).attr('id', id).addClass('modal');
		
		//	Create the modal body where we will load the external html/image
		var modalBody = document.createElement('div');
		$(modalBody).addClass('modal-body');

		//	Create and add the close button
		var closeBtn = document.createElement('button');
		$(closeBtn).addClass('close');
		$(closeBtn).text('&times;');

		$(modalBody).append(closeBtn);
		
		//	If the user provides an external link/image then load that image into the modal body
		if (options.url)
		{
			$(modalBody).load(options.url);
		}

		else
		{
			$(modalBody).append(element.contents);
		}

		// Finally let's add the content to the modal itself
		$(modalWindow).append(modalBody);
		$('body').append(modalWindow);
	}
	
	function closeModal()
	{
		//	Get the DOM that contains the modal so we can remove the backdrop
		var content = $('.modal-backdrop').contents();
		
		//	Have the backdrop and the modal fade out
		$('.modal-backdrop').find('#' + modalID).fadeOut();
		
		// Remove the backdrop from around the modal
		$('.modal-backdrop').replaceWith(content);	
	}
	
	$('.modal-show').on("click", function(event)
	{
		event.preventDefault();
		alert('Im in the modal-show click event');
		
		//	Get the ID of the modal that we want to show
		modalID = $(this).data('modal-id');
		
		/*
		*	Add the backdrop around the modal (This is done primarily
		*	to make the developer's life easier so that they don't
		*	have to create the div for the backdrop.
		*/
		$('#' + modalID).wrapAll('<div class="modal-backdrop">');
		
		// Have the backdrop and the modal fade in
		$('.modal-backdrop').fadeIn().find('#' + modalID).fadeIn();
	});
	
	$('.close').on("click", function(event)
	{
		event.preventDefault();
		
		closeModal();
	});

})(jQuery);



Is This A Good Question/Topic? 0
  • +

Replies To: Click event not working with dynamic content

#2 Dormilich   User is offline

  • 痛覚残留
  • member icon

Reputation: 4245
  • View blog
  • Posts: 13,452
  • Joined: 08-June 10

Re: Click event not working with dynamic content

Posted 16 June 2014 - 09:08 AM

why donít you just define the click event when you create the button (i.e. after line #28)?
Was This Post Helpful? 0
  • +
  • -

#3 RandomlyKnighted   User is offline

  • D.I.C Lover
  • member icon

Reputation: 119
  • View blog
  • Posts: 1,384
  • Joined: 14-January 10

Re: Click event not working with dynamic content

Posted 16 June 2014 - 10:52 AM

Because I need the click event to work with both the dynamic content and for the HTML code as well. By moving the click event into the buildModal function I don't see how it would get called by the other buttons since they don't use the buildModal function.
Was This Post Helpful? 0
  • +
  • -

#4 RandomlyKnighted   User is offline

  • D.I.C Lover
  • member icon

Reputation: 119
  • View blog
  • Posts: 1,384
  • Joined: 14-January 10

Re: Click event not working with dynamic content

Posted 16 June 2014 - 07:27 PM

I somewhat followed your advice by taking the code in the modal-show click event and putting that in a function. I then created a click event specifically for whatever is calling the modal function. Inside both click events I called the function that I just created. So now the modal will appear I just got to work out a couple of bugs like figuring out why the close button isn't getting added and figuring out why it lets me load an external page but when I tell it to load an image it just gives me data from the file like it would if I opened the image in Notepad or Word. Below my updated modal.js code in case anyone would like to see what I've changed.

(function($)
{
	$.fn.modal = function(userOptions)
	{
		var defaultOptions = 
		{
			url			: 	null
		}

		options = $.extend({}, defaultOptions, userOptions);
		
		$(this).addClass('modal-show');
		var id = $(this).data('modal-id');
		buildModal($(this), id);

		// Add an event listener to the button
		$(this).on("click", function(event)
		{
			showModal(id);
		});
	};
	
	function buildModal(element, id)
	{
		//	Create the modal window container
		var modalWindow = document.createElement('div');
		$(modalWindow).attr('id', id).addClass('modal');
		
		//	Create the modal body where we will load the external html/image
		var modalBody = document.createElement('div');
		$(modalBody).addClass('modal-body');

		//	Create and add the close button
		var closeBtn = document.createElement('button');
		$(closeBtn).addClass('close');
		$(closeBtn).text('&times;');

		$(modalBody).append(closeBtn);
		
		//	If the user provides an external link/image then load that image into the modal body
		if (options.url)
		{
			$(modalBody).load(options.url);
		}

		else
		{
			$(modalBody).append(element.contents);
		}

		// Finally let's add the content to the modal itself
		$(modalWindow).append(modalBody);
		$('body').append(modalWindow);
	}
	
	function closeModal(id)
	{
		//	Get the DOM that contains the modal so we can remove the backdrop
		var content = $('.modal-backdrop').contents();
		
		//	Have the backdrop and the modal fade out
		$('.modal-backdrop').find('#' + id).fadeOut();
		
		// Remove the backdrop from around the modal
		$('.modal-backdrop').replaceWith(content);	
	}

	function showModal(id)
	{
		/*
		*	Add the backdrop around the modal (This is done primarily
		*	to make the developer's life easier so that they don't
		*	have to create the div for the backdrop.
		*/
		$('#' + id).wrapAll('<div class="modal-backdrop">');

		// Have the backdrop and the modal fade in
		$('.modal-backdrop').fadeIn().find('#' + id).fadeIn();
	}
	
	$('.modal-show').on("click", function(event)
	{
		event.preventDefault();
		
		//	Get the ID of the modal that we want to show
		id = $(this).data('modal-id');

		showModal(id);
	});
	
	$('.close').on("click", function(event)
	{
		event.preventDefault();
		
		//	Get the ID of the modal that we want to show
		id = $(this).data('modal-id');

		closeModal(id);
	});

})(jQuery);


Was This Post Helpful? 0
  • +
  • -

#5 e_i_pi   User is offline

  • = -1
  • member icon

Reputation: 879
  • View blog
  • Posts: 1,893
  • Joined: 30-January 09

Re: Click event not working with dynamic content

Posted 16 June 2014 - 09:23 PM

If you want to bind events to DOM elements that don't exist (but may exist in the future) you have to delegate the event. See below:
$('#myParentElement').on('click', '.myChildElement', function() {
    alert('This is a delegated click event for elements of class "myChildElement" that are children of the element with id "myParentElement"');
});


See here for the syntax / doco.

Basically, if the element doesn't exist at the time of the event declaration, then you need to delegate the event by attaching it to the parent element and having it apply only to the relevant child(ren) element(s).

This post has been edited by e_i_pi: 16 June 2014 - 09:23 PM

Was This Post Helpful? 0
  • +
  • -

#6 RandomlyKnighted   User is offline

  • D.I.C Lover
  • member icon

Reputation: 119
  • View blog
  • Posts: 1,384
  • Joined: 14-January 10

Re: Click event not working with dynamic content

Posted 17 June 2014 - 10:45 AM

So in terms of modularity would I need to assign a class name to to any element that is going to call the modal function? That way I can delegate the event to it?
Was This Post Helpful? 0
  • +
  • -

#7 e_i_pi   User is offline

  • = -1
  • member icon

Reputation: 879
  • View blog
  • Posts: 1,893
  • Joined: 30-January 09

Re: Click event not working with dynamic content

Posted 17 June 2014 - 03:31 PM

I would use a class to do this, yes, and the same class for every dynamic element of the same type.
Was This Post Helpful? 0
  • +
  • -

#8 RandomlyKnighted   User is offline

  • D.I.C Lover
  • member icon

Reputation: 119
  • View blog
  • Posts: 1,384
  • Joined: 14-January 10

Re: Click event not working with dynamic content

Posted 17 June 2014 - 06:48 PM

Thanks! By doing that I was able to get the dynamic modal to open using the original click event (after I updated it to include the delegate parameter). I also updated the close event so that once I get the close button to show up in the dynamic modal it should work for it as well. Here's how I did it:


(function($)
{
	$.fn.modal = function(userOptions)
	{
		var defaultOptions = 
		{
			url			: 	null
		}

		options = $.extend({}, defaultOptions, userOptions);
		
		$(this).addClass('modal-show');
		var id = $(this).data('modal-id');
		buildModal($(this), id);
	};
	
	function buildModal(element, id)
	{
		//	Create the modal window container
		var modalWindow = document.createElement('div');
		$(modalWindow).attr('id', id).addClass('modal');
		
		//	Create the modal body where we will load the external html/image
		var modalBody = document.createElement('div');
		$(modalBody).addClass('modal-body');

		$(modalBody).append(closeBtn);
		
		//	If the user provides an external link/image then load that image into the modal body
		if (options.url)
		{
			$(modalBody).load(options.url);
		}

		else
		{
			$(modalBody).append(element.contents);
		}

		//	Create and add the close button
		var closeBtn = document.createElement('button');
		$(closeBtn).addClass('close');
		$(closeBtn).html('&times;');

		// Finally let's add the content to the modal itself
		$(modalWindow).append(modalBody);
		$('body').append(modalWindow);
	}
	
	function closeModal(id)
	{
		//	Get the DOM that contains the modal so we can remove the backdrop
		var content = $('.modal-backdrop').contents();
		
		//	Have the backdrop and the modal fade out
		$('.modal-backdrop').find('#' + id).fadeOut();
		
		// Remove the backdrop from around the modal
		$('.modal-backdrop').replaceWith(content);	
	}

	function showModal(id)
	{
		/*
		*	Add the backdrop around the modal (This is done primarily
		*	to make the developer's life easier so that they don't
		*	have to create the div for the backdrop.
		*/
		$('#' + id).wrapAll('<div class="modal-backdrop">');

		// Have the backdrop and the modal fade in
		$('.modal-backdrop').fadeIn().find('#' + id).fadeIn();
	}
	
	$('body').on('click', '.modal-show', function(event)
	{
		event.preventDefault();
		
		//	Get the ID of the modal that we want to show
		id = $(this).data('modal-id');

		showModal(id);
	});
	
	$('body').on("click", '.close', function(event)
	{
		event.preventDefault();
		
		//	Get the ID of the modal that we want to show
		id = $(this).data('modal-id');

		closeModal(id);
	});

})(jQuery);


This post has been edited by RandomlyKnighted: 17 June 2014 - 06:59 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1