JQuery Close Modal After Inactivity - javascript

I am creating a touch screen feedback kiosk that prompts users for their email address after they select a feedback option (good / bad).
Leaving their email address is optional, so the modal window should close after x seconds of inactivity.
How can I detect if a user is currently 'active' in the modal and close it if not (using JQuery)?
The countdown timer should be reset, and modal stay open if:
The user begins to type in the input.
The modal should be closed if;
The input has been inactive for x seconds (user leaves).
I have half of it complete, just need some help with the rest of it. Currently the timer only changes on each click of the input.
My current code is below;
Here's a link to a my fiddle.
HTML
<button type="button" class="btn btn-primary" id="feedbackFormBad">click</button>
<div aria-hidden="true" class="modal fade" id="memberNumberModal" role="dialog" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header modal-header-primary">
<h1>Hello</h1>
</div>
<div align="center" class="modal-body">
<p>Some text here.</p>
<p span id="countdown"></p>
<!-- show count down timer here -->
<form id="memberNumberForm" class="form-inline">
<div class="form-group mb-2">
<input type="text" name="Email" class="form-control" id="memberNumber" placeholder="enter email" required>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Send</button>
<button type="button" class="btn btn-secondary" id="closeModal" data-dismiss="modal">No Thanks</button>
</div>
</form>
</div>
</div>
</div>
</div>
JQuery
$(document).ready(function() {
$("#feedbackFormBad").on("touchstart, click", function(e) {
$('#memberNumberModal').modal('toggle');
var counter = 5;
var interval = setInterval(function() {
counter--;
$("#memberNumber").focus(function() {
$("#countdown").html('Window will close in ' + counter + ' seconds.');
});
if (counter == 0) {
$('#memberNumberModal').modal('hide');
clearInterval(interval);
}
}, 1000);
});
});
Any help is appreciated.

Try with the below javascript code
$(document).ready(function() {
$("#feedbackFormBad").on("touchstart, click", function(e) {
$('#memberNumberModal').modal('toggle');
var counter = 5;
var interval = setInterval(function() {
counter--;
$("#countdown").html('Window will close in ' + counter + ' seconds.');
if (counter == 0) {
$('#memberNumberModal').modal('hide');
clearInterval(interval);
}
}, 1000);
$('body').bind('mousedown keydown', function(event) {
counter = 5;
});
});
});
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<body>
<button type="button" class="btn btn-primary" id="feedbackFormBad">click</button>
<hr>
<p>The timer should be reset if:</p>
<ul>
<li>The user begins to type in the input.</li>
</ul>
<p>The modal should be closed if:</p>
<ul>
<li>The input has been inactive for x seconds (user leaves).</li>
</ul>
<div aria-hidden="true" class="modal fade" id="memberNumberModal" role="dialog" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header modal-header-primary">
<h1>Hello</h1>
</div>
<div align="center" class="modal-body">
<p>Some text here.</p>
<p span id="countdown"></p>
<!-- show count down timer here -->
<form id="memberNumberForm" class="form-inline">
<div class="form-group mb-2">
<input type="text" name="Email" class="form-control" id="memberNumber" placeholder="enter email" required>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Send</button>
<button type="button" class="btn btn-secondary" id="closeModal" data-dismiss="modal">No Thanks</button>
</div>
</form>
</div>
</div>
</div>
</div>
</body>

You could use a combination of setInterval and all of the events to achieve this. I've commented the code below.
Update
Originally, I'd posted an answer using the keyup function - missing the touchscreen part of the requirements. However, the below listens for any change to the text input. Let me know if this works.
The events were taken from this answer here
Best way to track onchange as-you-type in input type="text"?
// Keep track of if user is active
var active = true;
// keep track of how long since the user has typed
var timeElapsed = 0;
// check every second
setInterval(function(){
timeElapsed += 1;
// example
$("#timer").html(timeElapsed + " seconds inactive");
// a minute has passed since the user has typed
if(timeElapsed == 60){
// close modal
$('#memberNumberModal').modal('hide');
}
}, 1000);
// if the user types, reset the timer
$("#test").on('change keydown paste input propertychange click keyup blur', function(){
// user is active, has typed
timeElapsed = 0;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="test" type="text">
<span id="timer"></span>

Related

Disable and Enable click event on div from button type

I'm building Simon colors game with jQuery and I'm trying to disable the click event while the game is off or the player clicked on the wrong color. I'd read on the internet about the .prop('disalbe', true) and about .attr('disabled', 'disabled') but rn both of them didn't work for me. I'm using divs and not buttons elements
<div class="container" id="container">
<div class="row">
<div type="button" id="green" class="btn green">
</div>
<div type="button" id="red" class="btn red">
</div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow">
</div>
<div type="button" id="blue" class="btn blue">
</div>
</div>
</div>
allButtons.click(function() { // CLICK EVENT LISTENER
const userChosenColour = this.id;
userClickedPattern.push(userChosenColour);
const userButton = $(`#${this.id}`);
userButton.fadeTo(100, 0.1, function() { $(this).fadeTo(500, 1.0); });
makeSound(this.id)
if (checkAnswer(userClickedPattern.length)) { // CONDITIONS TO CHECK THE CURRENT CLICK
if (userClickedPattern.length === gamePattern.length) {
title.text('Success')
setTimeout(function() {nextSequence()}, 1000);
}
return true;
} else {
// allButtons.attr('disabled',true);
title.text('Wrong');
makeSound('wrong');
flashBackground();
allButtons.prop('disabled', true);
setTimeout(function() {resetGame()}, 500);
return false;
}
});
rn the result is nothing happen. thank you for your help here !
You can set the CSS property pointer-events to none to prevent clicks.
allButtons.css('pointer-events', 'none'); // Disable clicks
allButtons.css('pointer-events', ''); // Re-enable

How to close the selected div when we click on the button

In my angular application I have on textarea and within the popup and when we enter any data in textarea the to be displayed in some div.
.component.html
<div class="form-group popover-form" >
<label>Enter Custom Trigger Habit: When I</label>
<textarea class="form-control" [(ngModel)]="Trigger" name="Trigger"></textarea>
</div>
<!-- the entered data of textarea will display in below code-->
<div class="col-sm-5 " >
<div class="content-text" >
<p>{{Trigger}}</p>
</div>
</div>
<button type="button"><i class="icon icon-close" type="button" aria-hidden="true"></i></button>
and I have the close button and my requirement is to close the div when we click on the close button .
Can anyone help me on tha same.
You can create a boolean flag to check when to show or hide the div and then create a click event handler on your button to set that showDiv boolean to false to hide that div;
For example:
showDiv: boolean = true;
closeDiv() : void {
this.showDiv = false;
}
<div class="col-sm-5 " *ngIf="showDiv">
<div class="content-text" >
<p>{{Trigger}}</p>
</div>
</div>
<button (click)="closeDiv()" type="button">
<i class="icon icon-close" type="button" aria-hidden="true"></i>
</button>
You can use *ngIf
Template:
<div *ngIf="display">Test Data</div>
<input type="button" value="click" (click)="update"/>
Component:
display = true;
update(){
this.display = !this.display;
}
You can do this by using JavaScript like this.
on Click it will display none. This is just an example
function show() {
var x = document.getElementById("tabi")
x.style.display = "none"
}
<div class="form-group popover-form" >
<label>Enter Custom Trigger Habit: When I</label>
<textarea class="form-control" [(ngModel)]="Trigger" name="Trigger"></textarea>
</div>
<!-- the entered data of textarea will display in below code-->
<div class="col-sm-5 " id='tabi' >
<div class="content-text" >
<p>{{Trigger}}</p>
</div>
</div>
<button type="button" onclick="show()"><i class="icon icon-close" type="button" aria-hidden="true">Button</i></button>

Timer function doesn't start with eventlistener

I'm trying to make a game where once the user clicks 'begin', the timer will start and the user will be redirected to a new page.
so far, the user is being redirected to a new page, but the timer function is not counting down. I've got an error in my console log displaying
script.js:20 Uncaught TypeError: Cannot read property 'addEventListener' of null
at HTMLDocument. (script.js:20)
this is the js code
document.addEventListener('DOMContentLoaded', () => {
const timeLeftDisplay = document.querySelector("#timer");
const beginbtn = document.querySelector("#beginBtn");
let secondsLeft = 45
function countDown(){
window.location.href = "questions.html"
setInterval(function(){
if (secondsLeft <= 0) {
clearInterval(secondsLeft)
window.location.href = "https://twitter.com"
}
timeLeftDisplay.innerHTML = timeLeftDisplay
secondsLeft -=1
},1000)
}
beginbtn.addEventListener('click', countDown)
})
this is the HTML page that the user will be redirected to
<body>
<header class="container mt-5">
<div class = "row justify-content-end">
<h6>time:</h6>
<h6 id = "timer"></h6>
</div>
<div class="row justify-content-center">
<div class="col">
<h1 class="text-center">questions</h1>
</div>
</div>
</header>
<main>
<div class="container mt-5">
<div class="row justify-content-center">
<h6 id = "question"></h6>
</div>
<div class="row justify-content-center mt-2" id = questionContain>
<button type="button" class="btn btn-outline-info btn-lg" id = "choiceOne">
</button>
</div>
</div>
</main>
</body>
this is the home page with the begin button
<main>
<div class="container">
<div class="row justify-content-center">
<div>
<button
type="button"
class="btn btn-outline-info btn-lg"
id="beginBtn"
>
Begin
</button>
</div>
</div>
</div>
</main>
change timeLeftDisplay.innerHTML = timeLeftDisplay to timeLeftDisplay.innerHTML = secondsLeft; and move window.href inside if function. And add element with id="timer". Also add ; semicolons after each statements
If the browser is refreshing when it loads the second page your JS function is no longer executed. You should just call your countDown() function on the second page inside of the DOMContentLoaded listener.

how to get varying modal content

Hi I am trying to get the varying modal content but I am not sure where I am going wrong as I am new to JavaScript
My Code:
<a data-toggle="modal" data-target="#exampleModal" data-whatever="sampleText" >testData</a>
<div class="modal fade bs-example-modal-sm" tabindex="-1" id="exampleModal">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<h4 class="modal-title" id="exampleModalLabel">New message</h4>
<form>
<div class="form-group">
<label for="recipient-name" class="control-label">Recipient:</label>
<input type="text" class="form-control" id="recipient-name">
</div>
</form>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$('#exampleModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('whatever')
var modal = $(this)
modal.find('.modal-title').text('New message to ' + recipient)
modal.find('.modal-body input').val(recipient)
})
</script>
My aim is to display the "sampleText" in the input text box. But I dont get it. I am only getting empty box.
Also is there a way to display a list of strings in the input box.??
Sorry if my question is very basic.
S
There is no element with class of .modal-body in your markup, the selector should be .modal-content input.
modal.find('.modal-content input').val(recipient);
If by a list of strings you mean *-separated values, you can define an array and join the elements using Array.prototype.join method:
var list = ['an', 'array'];
var string = list.join('glue');
// ...
modal.find('.modal-content input').val(string);

Reset bootstrap modal

So, I am using bootstrap's modal.
I want to make a wizard style modal and came up with the following solution:
div snippets:
<div class="modal-instance hide fade" id="step1">
<div id="stepa">
...
</div>
</div>
<div id="stepb" style="display: none;">
...
</div>
Upon pressing a button in step-a step-b is loaded.
javascript snippet:
$("#stepa").replaceWith($('#stepb'));
document.getElementById('stepb').style.display = 'block';
This works ok.
But when I dismiss the modal. The div stepa has still been replaced by stepb. My solution was to build a replacement back to stepa when the modal is hidden:
$("#myModal").on("hidden", function() {
//replace the child
});
I tried:
$('#step1').children().remove();
$('#step1').append($('#stepa'));
and
$("#step1").children("div:first").replaceWith($('#stepa'));
But I am having a hardtime selecting step-a as a replacement div, probably due to it not being a separate div. My question is, is this the right approach for a wizard styled modal or should I take another approach?
It's much simpler just to hide the previous and next steps, instead of copying them.
<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>
<div id="myModal" class="modal hide fade" data-step="1">
<div class="step step1">
<h1>Step 1</h1>
<button class="btn next">Next</button>
</div>
<div class="step step2">
<h1>Step 2</h1>
<button class="btn previous">Previous</button>
<button class="btn next">Next</button>
</div>
<div class="step step3">
<h1>Step 3</h1>
<button class="btn previous">Previous</button>
<button class="btn done" data-dismiss="modal">Done</button>
</div>
</div>
<style type="text/css">
#myModal > .step { display: none; }​
</style>
<script type="text/javascript">
$(function() {
showStep(parseInt($('#myModal').data('step')) || 1);
$('#myModal .next').on('click', function () {
showStep(parseInt($('#myModal').data('step')) + 1);
});
$('#myModal .previous').on('click', function () {
showStep(parseInt($('#myModal').data('step')) - 1);
});
$('#myModal').on('hidden', function() {
showStep(1);
});
function showStep(step) {
$('#myModal').data('step', step);
$('#myModal > .step').hide();
$('#myModal > .step' + step).show();
}
});​
</script>
http://jsfiddle.net/7kg7z/5/

Categories

Resources