Optimized For Dynamic Content This is usually what you will want to use - it works with over 100 CMS Items using Finsweet CMS Load.
Copiar guión
<!-- 💙 MEMBERSCRIPT #20 v0.3 💙 SAVE & UNSAVE CMS ITEMS (OPTIMIZED FOR DYNAMIC CONTENT SUPPORT) -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
const memberData = (await memberstack.getMemberJSON()).data || {};
const updateButtonVisibility = function(button, savedItems) {
const itemId = button.getAttribute('ms-code-save-child');
const isItemSaved = savedItems.includes(itemId);
button.style.display = isItemSaved ? 'none' : 'block';
const action = isItemSaved ? 'block' : 'none';
button.closest('[ms-code-save]').querySelectorAll(`[ms-code-unsave-child="${itemId}"]`).forEach(unsaveButton => {
unsaveButton.style.display = action;
});
};
const toggleLikeButton = async function(button, jsonGroup, savedItems) {
const itemId = button.getAttribute('ms-code-save-child');
const itemIndex = savedItems.indexOf(itemId);
if (itemIndex > -1) {
savedItems.splice(itemIndex, 1); // Remove item from saved list
} else {
savedItems.push(itemId); // Add item to saved list
}
memberData[jsonGroup] = savedItems; // Directly modify the memberData to ensure updates are propagated correctly
await memberstack.updateMemberJSON({ json: memberData });
updateButtonVisibility(button, savedItems);
};
const initializeButtons = function(buttons, action) {
buttons.forEach(button => {
const jsonGroup = button.getAttribute('ms-code-save') || button.closest('[ms-code-save]').getAttribute('ms-code-save');
const savedItems = memberData[jsonGroup] || [];
if (action === 'update') updateButtonVisibility(button, savedItems);
button.removeEventListener('click', buttonClickHandler); // Prevent multiple bindings
button.addEventListener('click', buttonClickHandler);
});
};
function buttonClickHandler(event) {
event.preventDefault();
const button = event.currentTarget;
const jsonGroup = button.getAttribute('ms-code-save') || button.closest('[ms-code-save]').getAttribute('ms-code-save');
const savedItems = memberData[jsonGroup] || [];
toggleLikeButton(button, jsonGroup, savedItems);
}
const observeDOMChanges = function() {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1 && (node.matches('[ms-code-save-child]') || node.querySelector('[ms-code-save-child]'))) {
const saveButtons = node.querySelectorAll('[ms-code-save-child]');
const unsaveButtons = node.querySelectorAll('[ms-code-unsave-child]');
initializeButtons(saveButtons, 'update');
initializeButtons(unsaveButtons, 'attach');
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
};
const saveButtons = document.querySelectorAll('[ms-code-save-child]');
const unsaveButtons = document.querySelectorAll('[ms-code-unsave-child]');
initializeButtons(saveButtons, 'update');
initializeButtons(unsaveButtons, 'attach');
observeDOMChanges(); // Start observing changes in the document
});
</script>
Using Finsweet CMS Load If you do have over 100 CMS items, please watch this video.
Loads after member object If both logged in & logged out visitors will be on the page with this script, using this method will prevent errors.
Copiar guión
<!-- 💙 MEMBERSCRIPT #20.1 v0.2 💙 SAVE & UNSAVE CMS ITEMS AFTER MEMBERSTACK LOAD -->
<script>
const memberstack = window.$memberstackDom;
const updateButtonVisibility = async function(button, jsonGroup) {
const itemId = button.getAttribute('ms-code-save-child');
const member = await memberstack.getMemberJSON();
const savedItems = member.data && member.data[jsonGroup] ? member.data[jsonGroup] : [];
const isItemSaved = savedItems.includes(itemId);
const saveButton = button;
const parentElement = button.closest('[ms-code-save]');
const unsaveButtons = parentElement.querySelectorAll(`[ms-code-unsave-child="${itemId}"]`);
unsaveButtons.forEach(unsaveButton => {
if (isItemSaved) {
saveButton.style.display = 'none';
unsaveButton.style.display = 'block';
} else {
saveButton.style.display = 'block';
unsaveButton.style.display = 'none';
}
});
};
const toggleLikeButton = async function(button, jsonGroup) {
const itemId = button.getAttribute('ms-code-save-child');
const member = await memberstack.getMemberJSON();
if (!member.data) {
member.data = {};
}
if (!member.data[jsonGroup]) {
member.data[jsonGroup] = [];
}
const isItemSaved = member.data[jsonGroup].includes(itemId);
const parentElement = button.closest('[ms-code-save]');
const unsaveButtons = parentElement.querySelectorAll(`[ms-code-unsave-child="${itemId}"]`);
if (isItemSaved) {
member.data[jsonGroup] = member.data[jsonGroup].filter(item => item !== itemId);
button.style.display = 'block';
unsaveButtons.forEach(unsaveButton => {
unsaveButton.style.display = 'none';
});
} else {
member.data[jsonGroup].push(itemId);
button.style.display = 'none';
unsaveButtons.forEach(unsaveButton => {
unsaveButton.style.display = 'block';
});
}
await memberstack.updateMemberJSON({
json: member.data
});
updateButtonVisibility(button, jsonGroup);
};
memberstack.getCurrentMember().then(({ data }) => {
if (data) {
// Member is logged in
const saveButtons = document.querySelectorAll('[ms-code-save-child]');
saveButtons.forEach(button => {
const jsonGroup = button.getAttribute('ms-code-save') || button.closest('[ms-code-save]').getAttribute('ms-code-save');
updateButtonVisibility(button, jsonGroup);
button.addEventListener('click', async function(event) {
event.preventDefault();
await toggleLikeButton(button, jsonGroup);
});
});
const unsaveButtons = document.querySelectorAll('[ms-code-unsave-child]');
unsaveButtons.forEach(button => {
const jsonGroup = button.getAttribute('ms-code-save') || button.closest('[ms-code-save]').getAttribute('ms-code-save');
button.addEventListener('click', async function(event) {
event.preventDefault();
const parentElement = button.closest('[ms-code-save]');
const saveButton = parentElement.querySelector(`[ms-code-save-child="${button.getAttribute('ms-code-unsave-child')}"]`);
await toggleLikeButton(saveButton, jsonGroup);
});
});
} else {
// If member is not logged in
}
});
</script>