I've developed a couple of alert boxes that display on all site pages.
The user is able to close each box separately:
$(document).ready(function() {
$("#close-alert-box-news").click(function() {
$("#alert-box-news").hide(800);
});
$("#close-alert-box-maintenance").click(function() {
$("#alert-box-maintenance").hide(800);
});
});
.alert-box {
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
jsFiddle
Now I need to make sure that the box the user closes (could be one, could be both), doesn't re-appear as he/she browses the site, or reloads a page.
I'm thinking I could set a PHP cookie to expire in 24 hours. But most of the related posts on this site recommend a JavaScript cookie. Unfortunately, my efforts to implement a JavaScript solution haven't worked (the boxes re-appear after being closed). I've tried various methods, as outlined here:
- Set cookie to hide div when button is clicked
- Set cookie when my div is hidden
- jQuery Cookie hide/show div
- Hide div 24hr cookie javascript?
What would be a simple method to hide each box, sitewide, for 24 hours?
I'm open to jQuery, plain JavaScript, PHP, cookies, sessions or something else.
Use localStorage()
.
Local storage is per origin (per domain and protocol)
- On click of DIV close, you can get the current time-stamp
- Add number of hours (24) to that time-stamp
- Store that value in
localStorage
as localStorage.setItem('desiredTime', time)
- Check current time-stamp with that stored time-stamp
localStorage.getItem('desiredTime')
, based on that show/hide
jQuery
$(document).ready(function(){
//Get current time
var currentTime = new Date().getTime();
//Add hours function
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
//Get time after 24 hours
var after24 = new Date().addHours(10).getTime();
//Hide div click
$('.hide24').click(function(){
//Hide div
$(this).hide();
//Set desired time till you want to hide that div
localStorage.setItem('desiredTime', after24);
});
//If desired time >= currentTime, based on that HIDE / SHOW
if(localStorage.getItem('desiredTime') >= currentTime)
{
$('.hide24').hide();
}
else
{
$('.hide24').show();
}
});
HTML
<div>DIV-1</div>
<div class='hide24'>DIV-2</div>
Things to note
- You can use
$.cookie
as well, but that's an older approach now.
<div>
with class hide24
will be hidden only.
- Make sure that you put this code in general JavaScript, which loads on every HTTP request of your website.
- For
localStorage
, you should have HTML5 browsers.
Web Storage HTML5
Hope this helps.
Following on @Loading.. answer:
the alert boxes always re-appear briefly on reload before
disappearing. Any ideas?
Why is this?
The functions inside $(document).ready()
will execute until the entire DOM is loaded. That's why the alerts are rendered, then as soon as the function runs, it hides them.
Solution:
You can initially hide your alerts with a class just to take advantage that the browser won't render the content until the CSSOM has been built.
The class we are using is just setting the property display: none;
.
.hidden {
display: none;
}
This will of course cause redraw in the browser. (see notes)
Your logic is already showing the alert with
if (localStorage.getItem('desiredTime') >= currentTime) {
$('#alert-box-news').hide();
} else {
$('#alert-box-news').show();
}
Because using .show()
will add an inline-style display: block;
it will have a higher specificity than the .hidden
class, showing the alert.
jsFiddle
Notes:
- Using
display: none;
will push the content below the alert up or
down. You can use other methods if you like, like visibility: hidden;
or transform
which is not in the scope of this answer.
EDIT:
An illustration will be presented below doing the following steps:
- Demo counter increased to 20 seconds for testing.
- We click to dismiss the alert and trigger the
localStorage
function, setting the desiredTime
key.
- After the key has been set, we refresh the browser and hit run several times to see if the key is working.
Finally, just to check that the key is indeed being set, we go to:
DevTools (F12) -> Application Tab -> Local Storage -> jsFiddle shell.
Run is hit one more time, after the countdown has finished, showing the alert again.
Illustration:
We might need further details to solve the issue with this approach if it is not working live.
As far as I understand your question, hiding the alerts for 24 hours (and then subsequently showing them all again after a day) will be a bad user experience.
I assume you're loading these alerts from some sort of database. If so, the proper answer would be to store a status there. Whether it be a status
column or a deleted_at
timestamp, the implementations are endless.
Either way, I would store alert state in the database and filter your data when pulling accordingly.
Thus in your view you would have (assuming php here):
<?php
<?php if(!empty($newlyFilteredAlerts)): ?>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<?php foreach(newlyFilteredAlerts as $alert): ?>
<p><?= $alert ?></p>
<?php endforeach;?
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="" >
</a>
</article>
<?php endif; ?>
Then you would accordingly want to add some sort of endpoint to alter that database status:
$(document).ready(function() {
$("#close-alert-box-news").click(function() {
$.post({
url: '/alerts',
type: 'DELETE',
success: function () {
$("#alert-box-news").hide(800);
},
});
});
});
NOTE: This answer is meant to point you in the right direction, not write your code