I have a complex function attached to a click event that makes an AJAX call and then presents that information in a modal dialog. While the AJAX call is processing, the link is still active, so pressing it multiple times results in multiple AJAX calls and multiple dialogs being shown. I need to prevent that behavior, so clicking the link multiple times before the dialog shows will only result in one AJAX call and the dialog being shown once.
You can see my example below and at JSFiddle. For this example, the AJAX call is simulated with a timeout. If you click the "This should do something" link multiple times before the dialog shows, it will fire the event more than once and the dialog shows multiple times.
While my example uses jQuery mobile, I need this to work via native JavaScript because I have both mobile using jQuery mobile and desktop not using any jQuery. This is not as I'd like it, but it's also out of my control.
function showDialog() {
$.mobile.changePage("#dialog", {transition:"pop"});
}
function callDialog() {
setTimeout(showDialog, 1000);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/mobile/1.3.0-beta.1/jquery.mobile-1.3.0-beta.1.js"></script>
<link href="https://code.jquery.com/mobile/1.3.0-beta.1/jquery.mobile-1.3.0-beta.1.css" rel="stylesheet"/>
<div data-role="page" data-theme="a" id="home">
<div data-role="header" data-theme="a" align="center">
<h1>TESTING PAGE</h1>
<div data-role="navbar" data-iconpos="top">
<ul>
<li><a href="#home" data-icon="home">Home</a></li>
<li><a href="#away" data-icon="grid">Away</a></li>
</ul>
</div><!-- /navbar -->
</div>
<div data-role="content">
<p>TESTING PAGE ONE!!</p>
<ul data-role='listview' data-inset='true'>
<li><a href="#" onclick="callDialog();">This should do something.</a></li>
</ul>
</div>
<div data-role="footer" data-theme="a">
<h3>Copyright</h3>
</div>
</div>
<div data-role="page" data-theme="a" id="away">
<div data-role="header" data-theme="a" align="center">
<h1>TESTING PAGE</h1>
<div data-role="navbar" data-iconpos="top">
<ul>
<li><a href="#home" data-icon="home">Home</a></li>
<li><a href="#away" data-icon="grid">Away</a></li>
</ul>
</div><!-- /navbar -->
</div>
<div data-role="content">
<p>TESTING PAGE TWO!!</p>
</div>
<div data-role="footer" data-theme="a">
<h3>Copyright</h3>
</div>
</div>
<div data-role="dialog" id="dialog">
<div data-role="header" data-theme="d">
<h1>Dialog</h1>
</div>
<div data-role="content">
<h1>Close page?</h1>
<p>This is simply a page made to look like a </p>
<a
href="#" data-role="button" data-rel="back" data-theme="b">Sounds good</a> <a href="#" data-role="button" data-rel="back" data-theme="c">Cancel</a>
</div>
</div>
I've tried event.preventDefault
, removing the event listener, and a few other things, but I can't seem to re-attach the onclick event listener. So, once the dialog is closed, the user is unable to re-use that link if they so choose. I'd like to try to get this all wrapped into a single function due to the way that this dialog is rendered if at all possible.
You can use a flag to control the click behaviour
Ex
var inProgress = false;
function showDialog() {
inProgress = false;
$.mobile.changePage("#dialog", {transition:"pop"});
}
function callDialog() {
if(inProgress){
return;
}
inProgress = true;
setTimeout(showDialog, 1000);
}
Demo: Fiddle