Add link to dynamic page on repeater

I am trying to switch over a repeater to populate via JS, I’ve got everything working but I cannot seem to figure out how to add the link to go to the dynamic page for the relevant item in the repeater.
I have tried various different ways including using an onClick event using the title ID from the database but rather than the spaces in between the words showing as ‘-’ they are populating with a ‘+’ generating an invalid url.

Also there is already an on.Ready function on the page and it wont allow me to use this code without another .onReady function.

Below is the code I am using for this repeater (I haven’t included the full page code), everything populates on the repeater as it should, I just need some help with the URL please, thanks.

import wixData from 'wix-data';

$w.onReady(async function () {
	
$w('#repeater6').onItemReady( ($item, itemData) => {

$item('#imageX132').src = itemData.mainImage;
$item('#text248').text = itemData.h1Title;
$item('#text247').text = itemData.price;

        })
    
	const {items: repeaterData} = await wixData.query('MensFootwear').find();
	console.log(repeaterData);

    $w('#repeater6').data = repeaterData.slice(0,6);

})

Can you share a screenshot of the Page Settings panel of your dynamic page?

This can be found under Site Pages > Dynamic Page > 3 dots > Page Settings (in Editor X)

Hi

Please see attached screenshot, thank you…

Also screenshot from database…

Great! I’m assuming you have some kind of button that you want to link? Or maybe you want to link the image? In any case, just replace the linkedElementId with the id of the image and the button, and you are good to go!

import wixData from 'wix-data';
import wixLocationFrontend from 'wix-location-frontend';

$w.onReady(async function () {
	
$w('#repeater6').onItemReady( ($item, itemData) => {

            $item('#imageX132').src = itemData.mainImage;
            $item('#text248').text = itemData.h1Title;
            $item('#text247').text = itemData.price;
            $item("#linkedElementId").link = "/footwear/" + itemData.title;


        })
    
	const {items: repeaterData} = await wixData.query('MensFootwear').find();
	console.log(repeaterData);

    $w('#repeater6').data = repeaterData.slice(0,6);

})

I have actually tried this, but the url is showing ‘+’ between the words generating an invalid url, rather than ‘-’ .

If your Title has spaces then I would suggest you don’t use that as a url slug as that is prone to errors like the one you just mentioned. The best alternative would be to use Wix’s own _id field as the slug, since it is fully unique for each item, and won’t cause any errors too.

I’ve tried this too and again this doesn’t work.

I will contact Wix directly and see if there is something wrong they’re end.

Thank you for your help.

Wix have been unable to help due to the complexities of Javascript.

With the URL generating with a + in between the words, which has to be an error of some sort and the page URL slug is set to the same field so this should also work the same.

Is there a way maybe to add a command to replace the ‘+’ with a ‘-’?

Could you provide an example maybe? Like the name of one of your fields, the actual url being generated, and what you actually want instead? Like the screenshots you provided above?

So basically the field in the second screenshot above, this is connected to the field name ‘Product ID’ with the field key ‘title’ which generates the URL as normal for the dynamic page itself (/footwear/this-is-an-example).

By using the same field key in our code…

$item("#imageX132").link = "/footwear/" + itemData.title;

this should not be an issue, however the URL is generating as (footwear/this+is+an+example=), this is an invalid URL which redirects to the 404 page. I have also as suggested tried using one of Wix’s own ID fields (see below)

snip

But the field key does not work in this code, I have also contacted Wix support and they say they cannot help with Javascript.

The suggestion you have made above is correct, so I cannot understand why it is not working. So I can’t really provide anything else and really there is no other alternative but to keep the fields connected via the dataset without JS, unless this maybe is a temporary issue or there is something I am missing in the code.

Not sure if the below will help but this is my full-page code (minus this repeater issue)…

let currentItem

$w.onReady(function () {

    $w("#MensFootwearItem").onReady(async () => {
        currentItem = await $w("#MensFootwearItem").getCurrentItem();
        if (currentItem) {
            logicFunctions()
        }
    })
});

function logicFunctions() {
    Supplier1()
    Supplier2()
    Supplier3()
    Supplier4()
    Supplier5()
    Supplier6()
    Supplier7()
    Supplier8()
}

function Supplier1() {
    if (currentItem.supplier1) {
        $w('#imageX144').src = currentItem.mainImage;
        $w('#text29').text = currentItem.h1Title;
        $w('#text206').text = currentItem.styleCode;
        $w('#text203').text = currentItem.price;
        $w("#box86, #imageX8, #buyNow1").show();
        $w('#imageX8').src = currentItem.urlImage1;
        $w('#text101').text = currentItem.supplier1;
        $w('#text36').text = currentItem.priceUrl1;
        $w('#text37').text = currentItem.sizeText1;
        $w('#buyNow1').label = currentItem.buttonText1;
        $w('#buyNow1').link = currentItem.url1;
        $w('#imageX145').src = currentItem.image1;
        $w('#imageX146').src = currentItem.image2;
        $w('#imageX147').src = currentItem.image3;
        $w('#imageX144,#imageX145,#imageX146,#imageX147').alt = currentItem.h1Title;
    }
    if (currentItem.sizeText1 === 'Sold Out') {
        $w('#buyNow1').style.backgroundColor = "#FF0000";
    }
}

function Supplier2() {
    if (currentItem.supplier2) {
        $w("#box85, #imageX14, #buyNow2, #line12").show();
        $w('#imageX14').src = currentItem.urlImage2;
        $w('#text42').text = currentItem.supplier2;
        $w('#text41').text = currentItem.priceUrl2;
        $w('#text40').text = currentItem.sizeText2;
        $w('#buyNow2').label = currentItem.buttonText2;
        $w('#buyNow2').link = currentItem.url2;
    }
    if (!currentItem.supplier2) {
        $w("#box85, #imageX14, #buyNow2, #line12, #text42, #text41, #text40, #buyNow2").collapse();
    }
    if (currentItem.sizeText2 === 'Sold Out') {
        $w('#buyNow2').style.backgroundColor = "#FF0000";
    }
}

function Supplier3() {
    if (currentItem.supplier3) {
        $w("#box34, #imageX10, #buyNow3, #line13").show();
        $w('#imageX10').src = currentItem.urlImage3;
        $w('#text46').text = currentItem.supplier3;
        $w('#text45').text = currentItem.priceUrl3;
        $w('#text44').text = currentItem.sizeText3;
        $w('#buyNow3').label = currentItem.buttonText3;
        $w('#buyNow3').link = currentItem.url3;
    }
    if (!currentItem.supplier3) {
        $w("#box34, #imageX10, #buyNow3, #line13, #text46, #text45, #text44, #buyNow3").collapse();
    }
    if (currentItem.sizeText3 === 'Sold Out') {
        $w('#buyNow3').style.backgroundColor = "#FF0000";
    }
}

function Supplier4() {
    if (currentItem.supplier4) {
        $w("#box35, #imageX12, #buyNow4, #line14").show();
        $w('#imageX12').src = currentItem.urlImage4;
        $w('#text50').text = currentItem.supplier4;
        $w('#text49').text = currentItem.priceUrl4;
        $w('#text48').text = currentItem.sizeText4;
        $w('#buyNow4').label = currentItem.buttonText4;
        $w('#buyNow4').link = currentItem.url4;
    }
    if (!currentItem.supplier4) {
        $w("#box35, #imageX12, #buyNow4, #line14, #text50, #text49, #text48, #buyNow4").collapse();
    }
    if (currentItem.sizeText4 === 'Sold Out') {
        $w('#buyNow4').style.backgroundColor = "#FF0000";
    }
}

function Supplier5() {
    if (currentItem.supplier5) {
        $w("#box36, #imageX13, #buyNow5, #line15").show();
        $w('#imageX13').src = currentItem.urlImage5;
        $w('#text54').text = currentItem.supplier5;
        $w('#text53').text = currentItem.priceUrl5;
        $w('#text52').text = currentItem.sizeText5;
        $w('#buyNow5').label = currentItem.buttonText5;
        $w('#buyNow5').link = currentItem.url5;
    }
    if (!currentItem.supplier5) {
        $w("#box36, #imageX13, #buyNow5, #line15, #text54, #text53, #text52, #buyNow5").collapse();
    }
    if (currentItem.sizeText5 === 'Sold Out') {
        $w('#buyNow5').style.backgroundColor = "#FF0000";
    }
}

function Supplier6() {
    if (currentItem.supplier6) {
        $w("#box373, #imageX141, #buyNow6, #line16").show();
        $w('#imageX141').src = currentItem.urlImage6;
        $w('#text281').text = currentItem.supplier6;
        $w('#text280').text = currentItem.priceUrl6;
        $w('#text279').text = currentItem.sizeText6;
        $w('#buyNow6').label = currentItem.buttonText6;
        $w('#buyNow6').link = currentItem.url6;
    }
    if (!currentItem.supplier6) {
        $w("#box373, #imageX141, #buyNow6, #line16, #text281, #text280, #text279, #buyNow6").collapse();
    }
    if (currentItem.sizeText6 === 'Sold Out') {
        $w('#buyNow6').style.backgroundColor = "#FF0000";
    }
}

function Supplier7() {
    if (currentItem.supplier7) {
        $w("#box415, #imageX142, #buyNow7, #line17").show();
        $w('#imageX142').src = currentItem.urlImage7;
        $w('#text294').text = currentItem.supplier7;
        $w('#text293').text = currentItem.priceUrl7;
        $w('#text292').text = currentItem.sizeText7;
        $w('#buyNow7').label = currentItem.buttonText7;
        $w('#buyNow7').link = currentItem.url7;
    }
    if (!currentItem.supplier7) {
        $w("#box415, #imageX142, #buyNow7, #line17, #text294, #text293, #text292, #buyNow7").collapse();
    }
    if (currentItem.sizeText7 === 'Sold Out') {
        $w('#buyNow7').style.backgroundColor = "#FF0000";
    }
}

function Supplier8() {
    if (currentItem.supplier8) {
        $w("#box416, #imageX143, #buyNow8, #line18").show();
        $w('#imageX143').src = currentItem.urlImage8;
        $w('#text297').text = currentItem.supplier8;
        $w('#text296').text = currentItem.priceUrl8;
        $w('#text295').text = currentItem.sizeText8;
        $w('#buyNow8').label = currentItem.buttonText8;
        $w('#buyNow8').link = currentItem.url8;
    }
    if (!currentItem.supplier8) {
        $w("#box416, #imageX143, #buyNow8, #line18, #text297, #text296, #text295, #buyNow8").collapse();
    }
    if (currentItem.sizeText8 === 'Sold Out') {
        $w('#buyNow8').style.backgroundColor = "#FF0000";
    }
}

export function imageX144_viewportEnter(event) {
    $w('#box424').style.backgroundColor = "#000000";
    $w('#box425,#box426,#box427').style.backgroundColor = "#979797";
}

export function imageX145_viewportEnter(event) {
    $w('#box425').style.backgroundColor = "#000000";
    $w('#box424,#box426,#box427').style.backgroundColor = "#979797";
}

export function imageX146_viewportEnter(event) {
    $w('#box426').style.backgroundColor = "#000000";
    $w('#box424,#box425,#box427').style.backgroundColor = "#979797";
}

export function imageX147_viewportEnter(event) {
    $w('#box427').style.backgroundColor = "#000000";
    $w('#box424,#box425,#box426').style.backgroundColor = "#979797";
}

import wixLocation from 'wix-location';

export function button64_click(event) {
    wixLocation.to('/footwear');
}

Thanks

Managed to solve this using the below code, may not the best way to do it but it works…

import wixData from 'wix-data';

$w.onReady(function () {
  $w('#repeater6').onItemReady(($item, itemData, index) => {
    $item('#imageX132').src = itemData.mainImage;
            $item('#text248').text = itemData.h1Title;
            $item('#text247').text = itemData.price;
            $item("#imageX132").link = "/footwear/" + itemData.title.replace(/ /g, '-');
  });

  wixData.query("MensFootwear")
    
    .find()
    .then((results) => {
let item = results.items[0];
      if (results.totalCount > 0) {
        $w('#repeater6').data = results.items.slice(0,6);
      } 
    })
    .catch((error) => {
      console.error(error);
    }); 
});
2 Likes