Mitglieder-Skripte
Eine attributbasierte Lösung zum Hinzufügen von Funktionen zu Ihrer Webflow-Site.
Kopieren Sie einfach etwas Code, fügen Sie einige Attribute hinzu, und schon sind Sie fertig.
Alle Memberstack-Kunden können im 2.0 Slack um Unterstützung bitten. Bitte beachten Sie, dass dies keine offiziellen Funktionen sind und der Support nicht garantiert werden kann.

#98 - Altersfreigabe
Die Benutzer müssen ihr Alter bestätigen, bevor sie fortfahren.
<!-- 💙 MEMBERSCRIPT #98 v0.1 💙 AGE GATE -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const form = document.querySelector('form[ms-code-age-gate]');
const dayInput = document.querySelector('input[ms-code-age-gate="day"]');
const monthInput = document.querySelector('input[ms-code-age-gate="month"]');
const yearInput = document.querySelector('input[ms-code-age-gate="year"]');
const backButton = document.querySelector('a[ms-code-age-gate="back"]');
const wrapper = document.querySelector('[ms-code-age-gate="wrapper"]');
const errorDiv = document.querySelector('div[ms-code-age-gate="error"]');
if (localStorage.getItem('ageVerified') === 'true') {
wrapper.remove();
return;
}
backButton.addEventListener('click', (e) => {
e.preventDefault();
window.history.back();
});
const inputs = [dayInput, monthInput, yearInput];
inputs.forEach((input, index) => {
input.addEventListener('keyup', (e) => {
const maxChars = input === yearInput ? 4 : 2;
let value = e.target.value;
if (input === dayInput && value.length === maxChars) {
value = value > 31 ? '31' : value.padStart(2, '0');
} else if (input === monthInput && value.length === maxChars) {
value = value > 12 ? '12' : value.padStart(2, '0');
}
e.target.value = value;
if (value.length === maxChars) {
const nextInput = inputs[index + 1];
if (nextInput) {
nextInput.focus();
}
}
});
});
form.addEventListener('submit', (e) => {
e.preventDefault();
const enteredDate = new Date(yearInput.value, monthInput.value - 1, dayInput.value);
const currentDate = new Date();
const ageDifference = new Date(currentDate - enteredDate);
const age = Math.abs(ageDifference.getUTCFullYear() - 1970);
const ageLimit = parseInt(form.getAttribute('ms-code-age-gate').split('-')[1], 10);
if (age >= ageLimit) {
console.log('Age verified.');
errorDiv.style.display = 'none';
localStorage.setItem('ageVerified', 'true');
wrapper.remove();
} else {
console.log('Age verification failed, user is under the age limit.');
errorDiv.style.display = 'block';
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #98 v0.1 💙 AGE GATE -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const form = document.querySelector('form[ms-code-age-gate]');
const dayInput = document.querySelector('input[ms-code-age-gate="day"]');
const monthInput = document.querySelector('input[ms-code-age-gate="month"]');
const yearInput = document.querySelector('input[ms-code-age-gate="year"]');
const backButton = document.querySelector('a[ms-code-age-gate="back"]');
const wrapper = document.querySelector('[ms-code-age-gate="wrapper"]');
const errorDiv = document.querySelector('div[ms-code-age-gate="error"]');
if (localStorage.getItem('ageVerified') === 'true') {
wrapper.remove();
return;
}
backButton.addEventListener('click', (e) => {
e.preventDefault();
window.history.back();
});
const inputs = [dayInput, monthInput, yearInput];
inputs.forEach((input, index) => {
input.addEventListener('keyup', (e) => {
const maxChars = input === yearInput ? 4 : 2;
let value = e.target.value;
if (input === dayInput && value.length === maxChars) {
value = value > 31 ? '31' : value.padStart(2, '0');
} else if (input === monthInput && value.length === maxChars) {
value = value > 12 ? '12' : value.padStart(2, '0');
}
e.target.value = value;
if (value.length === maxChars) {
const nextInput = inputs[index + 1];
if (nextInput) {
nextInput.focus();
}
}
});
});
form.addEventListener('submit', (e) => {
e.preventDefault();
const enteredDate = new Date(yearInput.value, monthInput.value - 1, dayInput.value);
const currentDate = new Date();
const ageDifference = new Date(currentDate - enteredDate);
const age = Math.abs(ageDifference.getUTCFullYear() - 1970);
const ageLimit = parseInt(form.getAttribute('ms-code-age-gate').split('-')[1], 10);
if (age >= ageLimit) {
console.log('Age verified.');
errorDiv.style.display = 'none';
localStorage.setItem('ageVerified', 'true');
wrapper.remove();
} else {
console.log('Age verification failed, user is under the age limit.');
errorDiv.style.display = 'block';
}
});
});
</script>

#Nr. 97 - Dateien in S3 Bucket hochladen
Erlauben Sie Uploads zu einem S3-Bucket aus einem Webflow-Formular.
<!-- 💙 MEMBERSCRIPT #97 v0.1 💙 S3 FILE UPLOADS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
document.querySelectorAll('input[ms-code-s3-uploader]').forEach(input => {
input.addEventListener('change', function() {
if (this.files.length > 0) {
const file = this.files[0];
const uuid = generateUUID();
const extension = file.name.split('.').pop();
const newFileName = `${uuid}.${extension}`;
const wrapper = this.closest('div[ms-code-s3-wrapper]');
const s3FileInput = wrapper.querySelector('input[ms-code-s3-file]');
s3FileInput.value = s3FileInput.getAttribute('ms-code-s3-file') + encodeURIComponent(newFileName);
const apiGatewayUrl = wrapper.getAttribute('ms-code-s3-wrapper').replace('${encodeURIComponent(fileName)}', encodeURIComponent(newFileName));
fetch(apiGatewayUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type }
})
.then(response => {
if (response.status !== 200) {
throw new Error(`Upload failed with status: ${response.status}`);
}
console.log('File uploaded successfully:', newFileName);
})
.catch(error => {
console.error('Upload error:', error);
alert('Upload failed.');
});
}
});
});
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', function(event) {
const s3Inputs = Array.from(form.querySelectorAll('input[ms-code-s3-file]'));
const allUrlsSet = s3Inputs.every(input => input.value);
if (!allUrlsSet) {
event.preventDefault();
alert('Please wait for all files to finish uploading before submitting.');
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #97 v0.1 💙 S3 FILE UPLOADS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
document.querySelectorAll('input[ms-code-s3-uploader]').forEach(input => {
input.addEventListener('change', function() {
if (this.files.length > 0) {
const file = this.files[0];
const uuid = generateUUID();
const extension = file.name.split('.').pop();
const newFileName = `${uuid}.${extension}`;
const wrapper = this.closest('div[ms-code-s3-wrapper]');
const s3FileInput = wrapper.querySelector('input[ms-code-s3-file]');
s3FileInput.value = s3FileInput.getAttribute('ms-code-s3-file') + encodeURIComponent(newFileName);
const apiGatewayUrl = wrapper.getAttribute('ms-code-s3-wrapper').replace('${encodeURIComponent(fileName)}', encodeURIComponent(newFileName));
fetch(apiGatewayUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type }
})
.then(response => {
if (response.status !== 200) {
throw new Error(`Upload failed with status: ${response.status}`);
}
console.log('File uploaded successfully:', newFileName);
})
.catch(error => {
console.error('Upload error:', error);
alert('Upload failed.');
});
}
});
});
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', function(event) {
const s3Inputs = Array.from(form.querySelectorAll('input[ms-code-s3-file]'));
const allUrlsSet = s3Inputs.every(input => input.value);
if (!allUrlsSet) {
event.preventDefault();
alert('Please wait for all files to finish uploading before submitting.');
}
});
});
});
</script>

#96 - Strichliste speichern
Erstellen und aktualisieren Sie eine Zählung/Tabelle, die in einem benutzerdefinierten Feld gespeichert wird!
<!-- 💙 MEMBERSCRIPT #96 v0.1 💙 KEEPING A TALLY -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const memberstack = window.$memberstackDom;
const addButtons = document.querySelectorAll("[ms-code-add-tally]");
addButtons.forEach(button => {
button.addEventListener("click", async () => {
const tallyKey = button.getAttribute("ms-code-add-tally");
const tallyText = document.querySelector(`[ms-code-tally="${tallyKey}"]`);
if(tallyText){
let currentCount = parseInt(tallyText.textContent, 10);
currentCount += 1;
tallyText.textContent = currentCount;
// Store the new tally count to Memberstack
let newFields = {};
newFields[tallyKey] = currentCount;
await memberstack.updateMember({customFields: newFields});
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #96 v0.1 💙 KEEPING A TALLY -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const memberstack = window.$memberstackDom;
const addButtons = document.querySelectorAll("[ms-code-add-tally]");
addButtons.forEach(button => {
button.addEventListener("click", async () => {
const tallyKey = button.getAttribute("ms-code-add-tally");
const tallyText = document.querySelector(`[ms-code-tally="${tallyKey}"]`);
if(tallyText){
let currentCount = parseInt(tallyText.textContent, 10);
currentCount += 1;
tallyText.textContent = currentCount;
// Store the new tally count to Memberstack
let newFields = {};
newFields[tallyKey] = currentCount;
await memberstack.updateMember({customFields: newFields});
}
});
});
});
</script>

#95 - Konfetti auf Klick
Lass lustiges Konfetti auf Klick fliegen!
<!-- 💙 MEMBERSCRIPT #95 v0.1 💙 CONFETTI -->
<script src="https://cdn.jsdelivr.net/npm/tsparticles-confetti@2.12.0/tsparticles.confetti.bundle.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const confettiElems = document.querySelectorAll("[ms-code-confetti]");
confettiElems.forEach(item => {
item.addEventListener("click", () => {
const effect = item.getAttribute("ms-code-confetti");
switch (effect) {
case "falling":
const makeFall = () => {
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0 },
colors: ['#ffffff','#ff0000','#00ff00','#0000ff']
});
}
setInterval(makeFall, 2000);
break;
case "single":
confetti({
particleCount: 1,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: Math.random() }
});
break;
case "sides":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0.5 }
});
break;
case "explosions":
confetti({
particleCount: 100,
startVelocity: 50,
spread: 360
});
break;
case "bottom":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: 0.5, y: 1 }
});
break;
default:
console.log("Unknown confetti effect");
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #95 v0.1 💙 CONFETTI -->
<script src="https://cdn.jsdelivr.net/npm/tsparticles-confetti@2.12.0/tsparticles.confetti.bundle.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const confettiElems = document.querySelectorAll("[ms-code-confetti]");
confettiElems.forEach(item => {
item.addEventListener("click", () => {
const effect = item.getAttribute("ms-code-confetti");
switch (effect) {
case "falling":
const makeFall = () => {
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0 },
colors: ['#ffffff','#ff0000','#00ff00','#0000ff']
});
}
setInterval(makeFall, 2000);
break;
case "single":
confetti({
particleCount: 1,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: Math.random() }
});
break;
case "sides":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0.5 }
});
break;
case "explosions":
confetti({
particleCount: 100,
startVelocity: 50,
spread: 360
});
break;
case "bottom":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: 0.5, y: 1 }
});
break;
default:
console.log("Unknown confetti effect");
}
});
});
});
</script>

#94 - href-Attribut setzen
Dynamisches Setzen eines Links über das Webflow CMS (oder etwas anderes)
<!-- 💙 MEMBERSCRIPT #94 v0.1 💙 SET HREF ATTRIBUTE -->
<script>
window.onload = function(){
var elements = document.querySelectorAll('[ms-code-href]');
elements.forEach(function(element) {
var url = element.getAttribute('ms-code-href');
element.setAttribute('href', url);
});
};
</script>
<!-- 💙 MEMBERSCRIPT #94 v0.1 💙 SET HREF ATTRIBUTE -->
<script>
window.onload = function(){
var elements = document.querySelectorAll('[ms-code-href]');
elements.forEach(function(element) {
var url = element.getAttribute('ms-code-href');
element.setAttribute('href', url);
});
};
</script>

#93 - Erzwingen Sie gültige URLs in Formulareingaben
Konvertieren Sie alle Eingaben automatisch in eine gültige URL.
<!-- 💙 MEMBERSCRIPT #93 v0.1 💙 FORCE INPUT TO BE A VALID URL -->
<script>
// Get all form fields with attribute ms-code-convert="link"
const formFields = document.querySelectorAll('input[ms-code-convert="link"], textarea[ms-code-convert="link"]');
// Add event listener to each form field
formFields.forEach((field) => {
field.addEventListener('input', convertToLink);
});
// Function to convert input to a link
function convertToLink(event) {
const input = event.target;
// Get user input
const userInput = input.value.trim();
// Check if input starts with http:// or https://
if (userInput.startsWith('http://') || userInput.startsWith('https://')) {
input.value = userInput; // No conversion needed for valid links
} else {
input.value = `http://${userInput}`; // Prepend http:// for simplicity
}
}
</script>
<!-- 💙 MEMBERSCRIPT #93 v0.1 💙 FORCE INPUT TO BE A VALID URL -->
<script>
// Get all form fields with attribute ms-code-convert="link"
const formFields = document.querySelectorAll('input[ms-code-convert="link"], textarea[ms-code-convert="link"]');
// Add event listener to each form field
formFields.forEach((field) => {
field.addEventListener('input', convertToLink);
});
// Function to convert input to a link
function convertToLink(event) {
const input = event.target;
// Get user input
const userInput = input.value.trim();
// Check if input starts with http:// or https://
if (userInput.startsWith('http://') || userInput.startsWith('https://')) {
input.value = userInput; // No conversion needed for valid links
} else {
input.value = `http://${userInput}`; // Prepend http:// for simplicity
}
}
</script>

#Nr. 92 - Seitenwechsel bei Klick
Ändern Sie die aktuelle Seiten-URL, wenn Sie auf ein beliebiges Element klicken.
<!-- 💙 MEMBERSCRIPT #92 v0.1 💙 TURN ANYTHING INTO A LINK -->
<script>
document.addEventListener('click', function(event) {
let target = event.target;
// Traverse up the DOM tree to find an element with the ms-code-navigate attribute
while (target && !target.getAttribute('ms-code-navigate')) {
target = target.parentElement;
}
// If we found an element with the ms-code-navigate attribute
if (target) {
const navigateUrl = target.getAttribute('ms-code-navigate');
if (navigateUrl) {
event.preventDefault();
// Always open in a new tab
window.open(navigateUrl, '_blank');
}
}
});
</script>
<!-- 💙 MEMBERSCRIPT #92 v0.1 💙 TURN ANYTHING INTO A LINK -->
<script>
document.addEventListener('click', function(event) {
let target = event.target;
// Traverse up the DOM tree to find an element with the ms-code-navigate attribute
while (target && !target.getAttribute('ms-code-navigate')) {
target = target.parentElement;
}
// If we found an element with the ms-code-navigate attribute
if (target) {
const navigateUrl = target.getAttribute('ms-code-navigate');
if (navigateUrl) {
event.preventDefault();
// Always open in a new tab
window.open(navigateUrl, '_blank');
}
}
});
</script>

#91 - Popup für bestimmte Dauer ausblenden
Ausblenden eines Popups für X Zeit, wenn eine Schaltfläche angeklickt wird.
<!-- 💙 MEMBERSCRIPT #91 v0.1 💙 HIDE POPUP FOR SET DURATION -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Look for elements with 'ms-code-hide-popup' attribute
var items = $('[ms-code-hide-popup]');
var button;
var timeElement;
// Determine which element is the button and which is the timer
items.each(function(index, item) {
var value = $(item).attr('ms-code-hide-popup');
if (value === "button") {
button = $(item);
} else {
timeElement = $(item);
}
});
// Calculate the target date
var calculateTargetDate = function(timeStr) {
var splitTime = timeStr.split(':');
var now = new Date();
now.setDate(now.getDate() + parseInt(splitTime[0])); // add days
now.setHours(now.getHours() + parseInt(splitTime[1])); // add hours
now.setMinutes(now.getMinutes() + parseInt(splitTime[2])); // add minutes
now.setSeconds(now.getSeconds() + parseInt(splitTime[3])); // add seconds
return now;
};
// Check if element should be removed from DOM
var checkTimeAndRemoveElement = function() {
var targetDate = localStorage.getItem('targetDate');
if (targetDate && new Date() < new Date(targetDate)) {
timeElement.remove();
} else {
localStorage.removeItem('targetDate');
}
};
// Action on button click
button.on('click', function() {
var time = timeElement.attr('ms-code-hide-popup');
localStorage.setItem('targetDate', calculateTargetDate(time));
checkTimeAndRemoveElement();
});
// Initial check
checkTimeAndRemove AndRemoveElement();
});
</script>
<!-- 💙 MEMBERSCRIPT #91 v0.1 💙 HIDE POPUP FOR SET DURATION -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Look for elements with 'ms-code-hide-popup' attribute
var items = $('[ms-code-hide-popup]');
var button;
var timeElement;
// Determine which element is the button and which is the timer
items.each(function(index, item) {
var value = $(item).attr('ms-code-hide-popup');
if (value === "button") {
button = $(item);
} else {
timeElement = $(item);
}
});
// Calculate the target date
var calculateTargetDate = function(timeStr) {
var splitTime = timeStr.split(':');
var now = new Date();
now.setDate(now.getDate() + parseInt(splitTime[0])); // add days
now.setHours(now.getHours() + parseInt(splitTime[1])); // add hours
now.setMinutes(now.getMinutes() + parseInt(splitTime[2])); // add minutes
now.setSeconds(now.getSeconds() + parseInt(splitTime[3])); // add seconds
return now;
};
// Check if element should be removed from DOM
var checkTimeAndRemoveElement = function() {
var targetDate = localStorage.getItem('targetDate');
if (targetDate && new Date() < new Date(targetDate)) {
timeElement.remove();
} else {
localStorage.removeItem('targetDate');
}
};
// Action on button click
button.on('click', function() {
var time = timeElement.attr('ms-code-hide-popup');
localStorage.setItem('targetDate', calculateTargetDate(time));
checkTimeAndRemoveElement();
});
// Initial check
checkTimeAndRemove AndRemoveElement();
});
</script>

#90 - Elemente bei Eingabeänderung anzeigen
Anzeige von 1 oder mehreren Elementen, wenn ein Benutzer den Eingabewert ändert.
<!-- 💙 MEMBERSCRIPT #90 v0.1 💙 SHOW ELEMENTS ON INPUT CHANGE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Initially hide all elements
$('[ms-code-show-item]').css('display', 'none');
setTimeout(function() {
$('[ms-code-show-field]').change(function() {
var field = $(this).attr('ms-code-show-field');
$('[ms-code-show-item=' + field + ']').css('display', 'block');
});
}, 500); // Wait 500ms before starting, you can change this time based on your needs
});
</script>
<!-- 💙 MEMBERSCRIPT #90 v0.1 💙 SHOW ELEMENTS ON INPUT CHANGE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Initially hide all elements
$('[ms-code-show-item]').css('display', 'none');
setTimeout(function() {
$('[ms-code-show-field]').change(function() {
var field = $(this).attr('ms-code-show-field');
$('[ms-code-show-item=' + field + ']').css('display', 'block');
});
}, 500); // Wait 500ms before starting, you can change this time based on your needs
});
</script>

#Nr. 89 - Benutzerdefinierte Kontextmenüs
Zeigen Sie ein benutzerdefiniertes, integriertes Webflow-Kontextmenü an, wenn Sie mit der rechten Maustaste auf Ihr Element klicken.
<!-- 💙 MEMBERSCRIPT #89 v0.1 💙 CUSTOM CONTEXT MENUS -->
<script>
// Cache elements
const items = document.querySelectorAll("[ms-code-context-item]");
const menus = document.querySelectorAll("[ms-code-context-menu]");
// Disable default context menu on item right click and show custom context menu
items.forEach(element => {
element.addEventListener('contextmenu', event => {
event.preventDefault(); // Prevents showing the default context menu
hideAllMenus(); // Make sure other menus are hidden
// fetch the related menu, make it visible
const menuItemId = element.getAttribute("ms-code-context-item");
const menu = document.querySelector(`[ms-code-context-menu="${menuItemId}"]`);
if (menu) {
menu.classList.remove('hidden');
menu.classList.add('visible');
}
});
});
// Add click event on custom menus to stop event propagation
menus.forEach(menu => {
menu.addEventListener('click', event => {
event.stopPropagation();
});
});
// Close custom context menu on outside click
document.body.addEventListener('click', hideAllMenus);
// Helper function to hide all custom context menus
function hideAllMenus() {
menus.forEach(menu => {
menu.classList.remove('visible');
menu.classList.add('hidden');
});
}
</script>
<!-- 💙 MEMBERSCRIPT #89 v0.1 💙 CUSTOM CONTEXT MENUS -->
<script>
// Cache elements
const items = document.querySelectorAll("[ms-code-context-item]");
const menus = document.querySelectorAll("[ms-code-context-menu]");
// Disable default context menu on item right click and show custom context menu
items.forEach(element => {
element.addEventListener('contextmenu', event => {
event.preventDefault(); // Prevents showing the default context menu
hideAllMenus(); // Make sure other menus are hidden
// fetch the related menu, make it visible
const menuItemId = element.getAttribute("ms-code-context-item");
const menu = document.querySelector(`[ms-code-context-menu="${menuItemId}"]`);
if (menu) {
menu.classList.remove('hidden');
menu.classList.add('visible');
}
});
});
// Add click event on custom menus to stop event propagation
menus.forEach(menu => {
menu.addEventListener('click', event => {
event.stopPropagation();
});
});
// Close custom context menu on outside click
document.body.addEventListener('click', hideAllMenus);
// Helper function to hide all custom context menus
function hideAllMenus() {
menus.forEach(menu => {
menu.classList.remove('visible');
menu.classList.add('hidden');
});
}
</script>

#88 - Aktuellen Status für CMS anzeigen, Ordner-Links
Zeigen Sie den "aktuellen" Webflow-Status auf Ihren verschachtelten Seiten und CMS-Elementen an.
<!-- 💙 MEMBERSCRIPT #88 v0.1 💙 SHOW CURRENT STATE FOR NESTED URLS -->
<script>
window.onload = function() {
var currentUrl = window.location.href;
var elements = document.querySelectorAll('[ms-code-nested-link]'); // get all elements with ms-code-nested-link attribute
elements.forEach(function (element) {
var linkAttrValue = element.getAttribute('ms-code-nested-link'); // get the ms-code-nested-link value
if (currentUrl.includes(linkAttrValue)) { // check if current url matches the attribute value
element.classList.add('w--current'); // apply the class
}
});
};
</script>
<!-- 💙 MEMBERSCRIPT #88 v0.1 💙 SHOW CURRENT STATE FOR NESTED URLS -->
<script>
window.onload = function() {
var currentUrl = window.location.href;
var elements = document.querySelectorAll('[ms-code-nested-link]'); // get all elements with ms-code-nested-link attribute
elements.forEach(function (element) {
var linkAttrValue = element.getAttribute('ms-code-nested-link'); // get the ms-code-nested-link value
if (currentUrl.includes(linkAttrValue)) { // check if current url matches the attribute value
element.classList.add('w--current'); // apply the class
}
});
};
</script>

#Nr. 87 - Einen Plan nach dem Countdown entfernen
Erstellen Sie zeitkritische, sichere Inhalte!
<!-- 💙 MEMBERSCRIPT #87 v0.1 💙 REMOVE PLAN AFTER COUNTDOWN -->
<script>
const memberstack = window.$memberstackDom;
const countdown = new Date(localStorage.getItem('countdownDateTime'));
// Check if date has passed
const checkDate = async () => {
const now = new Date();
if (now > countdown) {
// Remove member's free plan
await memberstack.removePlan({
planId: "pln_10-minutes-of-gif-access-rw1fh0ktg"
});
console.log("Plan removed");
// Reload the page
location.reload();
}
}
// Execute checkDate every 10s
const intervalId = setInterval(checkDate, 10000);
</script>
<!-- 💙 MEMBERSCRIPT #87 v0.1 💙 REMOVE PLAN AFTER COUNTDOWN -->
<script>
const memberstack = window.$memberstackDom;
const countdown = new Date(localStorage.getItem('countdownDateTime'));
// Check if date has passed
const checkDate = async () => {
const now = new Date();
if (now > countdown) {
// Remove member's free plan
await memberstack.removePlan({
planId: "pln_10-minutes-of-gif-access-rw1fh0ktg"
});
console.log("Plan removed");
// Reload the page
location.reload();
}
}
// Execute checkDate every 10s
const intervalId = setInterval(checkDate, 10000);
</script>

#Nr. 86 - Kostenlose und einfache Text-zu-Sprache-Anwendung
Fügen Sie eine Schaltfläche hinzu, mit der Besucher Ihren Artikel anhören können.
<!-- 💙 MEMBERSCRIPT #86 v0.1 💙 VOICE TO TEXT BUTTON -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const textDiv = document.querySelector('[ms-code-text-to-speech="text"]');
const speakButton = document.querySelector('[ms-code-text-to-speech="button"]');
let utterance = new SpeechSynthesisUtterance();
speakButton.addEventListener('click', () => {
if(speechSynthesis.speaking || speechSynthesis.paused) {
speechSynthesis.cancel(); // stops current speech
} else {
utterance.text = textDiv.innerText;
speechSynthesis.speak(utterance); // starts speaking
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #86 v0.1 💙 VOICE TO TEXT BUTTON -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const textDiv = document.querySelector('[ms-code-text-to-speech="text"]');
const speakButton = document.querySelector('[ms-code-text-to-speech="button"]');
let utterance = new SpeechSynthesisUtterance();
speakButton.addEventListener('click', () => {
if(speechSynthesis.speaking || speechSynthesis.paused) {
speechSynthesis.cancel(); // stops current speech
} else {
utterance.text = textDiv.innerText;
speechSynthesis.speak(utterance); // starts speaking
}
});
});
</script>

#Nr. 85 - Formular-Eingaben "Zeile hinzufügen
Erlauben Sie Mitgliedern das Hinzufügen und Löschen von Zeilen aus einer Formulareingabe.
<!-- 💙 MEMBERSCRIPT #85 v0.1 💙 ADD A ROW FORM INPUTS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Hide all rows except the original row
$('[ms-code-row-input="new"]').hide();
// Add row button click event
$('[ms-code-row-input="add-row"]').click(function(e) {
e.preventDefault();
var clonedRow = $('[ms-code-row-input="new"]').first().clone();
clonedRow.find('input').val('');
clonedRow.show().appendTo('[ms-code-row-input="row-container"]');
updateHolderValue();
});
// Delete row button click event
$(document).on('click', '[ms-code-row-input="delete"]', function(e) {
e.preventDefault();
$(this).closest('[ms-code-row-input="new"]').remove();
updateHolderValue();
});
// Event for all inputs
$(document).on('input', '[ms-code-row-input="original"], [ms-code-row-input="new-input"], [ms-code-row-input="holder"]', function() {
if ($(this).is('[ms-code-row-input="holder"]')) {
updateRowsFromHolder();
} else {
updateHolderValue();
}
});
// Function to update the holder input value
function updateHolderValue() {
var values = [];
$('[ms-code-row-input="original"], [ms-code-row-input="new-input"]').each(function() {
var value = $(this).val().trim();
if (value) {
values.push(value);
}
});
$('[ms-code-row-input="holder"]').val(values.join(','));
}
// Function to update rows from the holder field
function updateRowsFromHolder() {
var holderValue = $('[ms-code-row-input="holder"]').val();
var values = holderValue.split(',');
$('[ms-code-row-input="new"]').not(':first').remove();
// For each holder value, create a new row
values.forEach(function(val, idx) {
if (idx === 0) {
$('[ms-code-row-input="original"]').val(val);
} else {
var newRow = $('[ms-code-row-input="new"]').first().clone().appendTo('[ms-code-row-input="row-container"]');
newRow.find('input').val(val);
newRow.show();
}
});
}
// Initial update of the holder input value
updateHolderValue();
// Adding MutationObserver to call updateRowsFromHolder on changes to the holder field
var targetNode = $('[ms-code-row-input="holder"]')[0];
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList')
{
updateRowsFromHolder();
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
</script>
<!-- 💙 MEMBERSCRIPT #85 v0.1 💙 ADD A ROW FORM INPUTS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Hide all rows except the original row
$('[ms-code-row-input="new"]').hide();
// Add row button click event
$('[ms-code-row-input="add-row"]').click(function(e) {
e.preventDefault();
var clonedRow = $('[ms-code-row-input="new"]').first().clone();
clonedRow.find('input').val('');
clonedRow.show().appendTo('[ms-code-row-input="row-container"]');
updateHolderValue();
});
// Delete row button click event
$(document).on('click', '[ms-code-row-input="delete"]', function(e) {
e.preventDefault();
$(this).closest('[ms-code-row-input="new"]').remove();
updateHolderValue();
});
// Event for all inputs
$(document).on('input', '[ms-code-row-input="original"], [ms-code-row-input="new-input"], [ms-code-row-input="holder"]', function() {
if ($(this).is('[ms-code-row-input="holder"]')) {
updateRowsFromHolder();
} else {
updateHolderValue();
}
});
// Function to update the holder input value
function updateHolderValue() {
var values = [];
$('[ms-code-row-input="original"], [ms-code-row-input="new-input"]').each(function() {
var value = $(this).val().trim();
if (value) {
values.push(value);
}
});
$('[ms-code-row-input="holder"]').val(values.join(','));
}
// Function to update rows from the holder field
function updateRowsFromHolder() {
var holderValue = $('[ms-code-row-input="holder"]').val();
var values = holderValue.split(',');
$('[ms-code-row-input="new"]').not(':first').remove();
// For each holder value, create a new row
values.forEach(function(val, idx) {
if (idx === 0) {
$('[ms-code-row-input="original"]').val(val);
} else {
var newRow = $('[ms-code-row-input="new"]').first().clone().appendTo('[ms-code-row-input="row-container"]');
newRow.find('input').val(val);
newRow.show();
}
});
}
// Initial update of the holder input value
updateHolderValue();
// Adding MutationObserver to call updateRowsFromHolder on changes to the holder field
var targetNode = $('[ms-code-row-input="holder"]')[0];
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList')
{
updateRowsFromHolder();
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
</script>

#Nr. 84 - Eingänge löschen OnLoad
Fügen Sie dieses Skript einer beliebigen Seite hinzu, um den Wert eines benutzerdefinierten Feldes beim Laden der Seite zu löschen.
<!-- 💙 MEMBERSCRIPT #84 v0.1 💙 CLEAR INPUT VALUES ONLOAD -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const fieldsToClear = ["phone", "last-name"]; // Specify the fields to clear
// Clear inputs and Memberstack fields on page load
memberstack.getCurrentMember().then(async ({ data: member }) => {
if (member) {
const customFieldsToUpdate = {};
fieldsToClear.forEach(fieldName => {
customFieldsToUpdate[fieldName] = '';
});
try {
await memberstack.updateMember({
customFields: customFieldsToUpdate
});
console.log("Fields cleared on page load.");
} catch (error) {
console.error('Error clearing fields on page load:', error);
}
}
// Clear input values on page load for specified fields
fieldsToClear.forEach(fieldName => {
const inputField = document.querySelector(`[data-ms-member="${fieldName}"]`);
if (inputField) {
inputField.value = '';
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #84 v0.1 💙 CLEAR INPUT VALUES ONLOAD -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const fieldsToClear = ["phone", "last-name"]; // Specify the fields to clear
// Clear inputs and Memberstack fields on page load
memberstack.getCurrentMember().then(async ({ data: member }) => {
if (member) {
const customFieldsToUpdate = {};
fieldsToClear.forEach(fieldName => {
customFieldsToUpdate[fieldName] = '';
});
try {
await memberstack.updateMember({
customFields: customFieldsToUpdate
});
console.log("Fields cleared on page load.");
} catch (error) {
console.error('Error clearing fields on page load:', error);
}
}
// Clear input values on page load for specified fields
fieldsToClear.forEach(fieldName => {
const inputField = document.querySelector(`[data-ms-member="${fieldName}"]`);
if (inputField) {
inputField.value = '';
}
});
});
});
</script>

#83 - Geräteübergreifende Cookie-Einstellungen
Erlauben Sie Mitgliedern, ihre Cookie-Einstellungen in ihrem Konto zu speichern.
<!-- 💙 MEMBERSCRIPT #83 v0.1 💙 CROSS-DEVICE COOKIE PREFERENCES -->
<script>
// Function to retrieve a cookie value by name
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
}
async function updateMemberConsentPreferences(fsCcCookieValue) {
try {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
if (!userData.data.customFields['cookie-consent']) {
const decodedFsCcCookieValue = decodeURIComponent(fsCcCookieValue);
await memberstack.updateMember({
customFields: {
'cookie-consent': decodedFsCcCookieValue
}
});
} else {
document.cookie = `fs-cc=${encodeURIComponent(userData.data.customFields['cookie-consent'])}`;
}
}
} catch (error) {}
}
async function initialize() {
const fsCcCookieValue = getCookie('fs-cc');
if (fsCcCookieValue) {
await updateMemberConsentPreferences(fsCcCookieValue);
const checkboxes = document.querySelectorAll('[fs-cc-checkbox]');
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', async () => {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
const customFieldKey = 'cookie-consent';
const checkboxName = checkbox.getAttribute('fs-cc-checkbox');
if (userData.data.customFields[customFieldKey]) {
const consentData = JSON.parse(userData.data.customFields[customFieldKey]);
consentData.consents[checkboxName] = checkbox.checked;
const updatedCustomField = JSON.stringify(consentData);
await memberstack.updateMember({
customFields: {
[customFieldKey]: updatedCustomField
}
});
document.cookie = `fs-cc=${encodeURIComponent(updatedCustomField)}`;
}
}
});
});
}
}
// Initialize the script
initialize();
</script>
<!-- 💙 MEMBERSCRIPT #83 v0.1 💙 CROSS-DEVICE COOKIE PREFERENCES -->
<script>
// Function to retrieve a cookie value by name
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
}
async function updateMemberConsentPreferences(fsCcCookieValue) {
try {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
if (!userData.data.customFields['cookie-consent']) {
const decodedFsCcCookieValue = decodeURIComponent(fsCcCookieValue);
await memberstack.updateMember({
customFields: {
'cookie-consent': decodedFsCcCookieValue
}
});
} else {
document.cookie = `fs-cc=${encodeURIComponent(userData.data.customFields['cookie-consent'])}`;
}
}
} catch (error) {}
}
async function initialize() {
const fsCcCookieValue = getCookie('fs-cc');
if (fsCcCookieValue) {
await updateMemberConsentPreferences(fsCcCookieValue);
const checkboxes = document.querySelectorAll('[fs-cc-checkbox]');
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', async () => {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
const customFieldKey = 'cookie-consent';
const checkboxName = checkbox.getAttribute('fs-cc-checkbox');
if (userData.data.customFields[customFieldKey]) {
const consentData = JSON.parse(userData.data.customFields[customFieldKey]);
consentData.consents[checkboxName] = checkbox.checked;
const updatedCustomField = JSON.stringify(consentData);
await memberstack.updateMember({
customFields: {
[customFieldKey]: updatedCustomField
}
});
document.cookie = `fs-cc=${encodeURIComponent(updatedCustomField)}`;
}
}
});
});
}
}
// Initialize the script
initialize();
</script>

#Nr. 82 - Lizenzschlüssel
Sichern Sie Ihre herunterladbaren Inhalte mit Lizenzschlüsseln.
<!-- 💙 MEMBERSCRIPT #82 v0.1 💙 LICENSE KEYS -->
<script>
const memberstack = window.$memberstackDom;
// Initialize MutationObserver
const observer = new MutationObserver(async (mutations) => {
const downloadBtn = document.getElementById("download");
if (downloadBtn) {
// Element exists, so add event listener
downloadBtn.addEventListener("click", async () => {
await memberstack.removePlan({
planId: "pln_activate-license-key-952c0d8u"
});
console.log("Plan removed");
});
// Stop observing since we found the element
observer.disconnect();
}
});
// Observe the whole document
observer.observe(document.body, { childList: true, subtree: true });
</script>
<!-- 💙 MEMBERSCRIPT #82 v0.1 💙 LICENSE KEYS -->
<script>
const memberstack = window.$memberstackDom;
// Initialize MutationObserver
const observer = new MutationObserver(async (mutations) => {
const downloadBtn = document.getElementById("download");
if (downloadBtn) {
// Element exists, so add event listener
downloadBtn.addEventListener("click", async () => {
await memberstack.removePlan({
planId: "pln_activate-license-key-952c0d8u"
});
console.log("Plan removed");
});
// Stop observing since we found the element
observer.disconnect();
}
});
// Observe the whole document
observer.observe(document.body, { childList: true, subtree: true });
</script>

#Nr. 81 - Benutzerdefinierte Kontrollkästchenwerte
Geben Sie einen eindeutigen Wert durch, je nachdem, ob das Kästchen angekreuzt ist oder nicht.
<!-- 💙 MEMBERSCRIPT #81 v0.1 💙 CUSTOM CHECKBOX VALUES -->
<script>
document.addEventListener('submit', function(e) {
var checkboxes = document.querySelectorAll('[ms-code-custom-checkbox]');
checkboxes.forEach(function(checkbox) {
var values = checkbox.getAttribute('ms-code-custom-checkbox').split(',');
var valueToSubmit = checkbox.checked ? values[0] : values[1];
var hiddenInput = document.createElement('input');
// Copy all attributes except type and ms-code-custom-checkbox
for (var i = 0; i < checkbox.attributes.length; i++) {
var attr = checkbox.attributes[i];
if (attr.name !== 'type' && attr.name !== 'ms-code-custom-checkbox') {
hiddenInput.setAttribute(attr.name, attr.value);
}
}
hiddenInput.type = 'hidden';
hiddenInput.value = valueToSubmit;
checkbox.form.appendChild(hiddenInput);
checkbox.remove(); // Remove the original checkbox so it doesn't interfere with submission
});
});
</script>
<!-- 💙 MEMBERSCRIPT #81 v0.1 💙 CUSTOM CHECKBOX VALUES -->
<script>
document.addEventListener('submit', function(e) {
var checkboxes = document.querySelectorAll('[ms-code-custom-checkbox]');
checkboxes.forEach(function(checkbox) {
var values = checkbox.getAttribute('ms-code-custom-checkbox').split(',');
var valueToSubmit = checkbox.checked ? values[0] : values[1];
var hiddenInput = document.createElement('input');
// Copy all attributes except type and ms-code-custom-checkbox
for (var i = 0; i < checkbox.attributes.length; i++) {
var attr = checkbox.attributes[i];
if (attr.name !== 'type' && attr.name !== 'ms-code-custom-checkbox') {
hiddenInput.setAttribute(attr.name, attr.value);
}
}
hiddenInput.type = 'hidden';
hiddenInput.value = valueToSubmit;
checkbox.form.appendChild(hiddenInput);
checkbox.remove(); // Remove the original checkbox so it doesn't interfere with submission
});
});
</script>

#Nr. 80 - Benachrichtigung über stornierte Pläne
Lösen Sie eine Slack-Benachrichtigung aus, wenn ein Mitglied seinen Plan kündigt.

#79 - Auslöser Click onHover
Auslösen eines Klick-Ereignisses onHover.
<!-- 💙 MEMBERSCRIPT #79 v0.1 💙 HOVER BASED TABS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const hoverTabElements = document.querySelectorAll('[ms-code-onhover="click"]');
hoverTabElements.forEach(hoverTabElement => {
hoverTabElement.addEventListener('mouseenter', function() {
hoverTabElement.click(); // Click on the element when hovering
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #79 v0.1 💙 HOVER BASED TABS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const hoverTabElements = document.querySelectorAll('[ms-code-onhover="click"]');
hoverTabElements.forEach(hoverTabElement => {
hoverTabElement.addEventListener('mouseenter', function() {
hoverTabElement.click(); // Click on the element when hovering
});
});
});
</script>
Mitglieder-Skripte
Instantly add custom features to your Webflow site.
Just paste a script, set attributes, and go live.
Join the Memberstack 2.0 Slack for tips, answers, and community scripts. Please note that these are not official features and support cannot be guaranteed.

#98 - Altersfreigabe
Die Benutzer müssen ihr Alter bestätigen, bevor sie fortfahren.
<!-- 💙 MEMBERSCRIPT #98 v0.1 💙 AGE GATE -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const form = document.querySelector('form[ms-code-age-gate]');
const dayInput = document.querySelector('input[ms-code-age-gate="day"]');
const monthInput = document.querySelector('input[ms-code-age-gate="month"]');
const yearInput = document.querySelector('input[ms-code-age-gate="year"]');
const backButton = document.querySelector('a[ms-code-age-gate="back"]');
const wrapper = document.querySelector('[ms-code-age-gate="wrapper"]');
const errorDiv = document.querySelector('div[ms-code-age-gate="error"]');
if (localStorage.getItem('ageVerified') === 'true') {
wrapper.remove();
return;
}
backButton.addEventListener('click', (e) => {
e.preventDefault();
window.history.back();
});
const inputs = [dayInput, monthInput, yearInput];
inputs.forEach((input, index) => {
input.addEventListener('keyup', (e) => {
const maxChars = input === yearInput ? 4 : 2;
let value = e.target.value;
if (input === dayInput && value.length === maxChars) {
value = value > 31 ? '31' : value.padStart(2, '0');
} else if (input === monthInput && value.length === maxChars) {
value = value > 12 ? '12' : value.padStart(2, '0');
}
e.target.value = value;
if (value.length === maxChars) {
const nextInput = inputs[index + 1];
if (nextInput) {
nextInput.focus();
}
}
});
});
form.addEventListener('submit', (e) => {
e.preventDefault();
const enteredDate = new Date(yearInput.value, monthInput.value - 1, dayInput.value);
const currentDate = new Date();
const ageDifference = new Date(currentDate - enteredDate);
const age = Math.abs(ageDifference.getUTCFullYear() - 1970);
const ageLimit = parseInt(form.getAttribute('ms-code-age-gate').split('-')[1], 10);
if (age >= ageLimit) {
console.log('Age verified.');
errorDiv.style.display = 'none';
localStorage.setItem('ageVerified', 'true');
wrapper.remove();
} else {
console.log('Age verification failed, user is under the age limit.');
errorDiv.style.display = 'block';
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #98 v0.1 💙 AGE GATE -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const form = document.querySelector('form[ms-code-age-gate]');
const dayInput = document.querySelector('input[ms-code-age-gate="day"]');
const monthInput = document.querySelector('input[ms-code-age-gate="month"]');
const yearInput = document.querySelector('input[ms-code-age-gate="year"]');
const backButton = document.querySelector('a[ms-code-age-gate="back"]');
const wrapper = document.querySelector('[ms-code-age-gate="wrapper"]');
const errorDiv = document.querySelector('div[ms-code-age-gate="error"]');
if (localStorage.getItem('ageVerified') === 'true') {
wrapper.remove();
return;
}
backButton.addEventListener('click', (e) => {
e.preventDefault();
window.history.back();
});
const inputs = [dayInput, monthInput, yearInput];
inputs.forEach((input, index) => {
input.addEventListener('keyup', (e) => {
const maxChars = input === yearInput ? 4 : 2;
let value = e.target.value;
if (input === dayInput && value.length === maxChars) {
value = value > 31 ? '31' : value.padStart(2, '0');
} else if (input === monthInput && value.length === maxChars) {
value = value > 12 ? '12' : value.padStart(2, '0');
}
e.target.value = value;
if (value.length === maxChars) {
const nextInput = inputs[index + 1];
if (nextInput) {
nextInput.focus();
}
}
});
});
form.addEventListener('submit', (e) => {
e.preventDefault();
const enteredDate = new Date(yearInput.value, monthInput.value - 1, dayInput.value);
const currentDate = new Date();
const ageDifference = new Date(currentDate - enteredDate);
const age = Math.abs(ageDifference.getUTCFullYear() - 1970);
const ageLimit = parseInt(form.getAttribute('ms-code-age-gate').split('-')[1], 10);
if (age >= ageLimit) {
console.log('Age verified.');
errorDiv.style.display = 'none';
localStorage.setItem('ageVerified', 'true');
wrapper.remove();
} else {
console.log('Age verification failed, user is under the age limit.');
errorDiv.style.display = 'block';
}
});
});
</script>

#Nr. 97 - Dateien in S3 Bucket hochladen
Erlauben Sie Uploads zu einem S3-Bucket aus einem Webflow-Formular.
<!-- 💙 MEMBERSCRIPT #97 v0.1 💙 S3 FILE UPLOADS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
document.querySelectorAll('input[ms-code-s3-uploader]').forEach(input => {
input.addEventListener('change', function() {
if (this.files.length > 0) {
const file = this.files[0];
const uuid = generateUUID();
const extension = file.name.split('.').pop();
const newFileName = `${uuid}.${extension}`;
const wrapper = this.closest('div[ms-code-s3-wrapper]');
const s3FileInput = wrapper.querySelector('input[ms-code-s3-file]');
s3FileInput.value = s3FileInput.getAttribute('ms-code-s3-file') + encodeURIComponent(newFileName);
const apiGatewayUrl = wrapper.getAttribute('ms-code-s3-wrapper').replace('${encodeURIComponent(fileName)}', encodeURIComponent(newFileName));
fetch(apiGatewayUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type }
})
.then(response => {
if (response.status !== 200) {
throw new Error(`Upload failed with status: ${response.status}`);
}
console.log('File uploaded successfully:', newFileName);
})
.catch(error => {
console.error('Upload error:', error);
alert('Upload failed.');
});
}
});
});
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', function(event) {
const s3Inputs = Array.from(form.querySelectorAll('input[ms-code-s3-file]'));
const allUrlsSet = s3Inputs.every(input => input.value);
if (!allUrlsSet) {
event.preventDefault();
alert('Please wait for all files to finish uploading before submitting.');
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #97 v0.1 💙 S3 FILE UPLOADS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
document.querySelectorAll('input[ms-code-s3-uploader]').forEach(input => {
input.addEventListener('change', function() {
if (this.files.length > 0) {
const file = this.files[0];
const uuid = generateUUID();
const extension = file.name.split('.').pop();
const newFileName = `${uuid}.${extension}`;
const wrapper = this.closest('div[ms-code-s3-wrapper]');
const s3FileInput = wrapper.querySelector('input[ms-code-s3-file]');
s3FileInput.value = s3FileInput.getAttribute('ms-code-s3-file') + encodeURIComponent(newFileName);
const apiGatewayUrl = wrapper.getAttribute('ms-code-s3-wrapper').replace('${encodeURIComponent(fileName)}', encodeURIComponent(newFileName));
fetch(apiGatewayUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': file.type }
})
.then(response => {
if (response.status !== 200) {
throw new Error(`Upload failed with status: ${response.status}`);
}
console.log('File uploaded successfully:', newFileName);
})
.catch(error => {
console.error('Upload error:', error);
alert('Upload failed.');
});
}
});
});
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', function(event) {
const s3Inputs = Array.from(form.querySelectorAll('input[ms-code-s3-file]'));
const allUrlsSet = s3Inputs.every(input => input.value);
if (!allUrlsSet) {
event.preventDefault();
alert('Please wait for all files to finish uploading before submitting.');
}
});
});
});
</script>

#96 - Strichliste speichern
Erstellen und aktualisieren Sie eine Zählung/Tabelle, die in einem benutzerdefinierten Feld gespeichert wird!
<!-- 💙 MEMBERSCRIPT #96 v0.1 💙 KEEPING A TALLY -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const memberstack = window.$memberstackDom;
const addButtons = document.querySelectorAll("[ms-code-add-tally]");
addButtons.forEach(button => {
button.addEventListener("click", async () => {
const tallyKey = button.getAttribute("ms-code-add-tally");
const tallyText = document.querySelector(`[ms-code-tally="${tallyKey}"]`);
if(tallyText){
let currentCount = parseInt(tallyText.textContent, 10);
currentCount += 1;
tallyText.textContent = currentCount;
// Store the new tally count to Memberstack
let newFields = {};
newFields[tallyKey] = currentCount;
await memberstack.updateMember({customFields: newFields});
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #96 v0.1 💙 KEEPING A TALLY -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const memberstack = window.$memberstackDom;
const addButtons = document.querySelectorAll("[ms-code-add-tally]");
addButtons.forEach(button => {
button.addEventListener("click", async () => {
const tallyKey = button.getAttribute("ms-code-add-tally");
const tallyText = document.querySelector(`[ms-code-tally="${tallyKey}"]`);
if(tallyText){
let currentCount = parseInt(tallyText.textContent, 10);
currentCount += 1;
tallyText.textContent = currentCount;
// Store the new tally count to Memberstack
let newFields = {};
newFields[tallyKey] = currentCount;
await memberstack.updateMember({customFields: newFields});
}
});
});
});
</script>

#95 - Konfetti auf Klick
Lass lustiges Konfetti auf Klick fliegen!
<!-- 💙 MEMBERSCRIPT #95 v0.1 💙 CONFETTI -->
<script src="https://cdn.jsdelivr.net/npm/tsparticles-confetti@2.12.0/tsparticles.confetti.bundle.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const confettiElems = document.querySelectorAll("[ms-code-confetti]");
confettiElems.forEach(item => {
item.addEventListener("click", () => {
const effect = item.getAttribute("ms-code-confetti");
switch (effect) {
case "falling":
const makeFall = () => {
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0 },
colors: ['#ffffff','#ff0000','#00ff00','#0000ff']
});
}
setInterval(makeFall, 2000);
break;
case "single":
confetti({
particleCount: 1,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: Math.random() }
});
break;
case "sides":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0.5 }
});
break;
case "explosions":
confetti({
particleCount: 100,
startVelocity: 50,
spread: 360
});
break;
case "bottom":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: 0.5, y: 1 }
});
break;
default:
console.log("Unknown confetti effect");
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #95 v0.1 💙 CONFETTI -->
<script src="https://cdn.jsdelivr.net/npm/tsparticles-confetti@2.12.0/tsparticles.confetti.bundle.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const confettiElems = document.querySelectorAll("[ms-code-confetti]");
confettiElems.forEach(item => {
item.addEventListener("click", () => {
const effect = item.getAttribute("ms-code-confetti");
switch (effect) {
case "falling":
const makeFall = () => {
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0 },
colors: ['#ffffff','#ff0000','#00ff00','#0000ff']
});
}
setInterval(makeFall, 2000);
break;
case "single":
confetti({
particleCount: 1,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: Math.random() }
});
break;
case "sides":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: Math.random(), y: 0.5 }
});
break;
case "explosions":
confetti({
particleCount: 100,
startVelocity: 50,
spread: 360
});
break;
case "bottom":
confetti({
particleCount: 100,
startVelocity: 30,
spread: 360,
origin: { x: 0.5, y: 1 }
});
break;
default:
console.log("Unknown confetti effect");
}
});
});
});
</script>

#94 - href-Attribut setzen
Dynamisches Setzen eines Links über das Webflow CMS (oder etwas anderes)
<!-- 💙 MEMBERSCRIPT #94 v0.1 💙 SET HREF ATTRIBUTE -->
<script>
window.onload = function(){
var elements = document.querySelectorAll('[ms-code-href]');
elements.forEach(function(element) {
var url = element.getAttribute('ms-code-href');
element.setAttribute('href', url);
});
};
</script>
<!-- 💙 MEMBERSCRIPT #94 v0.1 💙 SET HREF ATTRIBUTE -->
<script>
window.onload = function(){
var elements = document.querySelectorAll('[ms-code-href]');
elements.forEach(function(element) {
var url = element.getAttribute('ms-code-href');
element.setAttribute('href', url);
});
};
</script>

#93 - Erzwingen Sie gültige URLs in Formulareingaben
Konvertieren Sie alle Eingaben automatisch in eine gültige URL.
<!-- 💙 MEMBERSCRIPT #93 v0.1 💙 FORCE INPUT TO BE A VALID URL -->
<script>
// Get all form fields with attribute ms-code-convert="link"
const formFields = document.querySelectorAll('input[ms-code-convert="link"], textarea[ms-code-convert="link"]');
// Add event listener to each form field
formFields.forEach((field) => {
field.addEventListener('input', convertToLink);
});
// Function to convert input to a link
function convertToLink(event) {
const input = event.target;
// Get user input
const userInput = input.value.trim();
// Check if input starts with http:// or https://
if (userInput.startsWith('http://') || userInput.startsWith('https://')) {
input.value = userInput; // No conversion needed for valid links
} else {
input.value = `http://${userInput}`; // Prepend http:// for simplicity
}
}
</script>
<!-- 💙 MEMBERSCRIPT #93 v0.1 💙 FORCE INPUT TO BE A VALID URL -->
<script>
// Get all form fields with attribute ms-code-convert="link"
const formFields = document.querySelectorAll('input[ms-code-convert="link"], textarea[ms-code-convert="link"]');
// Add event listener to each form field
formFields.forEach((field) => {
field.addEventListener('input', convertToLink);
});
// Function to convert input to a link
function convertToLink(event) {
const input = event.target;
// Get user input
const userInput = input.value.trim();
// Check if input starts with http:// or https://
if (userInput.startsWith('http://') || userInput.startsWith('https://')) {
input.value = userInput; // No conversion needed for valid links
} else {
input.value = `http://${userInput}`; // Prepend http:// for simplicity
}
}
</script>

#Nr. 92 - Seitenwechsel bei Klick
Ändern Sie die aktuelle Seiten-URL, wenn Sie auf ein beliebiges Element klicken.
<!-- 💙 MEMBERSCRIPT #92 v0.1 💙 TURN ANYTHING INTO A LINK -->
<script>
document.addEventListener('click', function(event) {
let target = event.target;
// Traverse up the DOM tree to find an element with the ms-code-navigate attribute
while (target && !target.getAttribute('ms-code-navigate')) {
target = target.parentElement;
}
// If we found an element with the ms-code-navigate attribute
if (target) {
const navigateUrl = target.getAttribute('ms-code-navigate');
if (navigateUrl) {
event.preventDefault();
// Always open in a new tab
window.open(navigateUrl, '_blank');
}
}
});
</script>
<!-- 💙 MEMBERSCRIPT #92 v0.1 💙 TURN ANYTHING INTO A LINK -->
<script>
document.addEventListener('click', function(event) {
let target = event.target;
// Traverse up the DOM tree to find an element with the ms-code-navigate attribute
while (target && !target.getAttribute('ms-code-navigate')) {
target = target.parentElement;
}
// If we found an element with the ms-code-navigate attribute
if (target) {
const navigateUrl = target.getAttribute('ms-code-navigate');
if (navigateUrl) {
event.preventDefault();
// Always open in a new tab
window.open(navigateUrl, '_blank');
}
}
});
</script>

#91 - Popup für bestimmte Dauer ausblenden
Ausblenden eines Popups für X Zeit, wenn eine Schaltfläche angeklickt wird.
<!-- 💙 MEMBERSCRIPT #91 v0.1 💙 HIDE POPUP FOR SET DURATION -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Look for elements with 'ms-code-hide-popup' attribute
var items = $('[ms-code-hide-popup]');
var button;
var timeElement;
// Determine which element is the button and which is the timer
items.each(function(index, item) {
var value = $(item).attr('ms-code-hide-popup');
if (value === "button") {
button = $(item);
} else {
timeElement = $(item);
}
});
// Calculate the target date
var calculateTargetDate = function(timeStr) {
var splitTime = timeStr.split(':');
var now = new Date();
now.setDate(now.getDate() + parseInt(splitTime[0])); // add days
now.setHours(now.getHours() + parseInt(splitTime[1])); // add hours
now.setMinutes(now.getMinutes() + parseInt(splitTime[2])); // add minutes
now.setSeconds(now.getSeconds() + parseInt(splitTime[3])); // add seconds
return now;
};
// Check if element should be removed from DOM
var checkTimeAndRemoveElement = function() {
var targetDate = localStorage.getItem('targetDate');
if (targetDate && new Date() < new Date(targetDate)) {
timeElement.remove();
} else {
localStorage.removeItem('targetDate');
}
};
// Action on button click
button.on('click', function() {
var time = timeElement.attr('ms-code-hide-popup');
localStorage.setItem('targetDate', calculateTargetDate(time));
checkTimeAndRemoveElement();
});
// Initial check
checkTimeAndRemove AndRemoveElement();
});
</script>
<!-- 💙 MEMBERSCRIPT #91 v0.1 💙 HIDE POPUP FOR SET DURATION -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Look for elements with 'ms-code-hide-popup' attribute
var items = $('[ms-code-hide-popup]');
var button;
var timeElement;
// Determine which element is the button and which is the timer
items.each(function(index, item) {
var value = $(item).attr('ms-code-hide-popup');
if (value === "button") {
button = $(item);
} else {
timeElement = $(item);
}
});
// Calculate the target date
var calculateTargetDate = function(timeStr) {
var splitTime = timeStr.split(':');
var now = new Date();
now.setDate(now.getDate() + parseInt(splitTime[0])); // add days
now.setHours(now.getHours() + parseInt(splitTime[1])); // add hours
now.setMinutes(now.getMinutes() + parseInt(splitTime[2])); // add minutes
now.setSeconds(now.getSeconds() + parseInt(splitTime[3])); // add seconds
return now;
};
// Check if element should be removed from DOM
var checkTimeAndRemoveElement = function() {
var targetDate = localStorage.getItem('targetDate');
if (targetDate && new Date() < new Date(targetDate)) {
timeElement.remove();
} else {
localStorage.removeItem('targetDate');
}
};
// Action on button click
button.on('click', function() {
var time = timeElement.attr('ms-code-hide-popup');
localStorage.setItem('targetDate', calculateTargetDate(time));
checkTimeAndRemoveElement();
});
// Initial check
checkTimeAndRemove AndRemoveElement();
});
</script>

#90 - Elemente bei Eingabeänderung anzeigen
Anzeige von 1 oder mehreren Elementen, wenn ein Benutzer den Eingabewert ändert.
<!-- 💙 MEMBERSCRIPT #90 v0.1 💙 SHOW ELEMENTS ON INPUT CHANGE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Initially hide all elements
$('[ms-code-show-item]').css('display', 'none');
setTimeout(function() {
$('[ms-code-show-field]').change(function() {
var field = $(this).attr('ms-code-show-field');
$('[ms-code-show-item=' + field + ']').css('display', 'block');
});
}, 500); // Wait 500ms before starting, you can change this time based on your needs
});
</script>
<!-- 💙 MEMBERSCRIPT #90 v0.1 💙 SHOW ELEMENTS ON INPUT CHANGE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// Initially hide all elements
$('[ms-code-show-item]').css('display', 'none');
setTimeout(function() {
$('[ms-code-show-field]').change(function() {
var field = $(this).attr('ms-code-show-field');
$('[ms-code-show-item=' + field + ']').css('display', 'block');
});
}, 500); // Wait 500ms before starting, you can change this time based on your needs
});
</script>

#Nr. 89 - Benutzerdefinierte Kontextmenüs
Zeigen Sie ein benutzerdefiniertes, integriertes Webflow-Kontextmenü an, wenn Sie mit der rechten Maustaste auf Ihr Element klicken.
<!-- 💙 MEMBERSCRIPT #89 v0.1 💙 CUSTOM CONTEXT MENUS -->
<script>
// Cache elements
const items = document.querySelectorAll("[ms-code-context-item]");
const menus = document.querySelectorAll("[ms-code-context-menu]");
// Disable default context menu on item right click and show custom context menu
items.forEach(element => {
element.addEventListener('contextmenu', event => {
event.preventDefault(); // Prevents showing the default context menu
hideAllMenus(); // Make sure other menus are hidden
// fetch the related menu, make it visible
const menuItemId = element.getAttribute("ms-code-context-item");
const menu = document.querySelector(`[ms-code-context-menu="${menuItemId}"]`);
if (menu) {
menu.classList.remove('hidden');
menu.classList.add('visible');
}
});
});
// Add click event on custom menus to stop event propagation
menus.forEach(menu => {
menu.addEventListener('click', event => {
event.stopPropagation();
});
});
// Close custom context menu on outside click
document.body.addEventListener('click', hideAllMenus);
// Helper function to hide all custom context menus
function hideAllMenus() {
menus.forEach(menu => {
menu.classList.remove('visible');
menu.classList.add('hidden');
});
}
</script>
<!-- 💙 MEMBERSCRIPT #89 v0.1 💙 CUSTOM CONTEXT MENUS -->
<script>
// Cache elements
const items = document.querySelectorAll("[ms-code-context-item]");
const menus = document.querySelectorAll("[ms-code-context-menu]");
// Disable default context menu on item right click and show custom context menu
items.forEach(element => {
element.addEventListener('contextmenu', event => {
event.preventDefault(); // Prevents showing the default context menu
hideAllMenus(); // Make sure other menus are hidden
// fetch the related menu, make it visible
const menuItemId = element.getAttribute("ms-code-context-item");
const menu = document.querySelector(`[ms-code-context-menu="${menuItemId}"]`);
if (menu) {
menu.classList.remove('hidden');
menu.classList.add('visible');
}
});
});
// Add click event on custom menus to stop event propagation
menus.forEach(menu => {
menu.addEventListener('click', event => {
event.stopPropagation();
});
});
// Close custom context menu on outside click
document.body.addEventListener('click', hideAllMenus);
// Helper function to hide all custom context menus
function hideAllMenus() {
menus.forEach(menu => {
menu.classList.remove('visible');
menu.classList.add('hidden');
});
}
</script>

#88 - Aktuellen Status für CMS anzeigen, Ordner-Links
Zeigen Sie den "aktuellen" Webflow-Status auf Ihren verschachtelten Seiten und CMS-Elementen an.
<!-- 💙 MEMBERSCRIPT #88 v0.1 💙 SHOW CURRENT STATE FOR NESTED URLS -->
<script>
window.onload = function() {
var currentUrl = window.location.href;
var elements = document.querySelectorAll('[ms-code-nested-link]'); // get all elements with ms-code-nested-link attribute
elements.forEach(function (element) {
var linkAttrValue = element.getAttribute('ms-code-nested-link'); // get the ms-code-nested-link value
if (currentUrl.includes(linkAttrValue)) { // check if current url matches the attribute value
element.classList.add('w--current'); // apply the class
}
});
};
</script>
<!-- 💙 MEMBERSCRIPT #88 v0.1 💙 SHOW CURRENT STATE FOR NESTED URLS -->
<script>
window.onload = function() {
var currentUrl = window.location.href;
var elements = document.querySelectorAll('[ms-code-nested-link]'); // get all elements with ms-code-nested-link attribute
elements.forEach(function (element) {
var linkAttrValue = element.getAttribute('ms-code-nested-link'); // get the ms-code-nested-link value
if (currentUrl.includes(linkAttrValue)) { // check if current url matches the attribute value
element.classList.add('w--current'); // apply the class
}
});
};
</script>

#Nr. 87 - Einen Plan nach dem Countdown entfernen
Erstellen Sie zeitkritische, sichere Inhalte!
<!-- 💙 MEMBERSCRIPT #87 v0.1 💙 REMOVE PLAN AFTER COUNTDOWN -->
<script>
const memberstack = window.$memberstackDom;
const countdown = new Date(localStorage.getItem('countdownDateTime'));
// Check if date has passed
const checkDate = async () => {
const now = new Date();
if (now > countdown) {
// Remove member's free plan
await memberstack.removePlan({
planId: "pln_10-minutes-of-gif-access-rw1fh0ktg"
});
console.log("Plan removed");
// Reload the page
location.reload();
}
}
// Execute checkDate every 10s
const intervalId = setInterval(checkDate, 10000);
</script>
<!-- 💙 MEMBERSCRIPT #87 v0.1 💙 REMOVE PLAN AFTER COUNTDOWN -->
<script>
const memberstack = window.$memberstackDom;
const countdown = new Date(localStorage.getItem('countdownDateTime'));
// Check if date has passed
const checkDate = async () => {
const now = new Date();
if (now > countdown) {
// Remove member's free plan
await memberstack.removePlan({
planId: "pln_10-minutes-of-gif-access-rw1fh0ktg"
});
console.log("Plan removed");
// Reload the page
location.reload();
}
}
// Execute checkDate every 10s
const intervalId = setInterval(checkDate, 10000);
</script>

#Nr. 86 - Kostenlose und einfache Text-zu-Sprache-Anwendung
Fügen Sie eine Schaltfläche hinzu, mit der Besucher Ihren Artikel anhören können.
<!-- 💙 MEMBERSCRIPT #86 v0.1 💙 VOICE TO TEXT BUTTON -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const textDiv = document.querySelector('[ms-code-text-to-speech="text"]');
const speakButton = document.querySelector('[ms-code-text-to-speech="button"]');
let utterance = new SpeechSynthesisUtterance();
speakButton.addEventListener('click', () => {
if(speechSynthesis.speaking || speechSynthesis.paused) {
speechSynthesis.cancel(); // stops current speech
} else {
utterance.text = textDiv.innerText;
speechSynthesis.speak(utterance); // starts speaking
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #86 v0.1 💙 VOICE TO TEXT BUTTON -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const textDiv = document.querySelector('[ms-code-text-to-speech="text"]');
const speakButton = document.querySelector('[ms-code-text-to-speech="button"]');
let utterance = new SpeechSynthesisUtterance();
speakButton.addEventListener('click', () => {
if(speechSynthesis.speaking || speechSynthesis.paused) {
speechSynthesis.cancel(); // stops current speech
} else {
utterance.text = textDiv.innerText;
speechSynthesis.speak(utterance); // starts speaking
}
});
});
</script>

#Nr. 85 - Formular-Eingaben "Zeile hinzufügen
Erlauben Sie Mitgliedern das Hinzufügen und Löschen von Zeilen aus einer Formulareingabe.
<!-- 💙 MEMBERSCRIPT #85 v0.1 💙 ADD A ROW FORM INPUTS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Hide all rows except the original row
$('[ms-code-row-input="new"]').hide();
// Add row button click event
$('[ms-code-row-input="add-row"]').click(function(e) {
e.preventDefault();
var clonedRow = $('[ms-code-row-input="new"]').first().clone();
clonedRow.find('input').val('');
clonedRow.show().appendTo('[ms-code-row-input="row-container"]');
updateHolderValue();
});
// Delete row button click event
$(document).on('click', '[ms-code-row-input="delete"]', function(e) {
e.preventDefault();
$(this).closest('[ms-code-row-input="new"]').remove();
updateHolderValue();
});
// Event for all inputs
$(document).on('input', '[ms-code-row-input="original"], [ms-code-row-input="new-input"], [ms-code-row-input="holder"]', function() {
if ($(this).is('[ms-code-row-input="holder"]')) {
updateRowsFromHolder();
} else {
updateHolderValue();
}
});
// Function to update the holder input value
function updateHolderValue() {
var values = [];
$('[ms-code-row-input="original"], [ms-code-row-input="new-input"]').each(function() {
var value = $(this).val().trim();
if (value) {
values.push(value);
}
});
$('[ms-code-row-input="holder"]').val(values.join(','));
}
// Function to update rows from the holder field
function updateRowsFromHolder() {
var holderValue = $('[ms-code-row-input="holder"]').val();
var values = holderValue.split(',');
$('[ms-code-row-input="new"]').not(':first').remove();
// For each holder value, create a new row
values.forEach(function(val, idx) {
if (idx === 0) {
$('[ms-code-row-input="original"]').val(val);
} else {
var newRow = $('[ms-code-row-input="new"]').first().clone().appendTo('[ms-code-row-input="row-container"]');
newRow.find('input').val(val);
newRow.show();
}
});
}
// Initial update of the holder input value
updateHolderValue();
// Adding MutationObserver to call updateRowsFromHolder on changes to the holder field
var targetNode = $('[ms-code-row-input="holder"]')[0];
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList')
{
updateRowsFromHolder();
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
</script>
<!-- 💙 MEMBERSCRIPT #85 v0.1 💙 ADD A ROW FORM INPUTS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// Hide all rows except the original row
$('[ms-code-row-input="new"]').hide();
// Add row button click event
$('[ms-code-row-input="add-row"]').click(function(e) {
e.preventDefault();
var clonedRow = $('[ms-code-row-input="new"]').first().clone();
clonedRow.find('input').val('');
clonedRow.show().appendTo('[ms-code-row-input="row-container"]');
updateHolderValue();
});
// Delete row button click event
$(document).on('click', '[ms-code-row-input="delete"]', function(e) {
e.preventDefault();
$(this).closest('[ms-code-row-input="new"]').remove();
updateHolderValue();
});
// Event for all inputs
$(document).on('input', '[ms-code-row-input="original"], [ms-code-row-input="new-input"], [ms-code-row-input="holder"]', function() {
if ($(this).is('[ms-code-row-input="holder"]')) {
updateRowsFromHolder();
} else {
updateHolderValue();
}
});
// Function to update the holder input value
function updateHolderValue() {
var values = [];
$('[ms-code-row-input="original"], [ms-code-row-input="new-input"]').each(function() {
var value = $(this).val().trim();
if (value) {
values.push(value);
}
});
$('[ms-code-row-input="holder"]').val(values.join(','));
}
// Function to update rows from the holder field
function updateRowsFromHolder() {
var holderValue = $('[ms-code-row-input="holder"]').val();
var values = holderValue.split(',');
$('[ms-code-row-input="new"]').not(':first').remove();
// For each holder value, create a new row
values.forEach(function(val, idx) {
if (idx === 0) {
$('[ms-code-row-input="original"]').val(val);
} else {
var newRow = $('[ms-code-row-input="new"]').first().clone().appendTo('[ms-code-row-input="row-container"]');
newRow.find('input').val(val);
newRow.show();
}
});
}
// Initial update of the holder input value
updateHolderValue();
// Adding MutationObserver to call updateRowsFromHolder on changes to the holder field
var targetNode = $('[ms-code-row-input="holder"]')[0];
var config = { attributes: true, childList: true, subtree: true };
var callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList')
{
updateRowsFromHolder();
}
}
};
var observer = new MutationObserver(callback);
observer.observe(targetNode, config);
});
</script>

#Nr. 84 - Eingänge löschen OnLoad
Fügen Sie dieses Skript einer beliebigen Seite hinzu, um den Wert eines benutzerdefinierten Feldes beim Laden der Seite zu löschen.
<!-- 💙 MEMBERSCRIPT #84 v0.1 💙 CLEAR INPUT VALUES ONLOAD -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const fieldsToClear = ["phone", "last-name"]; // Specify the fields to clear
// Clear inputs and Memberstack fields on page load
memberstack.getCurrentMember().then(async ({ data: member }) => {
if (member) {
const customFieldsToUpdate = {};
fieldsToClear.forEach(fieldName => {
customFieldsToUpdate[fieldName] = '';
});
try {
await memberstack.updateMember({
customFields: customFieldsToUpdate
});
console.log("Fields cleared on page load.");
} catch (error) {
console.error('Error clearing fields on page load:', error);
}
}
// Clear input values on page load for specified fields
fieldsToClear.forEach(fieldName => {
const inputField = document.querySelector(`[data-ms-member="${fieldName}"]`);
if (inputField) {
inputField.value = '';
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #84 v0.1 💙 CLEAR INPUT VALUES ONLOAD -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const fieldsToClear = ["phone", "last-name"]; // Specify the fields to clear
// Clear inputs and Memberstack fields on page load
memberstack.getCurrentMember().then(async ({ data: member }) => {
if (member) {
const customFieldsToUpdate = {};
fieldsToClear.forEach(fieldName => {
customFieldsToUpdate[fieldName] = '';
});
try {
await memberstack.updateMember({
customFields: customFieldsToUpdate
});
console.log("Fields cleared on page load.");
} catch (error) {
console.error('Error clearing fields on page load:', error);
}
}
// Clear input values on page load for specified fields
fieldsToClear.forEach(fieldName => {
const inputField = document.querySelector(`[data-ms-member="${fieldName}"]`);
if (inputField) {
inputField.value = '';
}
});
});
});
</script>

#83 - Geräteübergreifende Cookie-Einstellungen
Erlauben Sie Mitgliedern, ihre Cookie-Einstellungen in ihrem Konto zu speichern.
<!-- 💙 MEMBERSCRIPT #83 v0.1 💙 CROSS-DEVICE COOKIE PREFERENCES -->
<script>
// Function to retrieve a cookie value by name
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
}
async function updateMemberConsentPreferences(fsCcCookieValue) {
try {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
if (!userData.data.customFields['cookie-consent']) {
const decodedFsCcCookieValue = decodeURIComponent(fsCcCookieValue);
await memberstack.updateMember({
customFields: {
'cookie-consent': decodedFsCcCookieValue
}
});
} else {
document.cookie = `fs-cc=${encodeURIComponent(userData.data.customFields['cookie-consent'])}`;
}
}
} catch (error) {}
}
async function initialize() {
const fsCcCookieValue = getCookie('fs-cc');
if (fsCcCookieValue) {
await updateMemberConsentPreferences(fsCcCookieValue);
const checkboxes = document.querySelectorAll('[fs-cc-checkbox]');
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', async () => {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
const customFieldKey = 'cookie-consent';
const checkboxName = checkbox.getAttribute('fs-cc-checkbox');
if (userData.data.customFields[customFieldKey]) {
const consentData = JSON.parse(userData.data.customFields[customFieldKey]);
consentData.consents[checkboxName] = checkbox.checked;
const updatedCustomField = JSON.stringify(consentData);
await memberstack.updateMember({
customFields: {
[customFieldKey]: updatedCustomField
}
});
document.cookie = `fs-cc=${encodeURIComponent(updatedCustomField)}`;
}
}
});
});
}
}
// Initialize the script
initialize();
</script>
<!-- 💙 MEMBERSCRIPT #83 v0.1 💙 CROSS-DEVICE COOKIE PREFERENCES -->
<script>
// Function to retrieve a cookie value by name
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
}
async function updateMemberConsentPreferences(fsCcCookieValue) {
try {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
if (!userData.data.customFields['cookie-consent']) {
const decodedFsCcCookieValue = decodeURIComponent(fsCcCookieValue);
await memberstack.updateMember({
customFields: {
'cookie-consent': decodedFsCcCookieValue
}
});
} else {
document.cookie = `fs-cc=${encodeURIComponent(userData.data.customFields['cookie-consent'])}`;
}
}
} catch (error) {}
}
async function initialize() {
const fsCcCookieValue = getCookie('fs-cc');
if (fsCcCookieValue) {
await updateMemberConsentPreferences(fsCcCookieValue);
const checkboxes = document.querySelectorAll('[fs-cc-checkbox]');
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', async () => {
const memberstack = window.$memberstackDom;
const userData = await memberstack.getCurrentMember();
if (userData && userData.data.customFields) {
const customFieldKey = 'cookie-consent';
const checkboxName = checkbox.getAttribute('fs-cc-checkbox');
if (userData.data.customFields[customFieldKey]) {
const consentData = JSON.parse(userData.data.customFields[customFieldKey]);
consentData.consents[checkboxName] = checkbox.checked;
const updatedCustomField = JSON.stringify(consentData);
await memberstack.updateMember({
customFields: {
[customFieldKey]: updatedCustomField
}
});
document.cookie = `fs-cc=${encodeURIComponent(updatedCustomField)}`;
}
}
});
});
}
}
// Initialize the script
initialize();
</script>

#Nr. 82 - Lizenzschlüssel
Sichern Sie Ihre herunterladbaren Inhalte mit Lizenzschlüsseln.
<!-- 💙 MEMBERSCRIPT #82 v0.1 💙 LICENSE KEYS -->
<script>
const memberstack = window.$memberstackDom;
// Initialize MutationObserver
const observer = new MutationObserver(async (mutations) => {
const downloadBtn = document.getElementById("download");
if (downloadBtn) {
// Element exists, so add event listener
downloadBtn.addEventListener("click", async () => {
await memberstack.removePlan({
planId: "pln_activate-license-key-952c0d8u"
});
console.log("Plan removed");
});
// Stop observing since we found the element
observer.disconnect();
}
});
// Observe the whole document
observer.observe(document.body, { childList: true, subtree: true });
</script>
<!-- 💙 MEMBERSCRIPT #82 v0.1 💙 LICENSE KEYS -->
<script>
const memberstack = window.$memberstackDom;
// Initialize MutationObserver
const observer = new MutationObserver(async (mutations) => {
const downloadBtn = document.getElementById("download");
if (downloadBtn) {
// Element exists, so add event listener
downloadBtn.addEventListener("click", async () => {
await memberstack.removePlan({
planId: "pln_activate-license-key-952c0d8u"
});
console.log("Plan removed");
});
// Stop observing since we found the element
observer.disconnect();
}
});
// Observe the whole document
observer.observe(document.body, { childList: true, subtree: true });
</script>

#Nr. 81 - Benutzerdefinierte Kontrollkästchenwerte
Geben Sie einen eindeutigen Wert durch, je nachdem, ob das Kästchen angekreuzt ist oder nicht.
<!-- 💙 MEMBERSCRIPT #81 v0.1 💙 CUSTOM CHECKBOX VALUES -->
<script>
document.addEventListener('submit', function(e) {
var checkboxes = document.querySelectorAll('[ms-code-custom-checkbox]');
checkboxes.forEach(function(checkbox) {
var values = checkbox.getAttribute('ms-code-custom-checkbox').split(',');
var valueToSubmit = checkbox.checked ? values[0] : values[1];
var hiddenInput = document.createElement('input');
// Copy all attributes except type and ms-code-custom-checkbox
for (var i = 0; i < checkbox.attributes.length; i++) {
var attr = checkbox.attributes[i];
if (attr.name !== 'type' && attr.name !== 'ms-code-custom-checkbox') {
hiddenInput.setAttribute(attr.name, attr.value);
}
}
hiddenInput.type = 'hidden';
hiddenInput.value = valueToSubmit;
checkbox.form.appendChild(hiddenInput);
checkbox.remove(); // Remove the original checkbox so it doesn't interfere with submission
});
});
</script>
<!-- 💙 MEMBERSCRIPT #81 v0.1 💙 CUSTOM CHECKBOX VALUES -->
<script>
document.addEventListener('submit', function(e) {
var checkboxes = document.querySelectorAll('[ms-code-custom-checkbox]');
checkboxes.forEach(function(checkbox) {
var values = checkbox.getAttribute('ms-code-custom-checkbox').split(',');
var valueToSubmit = checkbox.checked ? values[0] : values[1];
var hiddenInput = document.createElement('input');
// Copy all attributes except type and ms-code-custom-checkbox
for (var i = 0; i < checkbox.attributes.length; i++) {
var attr = checkbox.attributes[i];
if (attr.name !== 'type' && attr.name !== 'ms-code-custom-checkbox') {
hiddenInput.setAttribute(attr.name, attr.value);
}
}
hiddenInput.type = 'hidden';
hiddenInput.value = valueToSubmit;
checkbox.form.appendChild(hiddenInput);
checkbox.remove(); // Remove the original checkbox so it doesn't interfere with submission
});
});
</script>

#Nr. 80 - Benachrichtigung über stornierte Pläne
Lösen Sie eine Slack-Benachrichtigung aus, wenn ein Mitglied seinen Plan kündigt.

#79 - Auslöser Click onHover
Auslösen eines Klick-Ereignisses onHover.
<!-- 💙 MEMBERSCRIPT #79 v0.1 💙 HOVER BASED TABS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const hoverTabElements = document.querySelectorAll('[ms-code-onhover="click"]');
hoverTabElements.forEach(hoverTabElement => {
hoverTabElement.addEventListener('mouseenter', function() {
hoverTabElement.click(); // Click on the element when hovering
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #79 v0.1 💙 HOVER BASED TABS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const hoverTabElements = document.querySelectorAll('[ms-code-onhover="click"]');
hoverTabElements.forEach(hoverTabElement => {
hoverTabElement.addEventListener('mouseenter', function() {
hoverTabElement.click(); // Click on the element when hovering
});
});
});
</script>
Brauchen Sie Hilfe mit MemberScripts? Treten Sie unserer Slack-Community mit über 5.500 Mitgliedern bei! 🙌
MemberScripts sind eine Community-Ressource von Memberstack - wenn du Hilfe brauchst, damit sie mit deinem Projekt funktionieren, melde dich bitte im Memberstack 2.0 Slack an und bitte um Hilfe!
Unserem Slack beitretenEntdecken Sie echte Unternehmen, die mit Memberstack erfolgreich waren
Verlassen Sie sich nicht nur auf unser Wort - schauen Sie sich die Unternehmen aller Größen an, die sich auf Memberstack für ihre Authentifizierung und Zahlungen verlassen.
Bauen Sie Ihre Träume
Memberstack ist 100% kostenlos, bis Sie bereit sind, zu starten - worauf warten Sie also noch? Erstellen Sie Ihre erste App und beginnen Sie noch heute mit der Entwicklung.