info2
July 24, 2024, 5:54pm
1
I’m having issues using CMS Sort with a dynamic text content that is being changed when an action is made.
For this case, it is calculating distance based on a person’s address and the inputted address/postal code.
Here is the staging link:
https://ctcplayground01.webflow.io/
Would love to know what is the issue and if there is a solution.
Hey @info2 ! Could you give me a search example I could try? All locations appear as 0 miles for me.
info2
July 24, 2024, 7:58pm
3
Sorry it’s only postal code at the moment. Try any postal code and it should populate @Support-Luis
Hey @info2 ! I’m sorry but I can not notice any issue with the setup… I can input an initial postal code and click on “Nearest Person to me” and the smallest distance is the top result. I can enter another postal code from another state and results are sorted upon clicking again.
Could you please share a loom on what the issue is?
info2
July 25, 2024, 4:01pm
5
Hey @Support-Luis , here is a loom briefly outlining the issue with CMS Sort and a new staging link to review.
https://ctcplayground01.webflow.io/home-copy
Awesome, thanks!
Here is a quick video from my end
info2
July 26, 2024, 2:42pm
7
The original page is not using CMS Sort to reorder from smallest to largest number, the new link I gave is using CMS Sort but is not working which I need help to figure out why.
Hope that helps clarify @Support-Luis
info2
July 29, 2024, 2:48pm
8
Any insight on how we can make this work @Support-Luis ?
Hey @info2 ! I’m afraid I have not managed to get it to work yet. I’ll get back to you once I find the best solution
1 Like
Hey @info2 ! Can you test this code?
// This file was generated by Slater.app - Prototype 2.js
window.fsAttributes = window.fsAttributes || [];
window.fsAttributes.push([
'cmssort',
(listInstances) => {
// ------------------------
// Global Variables //
// ------------------------
const [listInstance] = listInstances;
const inputElement = document.querySelector('[f-el="input"]'); // Google Maps Input
const personElements = Array.from(document.querySelectorAll('[f-el="item"]')); // Collection Items
const formElement = document.querySelector('[f-el="form"]'); // Form Filter
const listElement = document.querySelector('[f-el="list"]'); // Collection List
const clearButton = formElement.querySelector('[fs-cmsfilter-element="clear"]'); // Filter Clear Button
let currentState = null;
const applyAutocomplete = (inputElement) => {
const autocomplete = new google.maps.places.Autocomplete(inputElement, {
types: ['(regions)'],
componentRestrictions: { country: 'us' },
});
autocomplete.setFields(['address_components', 'geometry']);
autocomplete.addListener('place_changed', function () {
const place = autocomplete.getPlace();
if (place.address_components) {
let zipCode = null;
let state = null;
for (const component of place.address_components) {
if (component.types.includes('postal_code')) {
zipCode = component.short_name;
}
if (component.types.includes('administrative_area_level_1')) {
state = component.long_name;
}
}
if (zipCode) {
calculateDistances(zipCode);
}
if (state) {
checkStateFilter(state);
currentState = state;
}
}
});
// ------------------------
// Clearing Input via Empty Input or Manual Click //
// ------------------------
inputElement.addEventListener('input', function () {
const input = this.value.trim();
if (input === '') {
clearButton?.click();
resetDistanceAndDuration();
clearDistanceAttributes();
} else if (/^\d{5}$/.test(input)) {
calculateDistances(input);
}
});
};
clearButton.addEventListener('click', () => {
resetDistanceAndDuration();
clearDistanceAttributes();
inputElement.value = '';
});
// ------------------------
// Calculate Distance via Google Maps JS //
// ------------------------
function calculateDistances(zipCode) {
const geocoder = new google.maps.Geocoder();
const distanceService = new google.maps.DistanceMatrixService();
geocoder.geocode({ address: zipCode }, function (results, status) {
if (status === 'OK' && results[0]) {
const origin = results[0].geometry.location;
personElements.forEach((person) => {
const address = person.querySelector('[f-el="address"]').textContent;
distanceService.getDistanceMatrix(
{
origins: [origin],
destinations: [address],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
},
function (response, status) {
if (status === 'OK') {
const distance = response.rows[0].elements[0].distance;
const duration = response.rows[0].elements[0].duration;
const distanceInMiles = (distance.value / 1609.34).toFixed(2);
let durationInMinutes = Math.round(duration.value / 60);
let durationHours = Math.floor(durationInMinutes / 60);
let durationDays = Math.floor(durationHours / 24);
durationHours %= 24;
durationInMinutes %= 60;
let durationText = `${durationInMinutes} mins`;
if (durationHours > 0) {
durationText = `${durationHours} hr ${durationText}`;
}
if (durationDays > 0) {
durationText = `${durationDays} day ${durationText}`;
}
person
.querySelectorAll('[f-el="distance"]')
.forEach((el) => (el.textContent = `${distanceInMiles}`));
person
.querySelectorAll('[f-el="min"]')
.forEach((el) => (el.textContent = `${durationText}`));
// Store the distance in a data attribute for sorting
person.setAttribute('data-distance', distanceInMiles);
}
window.fsAttributes.cmssort.destroy(); // needed to restar CMS Sort
window.fsAttributes.cmssort.init();
}
);
});
}
});
}
// ------------------------
// Autoclick on CMS Filter checkbox with States
// ------------------------
function checkStateFilter(state) {
if (formElement) {
const stateElements = formElement.querySelectorAll('[fs-cmsfilter-field="state"]');
stateElements.forEach((stateElement) => {
const stateName = stateElement.textContent.trim();
let checkbox = stateElement.previousElementSibling;
if (stateName === state) {
if (!checkbox.checked) {
checkbox.click();
}
} else if (stateName === currentState) {
if (checkbox.checked) {
checkbox.click();
}
}
});
}
}
// ------------------------
// Reset Functions //
// ------------------------
function resetDistanceAndDuration() {
personElements.forEach((person) => {
person.querySelectorAll('[f-el="distance"]').forEach((el) => (el.textContent = '0 miles'));
person.querySelectorAll('[f-el="min"]').forEach((el) => (el.textContent = '0 mins'));
});
}
function clearDistanceAttributes() {
personElements.forEach((person) => {
person.removeAttribute('data-distance');
});
}
// ------------------------
// Call Functions //
// ------------------------
applyAutocomplete(inputElement);
resetDistanceAndDuration();
},
]);
info2
July 31, 2024, 3:44pm
11
This works! Now having issues with CMS Load if the item are paginated @Support-Luis
Hey @info2 ! Issues with which part of the code?
info2
August 1, 2024, 3:19pm
13
I added CMS Load and having issues where it doesn’t hide or show the pagination buttons sometimes when I clear after filtering. @Support-Luis
Could you record a quick video on how to reproduce the issue?
1 Like
info2
August 1, 2024, 7:28pm
15
Here you go @Support-Luis
You’ll see a few issues:
Only calculation is being done on the first page of the pagination
Once cleared/reset, pagination buttons are gone permanently
Require refresh to restore pagination
Hey @info2 ! Seems that the lines we added to destroy and init CMS Sort are introducing the bug. If you comment them out everything should work normally except the sorting of the items.
We can ditch the Attributes sorting and create our own sorting function instead.
Let me know what you think
info2
August 7, 2024, 2:44pm
18
Sure that would work as well. Is there no way to make CMS Load work then? @Support-Luis
CMS Load will work and it should work at the moment if you just comment on these two lines
window.fsAttributes.cmssort.destroy(); // needed to restar CMS Sort
window.fsAttributes.cmssort.init();
I’ll work on integrating the sorting function and get back to you
1 Like