This topic is locked

Simple disappearing popup with countdown

4/2/2025 5:08:57 PM
PHPRunner Tips and Tricks
Sergey Kornilov admin

This article applies to all versions of PHPRunner and ASPRunner.NET. Using this simple code snippet we will display a popup with some information that will disappear after a specified period of time.

April 12, 2025 update : the code was updated to make sure that every user only sees the message once. To test how it works add a few records to messages table and proceed to the page where popup will be displayed.

img alt

  1. Messages are coming from database table named messages. We track which user seen which nessage in messages_tracking table. Our login table in this example is carsusers though it can be any other table.

img alt

In messages_tracking table userid column references id from the login table, messageid column references id from messages table.

  1. The following code needs be added to Javascript OnLoad event of the page where this popup needs to appear.

$.post("",
{
a:"getmessages"
})
.done(function(result){
if(result!=""){
// we have a message, display it
window.popup = Runner.displayPopup( {
html: "<div style='padding-bottom: 20px; font-weight: bold;'>" + result + "</div><div>This popup will disappear in <span style='text-align:center;width:100%' id='v_timer'></span> seconds </div",
header: "Important message", // popup header
width: 400,
height: 250,
afterCreate: function(popup) {
// delay time in seconds
var t = 10;
$("#v_timer").html(t+" seconds left");
window.intervalId = setInterval(function()
{
t--;
$("#v_timer").html(t);
if(t == 0){
clearTimeout(window.intervalId);
window.popup.close();
}
}, 1000);
},
beforeClose: function(popup) {
clearTimeout(window.intervalId);
}
});
}
});
return false;
  1. The following code goes to AfterAppInit event. Its job is to retrieve the next message for the current user if any and also to mark it as read.

if(postvalue("a") == "getmessages"){

// get current user id
$userData = Security::currentUserData();
$userid = $userData["id"];

// get first unread message for the current user
$sql = DB::PrepareSQL("select id, message from messages where id not in
( select messageid from messages_tracking where userid = :1 )", $userid);
$rs = DB::Query($sql);

if ( $data = $rs->fetchAssoc() )
{
// send message to the output
echo $data["message"];

// update messages_tracking table
$insert = array();
$insert["userid"] = $userid;
$insert["messageid"] = $data["id"];
DB::Insert("messages_tracking", $insert );

}

exit();
}
M
MikeUk 4/3/2025

That's neat. I use a similar method, but use Swal2 Toast method.

I use it as a js function so I can use it anywhere.
it is called using.
// set variables

var title = 'Message title';
var 'message' = 'some message';
var icon = 'e'; // 'e' = Error, 'i' = info, 's' = success,
var timer = 10; //seconds
var position = 1; // center screen

// usage

showToast(title,message,icon,timer, position);

// function
function showToast(title, message, imgIcon, duration, fc) {
// postions:'top', 'top-start', 'top-end', 'center', 'center-start', 'center-end', 'bottom', 'bottom-start', or 'bottom-end'
var myBordercol = '';
var myPosition = '';
if (fc == 0) {myPosition = 'bottom-end';} // appears at bottom right of screen
if (fc == 1) {myPosition = "center";}
if (fc == 2) {myPosition = 'top-start';}
if (fc == 3) {myPosition = 'top-end';}
if (fc == 4) {myPosition = 'center-end';}
var myIcon = "info"; // set a default
imgIcon = typeof imgIcon === 'string' && imgIcon.length > 0 ? imgIcon : 'info';
if (imgIcon.startsWith('e')) {myBordercol = "red";myIcon = "error";}
else if (imgIcon.startsWith('s')) {myBordercol = "green";myIcon = "success";}
else if (imgIcon.startsWith('i')) {myBordercol = "blue";myIcon = "info";}
else if (imgIcon.startsWith('w')) {myBordercol = "orange";myIcon = "warning";
}
if (duration !== 0) {var myDuration = duration || 3;}
else {var myDuration = 5;
}
myDuration = myDuration * 1000;
if (myDuration > 0 && myDuration < 1000) {myDuration = 3000;}
Swal.fire({
toast: true,
width: 450,
showClass: { popup: '' },
position: myPosition,
icon: myIcon || 'info',
timer: myDuration > 0 ? myDuration : null,
title: '<div style="font-size: 16px; font-weight: bold;">' + (title || 'Information') + '</div>', // Concatenated title
html: '<div><font size="3">' + message + '</font></div>',
showConfirmButton: false,
timerProgressBar: myDuration > 0,
showCloseButton: true,
customClass: {popup: 'custom-toast'},
didOpen: function(toast) {
if (myBordercol) {
toast.style.border = '2px solid ' + myBordercol;
}
}
});
}

Example.

img alt

When it runs an animated progressbar at the bottom of the popup shows.
Also, it's not modal so a user can continue what they were doing without too much interruption.

R
Rudy Lambrechts 4/4/2025

Is there a possibility to show this message only once by using cookies?
Thanks,

M
MikeUk 4/9/2025

Yes, you can use AJAX to query either a $_SESSION variable, or return a value from a field in a datatable. Or use a JS global variable on load

Dalkeith 4/11/2025

I wrote up my notes on something similar here for my own usage but others might find it useful

https://cloudydatablog.net/phprunner-and-ms-sql-azure-running-a-stored-procedure-behind-a-button-with-sweet-alert-user-feedback/