#106 - Gustar y guardar art铆culos CMS

Permita a sus miembros guardar elementos CMS en su perfil.

Video Tutorial

tutorial.mov

Watch the video for step-by-step implementation instructions

The Code

138 lines
Paste this into Webflow
<!-- 馃挋 MEMBERSCRIPT #106 v0.2 馃挋 SAVING & UNSAVING CMS ITEMS -->
<style>
 聽[ms-code-save], [ms-code-unsave] {
 聽 聽display: none;
 聽}
 聽[ms-code-save-item] {
 聽 聽display: none;
 聽}
</style>
<script>
document.addEventListener("DOMContentLoaded", function() {
 聽const memberstack = window.$memberstackDom;
 聽let isLoggedIn = false;
 聽let savedItems = [];

 聽async function checkMemberLogin() {
 聽 聽try {
 聽 聽 聽const member = await memberstack.getCurrentMember();
 聽 聽 聽return !!member;
 聽 聽} catch (error) {
 聽 聽 聽return false;
 聽 聽}
 聽}

 聽function getSavedItems(memberData) {
 聽 聽return memberData.savedItems || [];
 聽}

 聽function updateButtonVisibility() {
 聽 聽const saveButtons = document.querySelectorAll('[ms-code-save]');
 聽 聽const unsaveButtons = document.querySelectorAll('[ms-code-unsave]');

 聽 聽saveButtons.forEach(button => {
 聽 聽 聽const itemId = button.getAttribute('ms-code-save');
 聽 聽 聽button.style.display = !savedItems.includes(itemId) ? 'block' : 'none';
 聽 聽});

 聽 聽unsaveButtons.forEach(button => {
 聽 聽 聽const itemId = button.getAttribute('ms-code-unsave');
 聽 聽 聽button.style.display = savedItems.includes(itemId) ? 'block' : 'none';
 聽 聽});
 聽}

 聽function updateItemVisibility() {
 聽 聽const saveLists = document.querySelectorAll('[ms-code-save-list]');
 聽 聽saveLists.forEach(list => {
 聽 聽 聽const filter = list.getAttribute('ms-code-save-list');
 聽 聽 聽const items = list.querySelectorAll('[ms-code-save-item]');
 聽 聽 聽items.forEach(item => {
 聽 聽 聽 聽const saveButton = item.querySelector('[ms-code-save]');
 聽 聽 聽 聽if (!saveButton) {
 聽 聽 聽 聽 聽item.style.display = 'block';
 聽 聽 聽 聽 聽return;
 聽 聽 聽 聽}
 聽 聽 聽 聽const itemId = saveButton.getAttribute('ms-code-save');
 聽 聽 聽 聽
 聽 聽 聽 聽if (!isLoggedIn || filter === 'all') {
 聽 聽 聽 聽 聽item.style.display = 'block';
 聽 聽 聽 聽} else if (filter === 'saved' & savedItems.includes(itemId)) {
 聽 聽 聽 聽 聽item.style.display = 'block';
 聽 聽 聽 聽} else if (filter === 'unsaved' & !savedItems.includes(itemId)) {
 聽 聽 聽 聽 聽item.style.display = 'block';
 聽 聽 聽 聽} else {
 聽 聽 聽 聽 聽item.style.display = 'none';
 聽 聽 聽 聽}
 聽 聽 聽});
 聽 聽});
 聽}

 聽async function handleButtonClick(event) {
 聽 聽if (!isLoggedIn) return;

 聽 聽const button = event.currentTarget;
 聽 聽const action = button.getAttribute('ms-code-save') ? 'save' : 'unsave';
 聽 聽const itemId = button.getAttribute(action === 'save' ? 'ms-code-save' : 'ms-code-unsave');
 聽 聽
 聽 聽if (action === 'save' && !savedItems.includes(itemId)) {
 聽 聽 聽savedItems.push(itemId);
 聽 聽} else if (action === 'unsave') {
 聽 聽 聽savedItems = savedItems.filter(id => id !== itemId);
 聽 聽}

 聽 聽try {
 聽 聽 聽await memberstack.updateMemberJSON({ json: { savedItems } });
 聽 聽} catch (error) {
 聽 聽 聽// Silently handle the error
 聽 聽}

 聽 聽updateButtonVisibility();
 聽 聽updateItemVisibility();
 聽}

 聽function addClickListeners() {
 聽 聽const saveButtons = document.querySelectorAll('[ms-code-save]');
 聽 聽const unsaveButtons = document.querySelectorAll('[ms-code-unsave]');
 聽 聽saveButtons.forEach(button => button.addEventListener('click', handleButtonClick));
 聽 聽unsaveButtons.forEach(button => button.addEventListener('click', handleButtonClick));
 聽}

 聽async function initializeScript() {
 聽 聽isLoggedIn = await checkMemberLogin();

 聽 聽if (isLoggedIn) {
 聽 聽 聽try {
 聽 聽 聽 聽const result = await memberstack.getMemberJSON();
 聽 聽 聽 聽const memberData = result.data || {};
 聽 聽 聽 聽savedItems = getSavedItems(memberData);
 聽 聽 聽} catch (error) {
 聽 聽 聽 聽// Silently handle the error
 聽 聽 聽}
 聽 聽}

 聽 聽updateButtonVisibility();
 聽 聽updateItemVisibility();
 聽 聽addClickListeners();

 聽 聽// Set up a MutationObserver to watch keywordfor changes in the DOM
 聽 聽const observer = new MutationObserver((mutations) => {
 聽 聽 聽let shouldUpdate = false;
 聽 聽 聽mutations.forEach((mutation) => {
 聽 聽 聽 聽if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
 聽 聽 聽 聽 聽shouldUpdate = true;
 聽 聽 聽 聽}
 聽 聽 聽});
 聽 聽 聽if (shouldUpdate) {
 聽 聽 聽 聽updateButtonVisibility();
 聽 聽 聽 聽updateItemVisibility();
 聽 聽 聽 聽addClickListeners();
 聽 聽 聽}
 聽 聽});

 聽 聽// Start observing the document with the configured parameters
 聽 聽observer.observe(document.body, { childList: true, subtree: true });
 聽}

 聽initializeScript();
});
</script>

Script Info

Versionv0.2
PublishedNov 11, 2025
Last UpdatedNov 11, 2025

Need Help?

Join our Slack community for support, questions, and script requests.

Join Slack Community
Back to All Scripts

Related Scripts

More scripts in JSON