CMS Load – Render all issue

Hello.

I’ve implemented CMS Load + Render All on a collection list with 194 items, but I’m struggling with getting all items to render in this list. I’ve set the pagination natively and the limit to 100 items but I’m still having to use ‘Next’ to view the remaining 94 items.

The crux of the issue that I’ve integrated this CMS list with a Mapbox embed, and thus I need all 194 items to render in order to reflect on the map.

Pagination works – if I hide the list, but keep the pagination buttons set to visible, I can toggle between two views where items 1-100 are visible on the first and items 101-194 on the second render of the map, but I can’t seem to figure this one out!

I’ve had no luck in trouble shooting with the Automated support, nor with other queries on this forum, hence my asking here.

See a link to the page here

Hey @Work-Work! You are missing the Attribute script :wink:

<!-- [Attributes by Finsweet] CMS Load -->
<script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-cmsload@1/cmsload.js"></script>

Could you please add it and let me know how it goes?

Hey @Support-Luis

Thanks for picking that up. It is indeed now rendering the full list, which set to not-display, but I’m still not sure why the 100-item limit is still applied when that collection list is rendered on the Mapbox Embed.

Do you have any ideas?

Hey @Work-Work It may be on how the map is innitialized. Can you share the code, if any, that you are using?

Hey Louis:

See below the code snippet that I’m using before tag of the page in question

<script>

mapboxgl.accessToken = "pk.eyJ1IjoiYW10eW1iaW9zIiwiYSI6ImNsbjJ2bXU2dzBkODMya3IzY3gxMjdrMGQifQ.Y-jfjkM1ZaThsFlk3VRuyg";

// create empty locations geojson object
let mapLocations = {
	type: "FeatureCollection",
	features: [],
};

let selectedMapLocations = [];

// Initialize map and load in #map wrapper
let map = new mapboxgl.Map({
	container: "map",
	style: "mapbox://styles/amtymbios/clph7q4ea00jv01r5eyykbw6c",
	center: [19.229,17.699],
	zoom: 2.15,
});

// disable map zoom when using scroll
map.scrollZoom.disable();

// Adjust zoom of map for mobile and desktop
let mq = window.matchMedia("(min-width: 480px)");
if (mq.matches) {
	map.setZoom(2.15); //set map zoom level for desktop size
} else {
	map.setZoom(2.6); //set map zoom level for mobile size
}

// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl());

// Get cms items
let listLocations = document.getElementById("location-list").childNodes;

// For each colleciton item, grab hidden fields and convert to geojson proerty
function getGeoData() {
	listLocations.forEach(function (location) {
		console.log(location);
		let locationLat = location.querySelector("#locationLatitude").value;
		let locationLong = location.querySelector("#locationLongitude").value;
		let locationInfo = location.querySelector(".locations-map_card").innerHTML;
		let coordinates = [locationLong, locationLat];
		let locationID = location.querySelector("#locationID").value;
		let geoData = {
			type: "Feature",
			geometry: {
				type: "Point",
				coordinates: coordinates,
			},
			properties: {
				id: locationID,
				description: locationInfo,
			},
		};

		if (mapLocations.features.includes(geoData) === false) {
			mapLocations.features.push(geoData);
		}
	});
	console.log(mapLocations);
}

// Invoke function
getGeoData();

// Define mapping function to be invoked later
function addMapPoints() {
	/* Add the data to your map as a layer */
	map.addLayer({
		id: "locations",
		type: "circle",
		/* Add a GeoJSON source containing place coordinates and information. */
		source: {
			type: "geojson",
			data: mapLocations,
		},
		paint: {
			"circle-radius": 6,
			"circle-stroke-width": .5,
			"circle-color": "#fbbf10",
			"circle-opacity": 1,
			"circle-stroke-color": "white",
		},
	});

	// When a click event occurs on a feature in the places layer, open a popup at the
	// location of the feature, with description HTML from its properties.
	map.on("click", "locations", (e) => {
		// Copy coordinates array.
		const coordinates = e.features[0].geometry.coordinates.slice();
		const description = e.features[0].properties.description;

		// Ensure that if the map is zoomed out such that multiple
		// copies of the feature are visible, the popup appears
		// over the copy being pointed to.
		while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
			coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
		}

		new mapboxgl.Popup().setLngLat(coordinates).setHTML(description).addTo(map);
	});

	// Center the map on the coordinates of any clicked circle from the 'locations' layer.
	map.on("click", "locations", (e) => {
		map.flyTo({
			center: e.features[0].geometry.coordinates,
			speed: 0.5,
			curve: 1,
			easing(t) {
				return t;
			},
		});
	});

	// Change the cursor to a pointer when the mouse is over the 'locations' layer.
	map.on("mouseenter", "locations", () => {
		map.getCanvas().style.cursor = "pointer";
	});

	// Change it back to a pointer when it leaves.
	map.on("mouseleave", "locations", () => {
		map.getCanvas().style.cursor = "";
	});
}

//When map is loaded initialize with data
map.on("load", function (e) {
	addMapPoints();
});

</script>
```*emphasized text*

My theory is that the map is being initiated before the whole list is finished rendering, as you are using CMS Load mode set to render-all we can’t use the renderitems event we would normally use.

Can you please test this code? It will wait for the renderingQueue to be fullfilled and then run the map code.

<script>
  window.fsAttributes = window.fsAttributes || [];
  window.fsAttributes.push([
    'cmsload',
    (listInstances) => {
      console.log('cmsload Successfully loaded!');

      const [listInstance] = listInstances;
      console.log(listInstance);
      // Define an async function to use await
      async function processRenderingQueue() {
        try {
          // Await the fulfillment of the renderingQueue Promise
          const result = await listInstance.renderingQueue;

          mapboxgl.accessToken =
            'pk.eyJ1IjoiYW10eW1iaW9zIiwiYSI6ImNsbjJ2bXU2dzBkODMya3IzY3gxMjdrMGQifQ.Y-jfjkM1ZaThsFlk3VRuyg';

          // create empty locations geojson object
          let mapLocations = {
            type: 'FeatureCollection',
            features: [],
          };

          let selectedMapLocations = [];

          // Initialize map and load in #map wrapper
          let map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/amtymbios/clph7q4ea00jv01r5eyykbw6c',
            center: [19.229, 17.699],
            zoom: 2.15,
          });

          // disable map zoom when using scroll
          map.scrollZoom.disable();

          // Adjust zoom of map for mobile and desktop
          let mq = window.matchMedia('(min-width: 480px)');
          if (mq.matches) {
            map.setZoom(2.15); //set map zoom level for desktop size
          } else {
            map.setZoom(2.6); //set map zoom level for mobile size
          }

          // Add zoom and rotation controls to the map.
          map.addControl(new mapboxgl.NavigationControl());

          // Get cms items
          let listLocations = document.getElementById('location-list').childNodes;

          // For each colleciton item, grab hidden fields and convert to geojson proerty
          function getGeoData() {
            listLocations.forEach(function (location) {
              console.log(location);
              let locationLat = location.querySelector('#locationLatitude').value;
              let locationLong = location.querySelector('#locationLongitude').value;
              let locationInfo = location.querySelector('.locations-map_card').innerHTML;
              let coordinates = [locationLong, locationLat];
              let locationID = location.querySelector('#locationID').value;
              let geoData = {
                type: 'Feature',
                geometry: {
                  type: 'Point',
                  coordinates: coordinates,
                },
                properties: {
                  id: locationID,
                  description: locationInfo,
                },
              };

              if (mapLocations.features.includes(geoData) === false) {
                mapLocations.features.push(geoData);
              }
            });
            console.log(mapLocations);
          }

          // Invoke function
          getGeoData();

          // Define mapping function to be invoked later
          function addMapPoints() {
            /* Add the data to your map as a layer */
            map.addLayer({
              id: 'locations',
              type: 'circle',
              /* Add a GeoJSON source containing place coordinates and information. */
              source: {
                type: 'geojson',
                data: mapLocations,
              },
              paint: {
                'circle-radius': 6,
                'circle-stroke-width': 0.5,
                'circle-color': '#fbbf10',
                'circle-opacity': 1,
                'circle-stroke-color': 'white',
              },
            });

            // When a click event occurs on a feature in the places layer, open a popup at the
            // location of the feature, with description HTML from its properties.
            map.on('click', 'locations', (e) => {
              // Copy coordinates array.
              const coordinates = e.features[0].geometry.coordinates.slice();
              const description = e.features[0].properties.description;

              // Ensure that if the map is zoomed out such that multiple
              // copies of the feature are visible, the popup appears
              // over the copy being pointed to.
              while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
              }

              new mapboxgl.Popup().setLngLat(coordinates).setHTML(description).addTo(map);
            });

            // Center the map on the coordinates of any clicked circle from the 'locations' layer.
            map.on('click', 'locations', (e) => {
              map.flyTo({
                center: e.features[0].geometry.coordinates,
                speed: 0.5,
                curve: 1,
                easing(t) {
                  return t;
                },
              });
            });

            // Change the cursor to a pointer when the mouse is over the 'locations' layer.
            map.on('mouseenter', 'locations', () => {
              map.getCanvas().style.cursor = 'pointer';
            });

            // Change it back to a pointer when it leaves.
            map.on('mouseleave', 'locations', () => {
              map.getCanvas().style.cursor = '';
            });
          }

          //When map is loaded initialize with data
          map.on('load', function (e) {
            addMapPoints();
          });
        } catch (error) {
          // Handle any errors that may occur during the Promise execution
          console.error('Error processing renderingQueue:', error);
        }
      }

      // Call the async function to start processing the renderingQueue
      processRenderingQueue();
    },
  ]);
</script>
1 Like

@Support-Luis It works!

I’ve spent the better half of the day trying to figure out how to write that little bit of code!

Thank you so much mister!

1 Like

You are welcome! :raised_hands:

1 Like

Hey Luis,

Circling back to this solution which worked so well with the CMS Load Attribute.

I’m working on a project with exactly the same Mapbox Implementation, but this time round I need to allow for scenario where the CMS List that populates the map is filtered using Finsweet’s CMS Filter Attributes.

Would you be able to assist me in figuring out how to write that additional snippet that would filter the list before populating the map?

Many thanks again for the excellent help,

Michael

Hey @Work-Work! Can you share the project with this setup? I can try some stuff to see if we can handle it.