Persisting Scheduler Snooze Values

1 Answer 13 Views
Scheduler
Mark
Top achievements
Rank 1
Iron
Mark asked on 10 Feb 2025, 05:37 PM

My scenario is that i have a RadScheduler as part of my master page so it loads on all pages.  This is done so that appointment reminders can popup on any page regardless of what page the user is on.  This is working great with the exception of snoozing.  Snoozing seems to work as long as the user doesn't change to a different page, or do anything that performs a page postback.  When that happens, the page reloads and the snooze info is lost. I see there is a Reminder Snooze event, and in there can see where a Snooze Minutes value is provided.  My question is how do i persist this value so that i can get it back into the scheduler after the scheduler data is reloaded.  I can't assume that the user is just going to stay on the same page.  The snooze value doesn't appear to be part of the actual Reminder text string. 

Furthermore this snooze period would have to be converted to an actual time.   If the user presses snooze for 5 minutes and i update the database somehow with this information, and then the user changes pages after three minutes, when the appointment is read back in the popup should only snooze for 2 more minutes, not 5.

Thanks for your help!

-Mark

1 Answer, 1 is accepted

Sort by
0
Vasko
Telerik team
answered on 13 Feb 2025, 01:48 PM

Hi Mark,

To persist the snooze information across page reloads and ensure that the snooze period is accurately tracked, you can follow these steps:

Capture and Store Snooze Information

  • Capture Snooze Event: Use the ReminderSnooze event to capture the snooze minutes and the appointment ID. Store this information in a database with a timestamp to track when the snooze was set.

    protected void RadScheduler1_ReminderSnooze(object sender, ReminderSnoozeEventArgs e)
    {
        string appointmentId = e.Reminder.Appointment.ID.ToString();
        int snoozeMinutes = e.SnoozeMinutes;
        DateTime snoozeUntil = DateTime.Now.AddMinutes(snoozeMinutes);
    
        // Store snoozeUntil and appointmentId in the database
        SaveSnoozeInfo(appointmentId, snoozeUntil);
    }
    
  • Save Snooze Information: Implement a method to save the snooze details to the database.

    private void SaveSnoozeInfo(string appointmentId, DateTime snoozeUntil)
    {
        // Example: Save to database
        // UPDATE Appointments SET SnoozeUntil = @snoozeUntil WHERE AppointmentID = @appointmentId
    }
    

 Retrieve the Snooze Data When Loading the Scheduler

  • In the AppointmentDataBound event, fetch the snooze info for each specific appointment and add a custom attribute to it: 
protected void RadScheduler1_AppointmentDataBound(object sender, SchedulerEventArgs e)
{
    DateTime now = DateTime.Now.AddMinutes(3);
    DateTime? snoozeUntil = GetSnoozeInfo(e.Appointment.ID); // Fetch from DB

    if (snoozeUntil.HasValue && snoozeUntil.Value > DateTime.Now)
    {
        e.Appointment.Attributes["ReminderSnoozeUntil"] = now.ToString();
    }
}

Prevent the PopUp from showing

You can use the OnClientReminderTriggering event to get the appointment, extract the custom attribute's value and cancel the popup: 

function onClientReminderTriggering(sender, args) {
    let now = new Date();

    let appointment = args.get_appointment();
    let snoozeUntil = appointment.get_attributes().getAttribute("ReminderSnoozeUntil");

    if (snoozeUntil) {
        let snoozeTime = new Date(snoozeUntil);

        if (now < snoozeTime) {
            args.set_cancel(true); // Suppress reminder
        }
    }
}

    By implementing these steps, you can persist the snooze information across page loads and ensure that the snooze durations are accurately tracked, even when users navigate between pages. 

    Please refer to the following article for additional information - how to save snooze and dismiss when using DataSource.

    Try using this approach and see if it will help in your case.

    Regards,
    Vasko
    Progress Telerik

    Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources
    Mark
    Top achievements
    Rank 1
    Iron
    commented on 13 Feb 2025, 03:44 PM

    Ok, i believe this makes sense.  I will give this a go and report back!

    -Mark

    Mark
    Top achievements
    Rank 1
    Iron
    commented on 13 Feb 2025, 04:54 PM

    Vasko,

    This answer almost works, but contains one flaw.  The client-script event handler does a good job a preventing the premature reminder dialog from appearing, but from the scheduler's perspective the reminder was triggered, and there is no feedback mechanism back to the scheduler to tell it when it should re-prompt the reminder.  The re-prompt ONLY occurs if the user changes pages. 

    If the user presses the Snooze for 5 minutes button, and then changes pages right away (or within the 5 minute period) the client-side event handler will suppress the reminder popup, but if that user remains on that same page for more than the 5 minutes the reminder doesn't get re-triggered.  Ideally after you call args.set_cancel(true);  you'd need to also make some call back to the scheduler to tell it when to try again.  Is that possible?

    -Mark

    Mark
    Top achievements
    Rank 1
    Iron
    commented on 13 Feb 2025, 06:04 PM | edited

    I tried to write back to the reminder to have it re-prompt if the user stays on the same page, and the code seems to execute with no errors, but it doesn't actually re-trigger the reminder.   I'm hoping there is something simple that I'm missing.   There is no set_reminders() on the appointment object that i was able to see in the documentation.

    function onClientReminderTriggering(sender, args) {
        let now = new Date();
    
        let appointment = args.get_appointment();
        let snoozeUntil = appointment.get_attributes().getAttribute("ReminderSnoozeUntil");
    
        if (snoozeUntil) {
            let snoozeTime = new Date(snoozeUntil);
    
            if (now < snoozeTime) {
                //alert("Suppressed reminder popup");
                args.set_cancel(true); // Suppress reminder
    
                let reminders = appointment.get_reminders();
                if (reminders) {
                    //alert("Found " + reminders.get_count() + " reminders.");
    
                    for (i = 0; i < reminders.get_count(); i++) {
    
                        //There is probably just one...
                        let reminder = reminders.getReminder(i);
                        if (reminder) {
                            var minutesToSnooze = diffMinutes(now, snoozeTime);
                            
                            reminder.set_trigger(minutesToSnooze);
    
                            alert("Snoozing for " + minutesToSnooze + " minutes.");
                        }
                    }
                }
            }
        }
    }

     

    -Mark

    Vasko
    Telerik team
    commented on 18 Feb 2025, 07:24 AM

    Hi Mark,

    To address the issue of re-triggering reminders without changing pages, we need to use a combination of client-side logic and possibly server-side interaction to ensure the reminders are effectively managed. Here's a refined approach:

    Using the OnClientReminderTriggering event to check the snooze time, suppress the reminder if necessary, and set a timeout to re-trigger it.

    function onClientReminderTriggering(sender, args) {
        let now = new Date();
        let appointment = args.get_appointment();
        let snoozeUntil = appointment.get_attributes().getAttribute("ReminderSnoozeUntil");
        
        if (snoozeUntil) {
            let snoozeTime = new Date(snoozeUntil);
            
            if (now < snoozeTime) {
                args.set_cancel(true); // Suppress reminder
                
                let minutesToSnooze = Math.ceil((snoozeTime - now) / 60000);
                
                // Set a timeout to re-trigger the reminder
                setTimeout(function() {
                    // Logic to re-trigger the reminder
                    alert("Re-triggering reminder after snooze.");
                    // You may need to refresh or update the scheduler
                    // Example: sender.updateAppointment(appointment);
                }, minutesToSnooze * 60000);
            }
        }
    }
    

    Explanation

    • Suppress Reminder: The reminder is suppressed if the current time is less than the snooze time.
    • Re-Trigger Reminder: A setTimeout is used to calculate the remaining snooze time and re-trigger the reminder after the snooze period. This logic does not directly re-trigger the reminder as there is no direct method like set_reminders(), but you can refresh the scheduler or update the appointment to simulate a re-trigger.

    Considerations

    • Updating the Scheduler: You may need to refresh or update the scheduler to reflect the re-triggering of the reminder. This can be done by calling a function to update the appointment or refresh the scheduler view.

    Try this approach and let me know if it works for your case. Please refer to the following articles for additional information:

    Regards,
    Vasko
    Progress Telerik

    Mark
    Top achievements
    Rank 1
    Iron
    commented on 19 Feb 2025, 08:11 PM

    I might have something that is working.  I used the original onClientReminderTriggering code, that really just checks to see if the reminder needs to be suppressed,  and i put a Timer control on the Master Page whose sever side tick event handler just refreshes the scheduler data (which is already in an update panel of it's own).  It seems like this is working, but i'm still testing.    In the instance where a reminder is suppressed because the user previously pressed snooze and they remain on the same page, the scheduler will get rebound after 60 seconds in which case there will be another opportunity to see if the reminder should be shown again.

    -Mark

    Tags
    Scheduler
    Asked by
    Mark
    Top achievements
    Rank 1
    Iron
    Answers by
    Vasko
    Telerik team
    Share this question
    or