I’m having trouble with
I have created individual dynamic pages to display workout plans based on a users selections (at the gym, 30 mins, training chest, back, and shoulders, for example). I then need the table on the dynamic page to randomly display one exercise from chest, one from back, and one from shoulders. This is currently in a collection in the CMS, with individual columns for body part/muscle, exercise, and sets/reps. There are about 10 exercises per body part/muscle.
Working in
Wix Editor
What I’ve tried so far
I have the table populating the content from the CMS, but the standard CMS Editor options for load and filtering aren’t enough to do what I need. I suspect I need some code to call one exercise per body part but I can’t figure out how to do that. I will then replicate this for different times of workouts (therefore showing more exercises per body part/muscle).
Thanks in advance for any help!!
Yes, you will need code to query the CMS and pick a random exercise.
The code would be custom to match your specific CMS fields.
1 Like
Thanks Dan. I’m struggling to find any code examples to use to replace with my specific fields. Are you able to explain what code I should use please? Thanks!
you would use something like this to query
async function fetchExercisesForMuscle(muscle, { location } = {}) {
let q = wixData.query(EXERCISES_COLLECTION)
.eq('muscle', muscle);
maybe something like this to shuffle
function shuffleInPlace(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
like I mentioned, it would need to be custom coded to suit your requirements. You wont find any cut/paste codes to suit.
Thanks so much, this has helped a lot already! I have managed to get this far but have two issues:
-
There’s 3 different body parts (muscles) but it’s only displaying one in the table, not 3.
-
How do I get it to populate on page load (and then refresh with a new list if the user hits the refresh button)? It’s currenly on viewport which isn’t ideal if they scroll down and back up.
Thanks as usual!
import wixData from 'wix-data';
// Function to load random exercises
async function loadRandomExercises() {
try {
// Query the 'exercises' collection
let results = await wixData.query("AtHome-Starter")
.limit(1000) // Fetch a large number of items to ensure randomness
.find();
// Group exercises by 'bodyPart'
let exercisesByBodyPart = {};
results.items.forEach(item => {
if (!exercisesByBodyPart[item.bodyPart]) {
exercisesByBodyPart[item.bodyPart] = [];
}
exercisesByBodyPart[item.bodyPart].push(item);
});
// Select one random exercise per 'bodyPart'
let randomExercises = [];
for (let bodyPart in exercisesByBodyPart) {
let exercises = exercisesByBodyPart[bodyPart];
let randomIndex = Math.floor(Math.random() * exercises.length);
randomExercises.push(exercises[randomIndex]);
}
// Set the table rows to the random exercises
$w("#table1").rows = randomExercises;
} catch (error) {
console.error("Error loading exercises:", error);
}
}
// Event handler for when the table enters the viewport
$w("#table1").onViewportEnter(() => {
loadRandomExercises();
});
// Event handler for the refresh button
export function refreshButton_click(event) {
loadRandomExercises();
}
Thanks Dan! Okay I have disconnected the connection to the CMS and defined the table as below but it now doesn’t appear to be populating anything in the table. I’ve checked the field IDs in the CMS and they’re all correct. Do I need to publish instead of run/test mode, or is there still an issue with my code?
import wixData from 'wix-data';
// Function to load random exercises
async function loadRandomExercises() {
try {
// Query the 'exercises' collection
let results = await wixData.query("AtHome-Starter")
.limit(1000) // Fetch a large number of items to ensure randomness
.find();
// Group exercises by 'bodyPart'
let exercisesByBodyPart = {};
results.items.forEach(item => {
if (!exercisesByBodyPart[item.bodyPart]) {
exercisesByBodyPart[item.bodyPart] = [];
}
exercisesByBodyPart[item.bodyPart].push(item);
});
// Select one random exercise per 'bodyPart'
let randomExercises = [];
for (let bodyPart in exercisesByBodyPart) {
let exercises = exercisesByBodyPart[bodyPart];
let randomIndex = Math.floor(Math.random() * exercises.length);
randomExercises.push(exercises[randomIndex]);
}
// Set the table rows to the random exercises
$w("#table1").rows = randomExercises;
} catch (error) {
console.error("Error loading exercises:", error);
}
}
// Event handler for the refresh button
export function refreshButton_click(event) {
loadRandomExercises();
}
$w.onReady(function () {
$w("#table1").columns = [
{
"id": "title_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "Exercise",
"label": "Exercise", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
},
{
"id": "description_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "bodyPart",
"label": "Muscle Group", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
}
{
"id": "imagealttext_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "Sets & Reps",
"label": "Sets & Reps", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
}
]
})
some issues with your code
loadRandomExercises() is never called on page load
- the data path must match the field keys, so
Exercise may actually be exercise and Sets & Reps would be something like setsReps. Check all these
- Missing a comma between 2nd and 3rd column definitions
Thanks so much, have made some progress! The headings are now loading, but still no results. I don’t know what you mean by loadRandomExercises() is never called on page load? Do I need to change the order of the code (is the first section where it’s trying to load the random exercises confusing things?) or something else?
Also, I’m unclear where I label the button name on the refresh section of the code?
In terms of the code now:
import wixData from 'wix-data';
// Function to load random exercises
async function loadRandomExercises() {
try {
// Query the 'exercises' collection
let results = await wixData.query("AtHome-Starter")
.limit(1000) // Fetch a large number of items to ensure randomness
.find();
// Group exercises by 'bodyPart'
let exercisesByBodyPart = {};
results.items.forEach(item => {
if (!exercisesByBodyPart[item.bodyPart]) {
exercisesByBodyPart[item.bodyPart] = [];
}
exercisesByBodyPart[item.bodyPart].push(item);
});
// Select one random exercise per 'bodyPart'
let randomExercises = [];
for (let bodyPart in exercisesByBodyPart) {
let exercises = exercisesByBodyPart[bodyPart];
let randomIndex = Math.floor(Math.random() * exercises.length);
randomExercises.push(exercises[randomIndex]);
}
// Set the table rows to the random exercises
$w("#table1").rows = randomExercises;
} catch (error) {
console.error("Error loading exercises:", error);
}
}
// Event handler for the refresh button
export function refreshButton_click(event) {
loadRandomExercises();
}
$w.onReady(function loadRandomExercises() {
$w("#table1").columns = [
{
"id": "title_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "title_fld",
"label": "Exercise", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
},
{
"id": "description_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "description_fld",
"label": "Muscle Group", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
},
{
"id": "imagealttext_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "imagealttext_fld",
"label": "Sets & Reps", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
}
]
})
And in terms of how this is showing on the live site:
Thanks again!
Hi @Dan_Suhr thanks again for all your help so far. I now have the exercises showing - so only 2 issues remain!
- I want to show one random exercise from each body part. It’s randomising, but sometimes showing two from the same body part.
- My refresh button to update the list in the table still isn’t working. Any ideas?
Code is now as below:
import wixData from 'wix-data';
export function refreshButton_click(event) {
loadRandomExercises();
}
$w.onReady(function loadRandomExercises() {
$w("#table1").columns = [{
"id": "title_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "title_fld",
"label": "Exercise", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
},
{
"id": "description_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "description_fld",
"label": "Muscle Group", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
},
{
"id": "imagealttext_fld", // ID of the column for code purposes
// The field ID in the collection whose data this column displays
"dataPath": "imagealttext_fld",
"label": "Sets & Reps", // The column header
"width": 100, // Column width
"type": "string", // Data type for the column
}
]
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]; // Swap elements
}
return array;
}
$w.onReady(function () {
const collectionName = "AtHome-Starter"; // Replace with your actual collection name
const tableId = "#table1"; // Replace with your actual table element ID
wixData.query(collectionName)
.find()
.then((results) => {
let items = results.items;
items = shuffleArray(items);
items = items.slice(0, 3);
// Optional: Limit to a specific number of random items
// items = items.slice(0, 5); // Example: show 5 random items
$w(tableId).rows = items; // For tables, use .rows instead of .data
})
.catch((error) => {
console.error("Error loading random items:", error);
});
});
}
)