I’m hoping that some kind person could give me some guidance on what I can do to inprove my code which filters a dataset.
My website www.foulshamvillagehall.org is built in Wix Editor. It previously made use of the Wix Events app, but this proved overly complex for the users, so I have replaced it with a simpler CMS/Repeater combination.
The code:
import wixData from "wix-data";
// This function calculates the number of whole days from now until a specified date (targetDate)
function calculateDaysUntil(targetDate) {
const oneDay = 24 * 60 * 60 * 1000; // one day in milliseconds
const start = new Date(); // create current date constant (start)
const end = new Date(targetDate); // create target date constant (end)
const totalDays = Math.round(Math.abs((end - start) / oneDay)); // Calculate the difference in days (totalDays)
return totalDays; // return the result
}
// Load page
$w.onReady(function () {
$w('#eventsDataset').onReady(() => { // load dataset
// The following code filters the #eventsDataset to return only events which are on or after the current date
// It then counts the number of results in the filtered dataset and shows or hides the #noEventsText element accordingly
let dataset = $w("#eventsDataset"); // get eventsDataset (dataset)
const today = new Date(); // get the current date
const FutureEvents = wixData.filter().ge("date", today); // define FutureEvents criteria (dates greater or equal to today)
dataset.setFilter(FutureEvents) // apply the filter criteria to the dataset
.then(() => {
return dataset.getTotalCount(); // return the number of results in the filtered dataset
})
.then((count) => {
if (count === 0) { // if there are no results
$w("#noEventsText").show(); // show the "#noEventsText" element
} else {
$w("#noEventsText").hide(); // hide the "#noEventsText" element
}
})
// The following code loops through each repeater item and creates the text to populate the #eventTimes element (with start and end time)
// It also calculates how many days until the event and populates the #dtgText element with the result
$w("#eventsRepeater").forEachItem(($item, itemData, index) => {
let eventDate = new Date(itemData.date) // set eventDate variable as the date field of the currentItem
let startTime = eventDate.toLocaleTimeString('en-US', { timeStyle: 'short' }).toLowerCase(); // extract start time from eventDate and store in startTime variable
if (!itemData.endTime) { // if there is no endTime
var endTime = "" // set endTime variable to null
} else {
var endTime = " to " + new Date("01/01/2024 " + itemData.endTime).toLocaleTimeString('en-US', { timeStyle: 'short' }).toLowerCase(); // set endTime to end time of currentItem and cnovert am/pm to lowercase
}
$item("#eventTimes").text = startTime + endTime; // set the eventTime element to startTime + endTime
let daysToGo = calculateDaysUntil(eventDate); // get the number of days until event
if (daysToGo === 1) { // set the text accordingly
var txt = " day"
} else {
var txt = " days"
}
$item("#dtgText").text = "in " + daysToGo + txt; // set the #dtgText element to number of days plus txt
});
});
});
I have added some code to filter the dataset so that only events in the future are displayed in the repeater (ie past events do not show). The code also calculates the number of days until each event and this is also displayed in the repeater.
On the whole, this works well, but today I noticed (on my PC) that if, whilst on the events page, I refresh the browser, it will briefly display a past event. If I do the same on my mobile, it even shows me an “empty” event with default repeater values and this doesn’t go away.
It seems that there is some kind of timing or syncing issue, but not sure how best to resolve it. Any advice on how my code could be improved would be greatly received. I’m a relative novice when it comes to Velo, but eager to learn.
Thank you in advance.
Mike