Webflow Page with multiple external data collection lists

Hello! Im having some issues when trying to reference several external lists (local or api sources) to lists collections using attributes.

In my case, I want to show two different lists of photos in a webflow page. I have define both instances in the custom code section, and replicated the code structure provided by Alex in the youtube video CMS Attributes + External Data (https://www.youtube.com/watch?v=VgI8rf9mbH4).

I got this to work perfectly with one list, but when trying with several lists it doesn’t seem to work. For some reason, its only showing me the first collection list with the last instance created in the custom code:

I’ve seen in Finsweet documentation, that I have to reference the second list with atributtes labeled with the suffix (-2). I have done this for following elements:

Form: fs-cmsfilter-element:“filters-2”
Select Field: fs-cmssort-element: “trigger-2”
Button: fs-cmsfilter-element: “reset-2”
Radio button field: data-element:“filter-2”
Collection list: fs-cmsload-element: “list-2” + fs-cmsfilter-element: “list-2” + fs-cmssort-element: “list-2”

As im pretty new in all this, im sure im missing out on something important in the attributes configuration or the instances creation on the custom code section.

Anyone with any ideas on this?

Thanks,

Alex :slight_smile:

Hey @web.myactors! can you share a read-only link?

Hello @Support-Luis! Thanks for your quick response. Heres share-only link.

https://preview.webflow.com/preview/myactors?utm_medium=preview_link&utm_source=designer&utm_content=myactors&preview=ea0cf795fb09029d804f67f60b3ac423&pageId=6476637ec9b4aae9b0ce2c4f&workflow=preview

Much appreciated!

Hey @web.myactors! you were using const [filtersInstance] = filtersInstances; for both instances and this will only target the first filter instance.

You can try using this code instead which worked alright on my end. (ran it through ChatGPT to refactor it and remove duplicated code)

<script>
      window.fsAttributes = window.fsAttributes || [];

      const photoLists = [
        {
          listInstanceIndex: 0,
          photoList: [
            {
              title: 'Image 1',
              image:
                'https://fastly.picsum.photos/id/25/5000/3333.jpg?hmac=yCz9LeSs-i72Ru0YvvpsoECnCTxZjzGde805gWrAHkM',
              description: 'Example description 1',
              category: 'Trees',
            },
            {
              title: 'Image 2',
              image:
                'https://fastly.picsum.photos/id/29/4000/2670.jpg?hmac=rCbRAl24FzrSzwlR5tL-Aqzyu5tX_PA95VJtnUXegGU',
              description: 'Example description 2',
              category: 'Mountains',
            },
            // Add more objects as needed
          ],
        },
        {
          listInstanceIndex: 1,
          photoList: [
            {
              title: 'Image 1',
              image:
                'https://fastly.picsum.photos/id/28/4928/3264.jpg?hmac=GnYF-RnBUg44PFfU5pcw_Qs0ReOyStdnZ8MtQWJqTfA',
              description: 'Example description 1',
              category: 'Jungle',
            },
            {
              title: 'Image 2',
              image:
                'https://fastly.picsum.photos/id/18/2500/1667.jpg?hmac=JR0Z_jRs9rssQHZJ4b7xKF82kOj8-4Ackq75D_9Wmz8',
              description: 'Example description 2',
              category: 'Grass',
            },
            // Add more objects as needed
          ],
        },
      ];

      photoLists.forEach(({ listInstanceIndex, photoList }) => {
        window.fsAttributes.push([
          'cmsfilter',
          async (filtersInstances) => {
            const filtersInstance = filtersInstances[listInstanceIndex];
            const { listInstance } = filtersInstance;
            const [firstItem] = listInstance.items;
            const itemTemplateElement = firstItem.element;

            console.log(`Photo List ${listInstanceIndex + 1}:`, photoList);

            listInstance.clearItems();
            const newItems = photoList.map((product) => createItem(product, itemTemplateElement));
            await listInstance.addItems(newItems);

            const filterElementSelector =
              listInstanceIndex === 0 ? '[data-element="filter"]' : '[data-element="filter-2"]';
            const filterTemplateElement = filtersInstance.form.querySelector(filterElementSelector);
            if (!filterTemplateElement) return;
            const filtersWrapper = filterTemplateElement.parentElement;
            if (!filtersWrapper) return;
            filterTemplateElement.remove();
            const categories = collectCategories(photoList);
            for (const category of categories) {
              const newFilter = createFilter(category, filterTemplateElement);
              if (!newFilter) continue;
              filtersWrapper.append(newFilter);
            }
            filtersInstance.storeFiltersData();
          },
        ]);
      });

      var createItem = (product, templateElement) => {
        const newItem = templateElement.cloneNode(true);
        const image = newItem.querySelector('[data-element="image"]');
        const title = newItem.querySelector('[data-element="title"]');
        const category = newItem.querySelector('[data-element="category"]');
        const description = newItem.querySelector('[data-element="description"]');
        if (image) image.src = product.image;
        if (title) title.textContent = product.title;
        if (category) category.textContent = product.category;
        if (description) description.textContent = product.description;
        return newItem;
      };

      var collectCategories = (products) => {
        const categories = new Set();
        for (const { category } of products) {
          categories.add(category);
        }
        return [...categories];
      };

      var createFilter = (category, templateElement) => {
        const newFilter = templateElement.cloneNode(true);
        const label = newFilter.querySelector('span');
        const radio = newFilter.querySelector('input');
        if (!label || !radio) return;
        label.textContent = category;
        radio.value = category;
        return newFilter;
      };
    </script>

This uses a forEach loop for your photoLists but you can loop over attributes instances like this

<script>
  window.fsAttributes = window.fsAttributes || [];
  window.fsAttributes.push([
    'cmsload',
    (listInstances) => {
      console.log('cmsload Successfully loaded!');
      listInstances.forEach((instance) => {
        instance.on('renderitems', (renderedItems) => {
          // your code for all cmsload instances
        });
      });
    },
  ]);
</script>