Reputation: 762
I am working on simple POS restaurant ordering system. Here users can add items into their cart and easily checkout. I am trying to implement that user can only click once on checkout button for a specific time and when time's over button enable again.
By now, I have disabled the button for specific time, but that is not good solution, because when page refresh, buttons are enabled again.
DEMO: Can be find here.
Html:
<body>
<div>
<button>checkout</button>
</div>
</body>
Jquery:
$.fn.disableFor = function(mins, secs) {
var i = [],
play = [];
this.click(function() {
var selector = $(this),
inDex = $(selector).index(),
prevText = $(selector).text();
i[inDex] = 0;
var inSeconds = mins * 60 + secs;
$(selector).prop("disabled", "disabled");
play[inDex] = setInterval(function() {
if(inSeconds > 60){
inSeconds = inSeconds - 1;
var minutes = Math.floor(inSeconds / 60);
var seconds = inSeconds % 60;
if(minutes >= 1){
if(seconds.toString().length > 1){
$(selector).text(minutes + ":" + seconds + " minutes left");
}else{
$(selector).text(minutes + ":" + "0" + seconds + " minutes left");
}
}else{
$(selector).text(seconds + " seconds left");
}
}else{
if(inSeconds > 1){
inSeconds = inSeconds - 1;
if(inSeconds.toString().length > 1){
$(selector).text(inSeconds + " seconds left");
}else{
$(selector).text("0" + inSeconds + " seconds left");
}
}else{
$(selector).prop("disabled", "");
clearInterval(play[inDex]);
$(selector).text(prevText);
}
}
}, 1000);
});
};
$(function() {
$("button").disableFor(2,0); // First parameter stands for minutes and the second for the seconds.
});
Upvotes: 1
Views: 907
Reputation: 861
Try this:
//start cookies functions
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function removeCookie(cname) {
document.cookie = cname+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
}
//end cookies functions
var cookieCheckout = getCookie('checkouttime');
var secondsTimeout = 0;
var delayTime = 2*60;
if (cookieCheckout && cookieCheckout != "") {// if we have cookie then set cookie seconds, when load page
secondsTimeout = delayTime - Math.round((Date.now() - parseInt(cookieCheckout)) / 1000);
if (secondsTimeout > delayTime) {
removeCookie('checkouttime');
//make checkout button enable
} else {
//make checkout button disable
}
}
setCookie('checkouttime', Date.now(), 30);// set timestamp, when you click on enable checkout
if (secondsTimeout > delayTime) { //if time more then need limit then refresh timer, inside interval
removeCookie('checkouttime');
//make checkout button enable
}
Upvotes: 1
Reputation: 1994
I think this code is quite self-explanatory. Let me know if something is not clear.
I used localStorage (just like AlwaysHelping in his answer) which unfortunately doesn't work in StackOverflow's sandbox. You can save this as an html file and open it locally to test it.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div>
<button>checkout</button>
</div>
</body>
<script>
const button = $('button');
const pauseTime = 8 * 1000; // 8 seconds
let cache = retrieveDisableTime();
let disabledTime;
let currentTime;
let interval;
button.on('click', function(){
disabledTime = + new Date();
cache = {time: disabledTime};
saveDisableTime(cache);
button.prop("disabled", "disabled");
setTimer();
});
if(shouldButtonBeOff()) {
button.prop("disabled", "disabled");
setTimer();
}
function shouldButtonBeOff() {
disabledTime = cache ? cache.time : false;
currentTime = + new Date();
return disabledTime && disabledTime + pauseTime > currentTime;
}
function setTimer() {
interval = setInterval(function() {
console.log('Not yet ready');
if(!shouldButtonBeOff()) {
console.log('READY');
button.prop("disabled", false);
clearInterval(interval);
}
}, 1000);
}
function saveDisableTime(obj) {
localStorage.setItem('disableButton', JSON.stringify(obj));
}
function retrieveDisableTime() {
return JSON.parse(localStorage.getItem('disableButton'));
}
</script>
Upvotes: 2
Reputation: 14570
You need to use browser localStorage to store the seconds.
Once you click on checkout button we will setItem
time as the the seconds
- In setIterval
we will keep updated the time remaining in the button and once the time reaches the limit of end we will remove using removeItem
the localStorage
from the browser
.
If the user refreshes the checkout page (This is where your question comes in) - We click on the checkout button the we will check if there is any time remaining in the localStorage
for our key we have set in before.
If there is no remaining time we will use start the clock at 1 minutes and 15 seconds
OR else we will start
at the time remaining using getItem
in the localStorage
.
I have tested this code and it works perfectly.
Demo: (You need to try this in your own browser - localStorage
is not supported in this snippet.)
$.fn.disableFor = function(mins, secs) {
var i = [],
play = [];
this.click(function() {
var selector = $(this),
inDex = $(selector).index(),
prevText = $(selector).text();
i[inDex] = 0;
//Store seconds
var inSeconds = mins * 60 + secs;
//Get the previous stored seconds - check local storage
var retrievedObject = localStorage.getItem('time');
if (retrievedObject) {
inSeconds = retrievedObject
}
//Disable button
$(selector).prop("disabled", "disabled");
play[inDex] = setInterval(function() {
if (inSeconds > 60) {
localStorage.setItem('time', inSeconds); //Set time again
inSeconds = inSeconds - 1;
var minutes = Math.floor(inSeconds / 60);
var seconds = inSeconds % 60;
if (minutes >= 1) {
if (seconds.toString().length > 1) {
$(selector).text(minutes + ":" + seconds + " minutes left");
} else {
$(selector).text(minutes + ":" + "0" + seconds + " minutes left");
}
} else {
$(selector).text(seconds + " seconds left");
}
} else {
localStorage.setItem('time', inSeconds); //Set time again
if (inSeconds > 1) {
inSeconds = inSeconds - 1;
if (inSeconds.toString().length > 1) {
$(selector).text(inSeconds + " seconds left");
} else {
$(selector).text("0" + inSeconds + " seconds left");
}
} else {
localStorage.removeItem('time');
$(selector).prop("disabled", "");
clearInterval(play[inDex]);
$(selector).text(prevText);
}
}
}, 1000);
});
};
$(function() {
$("button").disableFor(1, 15); // First parameter stands for minutes and the second for the seconds.
});
div {
margin: 0 auto;
padding: 10px;
vertical-align: middle;
background-image: -moz-linear-gradient(bottom, white 0%, #CCC 100%);
background-image: -o-linear-gradient(bottom, white 0%, #CCC 100%);
background-image: -webkit-linear-gradient(bottom, white 0%, #CCC 100%);
background-image: -ms-linear-gradient(bottom, white 0%, #CCC 100%);
background-image: linear-gradient(bottom, white 0%, #CCC 100%);
}
button {
color: #2b2b2b;
text-shadow: 0 1px 0 #999;
font-size: 18px;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
margin: 0 5px;
border-radius: 12px;
-moz-box-shadow: 4px 4px 4px #CCC;
-o-box-shadow: 4px 4px 4px #CCC;
-ms-box-shadow: 4px 4px 4px #CCC;
-webkit-box-shadow: 4px 4px 4px #CCC;
box-shadow: 4px 4px 4px #CCC;
}
button:hover {
color: #3c3c3c;
background-image: -moz-linear-gradient(top, #CCC 0%, white 20%, #666 100%);
background-image: -o-linear-gradient(top, #CCC 0%, white 20%, #666 100%);
background-image: -ms-linear-gradient(top, #CCC 0%, white 20%, #666 100%);
background-image: -webkit-linear-gradient(top, #CCC 0%, white 20%, #666 100%);
background-image: linear-gradient(top, #CCC 0%, white 20%, #666 100%);
}
button:disabled {
color: #999;
cursor: default;
background: #CCC;
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div>
<button>checkout</button>
</div>
</body>
Upvotes: 2