Concatenate data from CMS in dynamic item page

In Wix Studio, I have a dynamic item page linked to a CMS. How could I concatenate data from multiple columns of this same CMS into a single text field?

For example, on the dynamic item page of the CMS “projects”, I would like to retrieve the data from the “type”, “technic”, “duration” and “year” columns to display them on a single line separated by commas.

Could you please help me ?

JavaScript has a join function that can do this: Array.prototype.join() - JavaScript | MDN

Thanks for your help !

The problem is more how to access the dynamic Item Page data, rather than how to concatenate it.

More concretely: I have a CMS called “projects” which has the “type”, “technic”, “duration” and “year” columns. I would like this data to be displayed on the dynamic item page in a single line separated by commas.

This code works, but unfortunately it lists all the CMS entries rather than just filtering the entry of the current item linked to the current dynamic item page.

import wixData from 'wix-data';

$w.onReady(function () {
    let maCollection = wixData.query("projects");
    maCollection.find().then((results) => {
        let concatenatedValue = "";
        results.items.forEach((item) => {
            concatenatedValue += item.type + ", " + item.technic+ ", "+ item.duration + ", " + item.year + "\n";
        });
        $w("#technicalSheet").text = concatenatedValue;
    });
});

How could I modify this code so that it only displays the data for the current item ?

1 Like

I finally used this code which works :

import wixData from 'wix-data';

$w.onReady(function () {
    // Get the ID of the current item from the page context
    let itemId = $w("#dynamicDataset").getCurrentItem()._id; // Make sure to replace "dynamicDataset" with the actual name of your dataset

    // Retrieve data for the current item
    wixData.get("projects", itemId)
        .then((result) => {
            // Concatenate values from CMS columns you want to display
            let concatenatedValue = `${result.type}, ${result.technic}`;

            // Add the value of "duration" only if it is not empty
            if (result.duration) {
                concatenatedValue += `, ${result.duration}min`;
            }

            concatenatedValue += `, ${result.year}`;

            console.log("concatenatedValue:", concatenatedValue);

            // Display the concatenated value in the "technicalSheet" text field
            $w("#technicalSheet").text = concatenatedValue;
        })
        .catch((error) => {
            console.error(error);
        });
});


2 Likes

Got it. Glad you figured it out. You should also be able to use just $w("#dynamicDataset").getCurrentItem(); to get all the current data without needing to do an additional wixData.get()

So something like:

$w.onReady(function () {
    // Get the ID of the current item from the page context
    let item = $w("#dynamicDataset").getCurrentItem(); // Make sure to replace "dynamicDataset" with the actual name of your dataset

    // Concatenate values from CMS columns you want to display
    let concatenatedValue = `${item.type}, ${item.technic}`;

    // Add the value of "duration" only if it is not empty
    if (item.duration) {
        concatenatedValue += `, ${item.duration}min`;
    }

    concatenatedValue += `, ${item.year}`;

    console.log("concatenatedValue:", concatenatedValue);

    // Display the concatenated value in the "technicalSheet" text field
    $w("#technicalSheet").text = concatenatedValue;
});
1 Like

Thank you very much for these clarifications !

1 Like

Ohh you probably also want to wrap it all in a dataset onReady as in this example:

$w.onReady( () => {
  $w("#myDataset").onReady( () => {
    let item = $w("#myDataset").getCurrentItem();
  } );
} );
2 Likes

Now I’m struggling to do the same thing in a repeater’s text field. The data is correctly loaded and concatenated, but only certain repeater items are correctly updated, the others keep the default text of the design.

:white_circle: The part of code that does not work properly :

$w('#repeaterAwards').forEachItem(($item, data) => {
    if (data._id === item._id) {
        $item('#award').text = concatenatedData;
        //console.log("\n",data,"\n",concatenatedData,"\n");
    }
});

:white_circle: Full page code :

import wixData from 'wix-data';

// Utility function to show, expand, and mute/unmute a video
function showAndExpand(elementToShow, elementToHide, videoToPlay) {
    elementToShow.expand();
    videoToPlay.mute();
    elementToHide.collapse();
}

$w.onReady(function () {
    // Necessary initializations
    $w('#boxAward').hide();
    $w('#dataset2').onReady(() => {
        // Handling the alternating display of videos
        $w('#repeaterCompetences').onItemReady(($repeaterItem, repeaterItemData) => {
            let even = repeaterItemData.order;
            let videoPlayer = even % 2 === 0 ? $repeaterItem('#videoPlayer2') : $repeaterItem('#videoPlayer1');

            // Start the video when the corresponding part is visible in the viewport
            $repeaterItem('#v1').onViewportEnter(() => {
                videoPlayer.play();
            });

            $repeaterItem('#v2').onViewportEnter(() => {
                videoPlayer.play();
            });

            // Display and configure videos alternately
            if (even % 2 === 0) {
                showAndExpand($repeaterItem('#v2'), $repeaterItem('#v1'), $repeaterItem('#videoPlayer2'));
            } else {
                showAndExpand($repeaterItem('#v1'), $repeaterItem('#v2'), $repeaterItem('#videoPlayer1'));
            }
        });

        // Loading data from the "Awards" collection
        wixData.query("Awards")
            .find()
            .then(res => {

                // After loading data, trigger the synchronized fade
                let areImagesHidden = true;
                const intervalBetweenImagesInMs = 500;
                const fadeDurationInMs = 500;

                $w('#repeaterAwards').onItemReady(($item, itemData, index) => {
                    $item('#boxAward').hide();

                    // Processing collection items
                    res.items.forEach(item => {
                        // Constructing the concatenated string with line breaks
                        let concatenatedData = `${item.award}\n${item.festival}`;
                        if (item.city) concatenatedData += `\n${item.city}`;
                        if (item.year) concatenatedData += ` ${item.year}`;

                        // Updating text in the repeater
                        $w('#repeaterAwards').forEachItem(($item, data) => {
                            if (data._id === item._id) {
                                $item('#award').text = concatenatedData;
                                //console.log("\n",data,"\n",concatenatedData,"\n");
                            }
                        });
                    });

                    // Start synchronized fade when the repeater is visible in the viewport
                    $w('#repeaterAwards').onViewportEnter(() => {
                        if (areImagesHidden) {
                            $w('#repeaterAwards').forEachItem(($item, itemData, index) => {
                                setTimeout(() => {
                                    $item('#boxAward').show('flip', { duration: fadeDurationInMs });
                                    $item('#boxAward').show('fade', { duration: fadeDurationInMs });
                                }, intervalBetweenImagesInMs * index);
                            });
                            areImagesHidden = false;
                        }
                    });
                });
            })
            .catch(err => {
                console.error(err);
            });
    });

    // Handling page scrolling
    $w('#piedPage').onViewportEnter(() => {
        $w('#scrollDownIndicator').hide('fade', { duration: 300 });
    });

    $w('#piedPage').onViewportLeave(() => {
        $w('#scrollDownIndicator').show('fade', { duration: 300 });
    });
});