I want to display features on a dynamic item page, showing the same item features with an image or icon if possible. The features data is added in the Tags field

Question:
I want to display a Tags field from a collection Item in a Wix repeater, where each tag is shown separately within its own repeater container or button, accompanied by an image or icon.

Product:
Wix Editor

What are you trying to achieve:
I want to showcase the features of an ITEM on a dynamic page, where these features are dependent on the specific tags associated with that item. Could you guide me on how to achieve this? For example, in my collection, there is a Tags field that includes features like Power Back-up, Intercom Facility, Lift(s), Maintenance Staff, Piped-gas, Swimming Pool, Park, Security Personnel, Internet/wi-fi connectivity, Shopping Center, etc. I want to display these tags like below the attached image.

What have you already tried:
I’ve tried numerous approaches, but I’m feeling quite hopeless about how to achieve this functionality.

Additional information:
My Page Link Section (Features) : https://www.estatencr.com/residential/4-bhk-apartment-flat-for-sale-in-supertech-supernova-supertech-sector-94-noida-5200-sq-ft-031f1252-74a2-459c-a4fa-d3614c898e93

For the sake of the example, I’m using an array of data for the tags - you’ll need to adjust it so the initial array (ammenities) is using the tags from the database.



const iconMap = {
    "Power Back-up": "🔋",
    "Intercom Facility": "📞",
    "Lift(s)": "🛗",
    "Maintenance Staff": "👷",
    "Piped-gas": "🛢️",
    "Swimming Pool": "🏊",
    "Park": "🏞️",
    "Security Personnel": "👮",
    "Internet/wi-fi connectivity": "📶",
    "Shopping Center": "🛍️"
};

$w.onReady(function () {

    const amenities = [
        "Power Back-up",
        "Intercom Facility",
        "Lift(s)",
        "Maintenance Staff",
        "Piped-gas",
        "Swimming Pool",
        "Park",
        "Security Personnel",
        "Internet/wi-fi connectivity",
        "Shopping Center"
    ];

    const mappedAmenities = amenities.map((amenity, index) => {
        const _id = String(index);
        const icon = iconMap[amenity] || "❓"; // Fallback icon in case of a missing icon in the map
        return {
            _id,
            amenity,
            icon
        };
    });

    console.log(mappedAmenities);

	$w("#repeater").data = mappedAmenities

	$w("#repeater").onItemReady(($item, itemData, index) => {
		$item("#text").text = itemData.amenity
		$item("#icon").text = itemData.icon
	})

});

Summary of what’s happening:

  • Create a iconmap that will correspond a value to an icon (in this case an emoji). You could swap it out for an image URL etc
  • amenities represents the tags from the database
  • mappedAmenities converts a an array of strings into an object with an unique_id which is needed for repeaters to work correctly
  • It also finds the icon from the iconMap based on matching the tag with the value in the map. If nothing is found it uses a default icon
  • Set the repeater data
  • Load the repeater with the data it now has

Hoep this helps you get things started :slight_smile:

Thank you for your response! I tried using the code you provided, but unfortunately, it’s still not working as expected. I’m not sure where the issue might be, so I’ve attached some screenshots to help illustrate the problem. Could you please take a look and let me know if you spot anything that could be causing the error? Your guidance is much appreciated!

I’m guessing it’s showing the same features on all listings?

This is because it’s using the static:

const features = [
        "Power Back-up",
        "Intercom Facility",
        "Lift(s)",
        "Maintenance Staff",
        "Piped-gas",
        "Swimming Pool",
        "Park",
        "Security Personnel",
        "Internet/wi-fi connectivity",
        "Shopping Center"
    ];

And not actually using the data from your database.

Since this is on a dynamic page, you’ll want to replace the above array with something that looks like:

$w("#dynamicDataset").onReady(() => {
		let itemObj = $w("#dynamicDataset").getCurrentItem()
		let amenities = itemObj.tags

Which is getting the tags from your database. (.tags will need updating to your field key)

And then you’ll need to close the .onReady before the end with })

Full code will look something like:

const iconMap = {
    "Power Back-up": "🔋",
    "Intercom Facility": "📞",
    "Lift(s)": "🛗",
    "Maintenance Staff": "👷",
    "Piped-gas": "🛢️",
    "Swimming Pool": "🏊",
    "Park": "🏞️",
    "Security Personnel": "👮",
    "Internet/wi-fi connectivity": "📶",
    "Shopping Center": "🛍️"
};

$w.onReady(function () {
    $w("#dynamicDataset").onReady(() => {
		let itemObj = $w("#dynamicDataset").getCurrentItem()
		let amenities = itemObj.tags

        const mappedAmenities = amenities.map((amenity, index) => {
            const _id = String(index);
            const icon = iconMap[amenity] || "❓"; // Fallback icon in case of a missing icon in the map
            return {
                _id,
                amenity,
                icon
            };
        });

        console.log(mappedAmenities);

        $w("#repeater").data = mappedAmenities

        $w("#repeater").onItemReady(($item, itemData, index) => {
            $item("#text").text = itemData.amenity
            $item("#icon").text = itemData.icon
        })

    })

});
1 Like

I tried implementing the code, but it’s not working as expected. Let me provide some details about my setup:

  • Page Type: Dynamic
  • Page Name: Residential (Item)
  • Page Connected Collection: Residential (Import647)
  • Dataset ID: #Residential

Field Details:

  • Field Type: Text
  • Field ID: features
  • Field Data: (Power Back-up, Intercom Facility, Lift(s), Maintenance Staff, Piped-gas, Swimming Pool, Park, Security Personnel, Internet/wi-fi connectivity, Shopping Center)

Element Details:

  • Repeater ID: #featuresRepeater
  • Text ID: #featuresText
  • Icon ID: #featuresIcon (Text Element)

Objective: I want to display the features of each item on the Dynamic (Item) Page with corresponding images or icons. Since the number of features varies for each item (sometimes a few, sometimes 50+), I chose to use an array or tags field to store the data. However, I’m having trouble figuring out how to display and manage these features effectively on my Item Page.

Can you provide guidance on how to achieve this?

I’ve tested in a site with the same setup and seems to be working.

I do see that in your IDE, there are errors in the top (the lines out of view), which are likely stopping the code from running on the page.

Also when visiting the live site, the console shows “Cannot find module ‘backend/data.jsw’ in ‘public/pages/rhhjq.js’” which makes me think you’re importing something from a public file that is calling from the backend, but the backend file doesn’t exist.

If you resolve those, it should work

I’ve been trying to rectify an issue, but I can’t pinpoint where the problem is. I have some custom code for combining field data into a string. Below is the code for the Residential (Item) page:

Page Code:

import { updateCombinedField, updateItemInCollection } from 'backend/data.jsw';

$w.onReady(function () {
    const dataset = $w('#Import647'); // Replace with your dataset ID

    dataset.onBeforeSave(async (event) => {
        // Combine fields and prepare the updated item
        const updatedItem = await updateCombinedField(event.item);

        // Update the item in the collection
        try {
            await updateItemInCollection(event.item._id, updatedItem);
        } catch (error) {
            console.error('Error updating item:', error);
        }

        // Set the updated item for the event
        event.item = updatedItem;
    });
});

And here is the code for backend/data.js:

import wixData from 'wix-data';

// Hook function for before inserting a new item
export function Import647_beforeInsert(item, context) {
    return updateCombinedField(item);
}

// Hook function for before updating an existing item
export function Import647_beforeUpdate(item, context) {
    return updateCombinedField(item);
}

function updateCombinedField(item) {
    // Combine fields according to your logic
    let combinedString = '';

    combinedString += (item.noOfBedrooms ? item.noOfBedrooms + '-' : '');
    combinedString += (item.whatKindOfPropertyUrl ? item.whatKindOfPropertyUrl + '-' : '');
    combinedString += (item.availableForUrl ? item.availableForUrl + '-in-' : '');
    combinedString += (item.projectName ? item.projectName + '-' : '');
    combinedString += (item.builderName ? item.builderName + '-' : '');
    combinedString += (item.localities ? item.localities + '-' : '');
    combinedString += (item.city ? item.city + '-' : '');
    combinedString += (item.superBuiltUpAreaSqFt ? item.superBuiltUpAreaSqFt + '-' : '');
    combinedString += (item.areaMeasurementType ? item.areaMeasurementType + '-' : '');
    combinedString += (item._id ? item._id : '');

    // Return the item with the updated combinedField
    return {
        ...item,
        combinedField: combinedString // Replace 'combinedField' with the name of your field
    };
}

I’ve checked, and this code works fine for combining item fields into a string, which is important for generating my item page URL slugs, such as:

[4-bhk-apartment-flat-for-sale-in-supertech-supernova-supertech-sector-94-noida-5200-sq-ft-031f1252-74a2-459c-a4fa-d3614c898e93]

However, I still don’t understand the following error message:

Cannot find module ‘backend/data.jsw’ in ‘public/pages/rhhjq.js’

I’ve searched, but I can’t find these files. Could you suggest what I should do next?

—Updates—

Finally, I did it! Successfully implemented the code you provided. The ‘Features’ section is now live on my Dynamic Item Page. I removed the previously mentioned code for the ‘CombinedField,’ which is also an important part of my website. Could you please suggest any alternative ways to achieve the ‘CombinedField’ functionality? If it’s possible, I’d love to know. Thanks again—your help has been incredibly valuable!