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.

#Nr. 38 - Feld zum Hochladen von Dateien
Fügen Sie einen Datei-Uploader zu jeder Website hinzu und senden Sie die Übermittlung an Google Drive, E-Mail oder an einen anderen Ort Ihrer Wahl.
<!-- 💙 MEMBERSCRIPT #38 v0.1 💙 FORM FILE UPLOADER -->
<script>
const forms = document.querySelectorAll('form[ms-code-file-upload="form"]');
forms.forEach((form) => {
form.setAttribute('enctype', 'multipart/form-data');
const uploadInputs = form.querySelectorAll('[ms-code-file-upload-input]');
uploadInputs.forEach((uploadInput) => {
const inputName = uploadInput.getAttribute('ms-code-file-upload-input');
const fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('name', inputName);
fileInput.setAttribute('id', inputName);
fileInput.required = true; // delete this line to make the input optional
uploadInput.appendChild(fileInput);
});
});
</script>
<!-- 💙 MEMBERSCRIPT #38 v0.1 💙 FORM FILE UPLOADER -->
<script>
const forms = document.querySelectorAll('form[ms-code-file-upload="form"]');
forms.forEach((form) => {
form.setAttribute('enctype', 'multipart/form-data');
const uploadInputs = form.querySelectorAll('[ms-code-file-upload-input]');
uploadInputs.forEach((uploadInput) => {
const inputName = uploadInput.getAttribute('ms-code-file-upload-input');
const fileInput = document.createElement('input');
fileInput.setAttribute('type', 'file');
fileInput.setAttribute('name', inputName);
fileInput.setAttribute('id', inputName);
fileInput.required = true; // delete this line to make the input optional
uploadInput.appendChild(fileInput);
});
});
</script>

#Nr. 37 - Automatisch den kostenlosen Plan entfernen
Entfernen Sie einen kostenlosen Plan automatisch nach einer bestimmten Zeit!
<!-- 💙 MEMBERSCRIPT #37 v0.1 💙 MAKE FREE TRIAL EXPIRE AFTER SET TIME -->
<script>
let memberPlanId = "your_plan_ID"; // replace with your actual FREE plan ID
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
// Fetch the member's data
const member = await memberstack.getMemberJSON();
// Fetch the member's planConnections from local storage
const memberDataFromLocalStorage = JSON.parse(localStorage.getItem('_ms-mem'));
const planConnections = memberDataFromLocalStorage.planConnections;
// Check if the member has x plan
let hasPlan = false;
if (planConnections) {
hasPlan = planConnections.some(planConnection => planConnection.planId === memberPlanId);
}
if (hasPlan) {
// Check the members one-time-date
let currentDate = new Date();
let oneTimeDate = new Date(member.data['one-time-date']);
if (currentDate > oneTimeDate) {
// If the members' one time date has passed, remove x plan
memberstack.removePlan({
planId: memberPlanId
}).then(() => {
// Redirect to /free-trial-expired
window.location.href = "/free-trial-expired";
}).catch(error => {
// Handle error
});
}
}
});
</script>
<!-- 💙 MEMBERSCRIPT #37 v0.1 💙 MAKE FREE TRIAL EXPIRE AFTER SET TIME -->
<script>
let memberPlanId = "your_plan_ID"; // replace with your actual FREE plan ID
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
// Fetch the member's data
const member = await memberstack.getMemberJSON();
// Fetch the member's planConnections from local storage
const memberDataFromLocalStorage = JSON.parse(localStorage.getItem('_ms-mem'));
const planConnections = memberDataFromLocalStorage.planConnections;
// Check if the member has x plan
let hasPlan = false;
if (planConnections) {
hasPlan = planConnections.some(planConnection => planConnection.planId === memberPlanId);
}
if (hasPlan) {
// Check the members one-time-date
let currentDate = new Date();
let oneTimeDate = new Date(member.data['one-time-date']);
if (currentDate > oneTimeDate) {
// If the members' one time date has passed, remove x plan
memberstack.removePlan({
planId: memberPlanId
}).then(() => {
// Redirect to /free-trial-expired
window.location.href = "/free-trial-expired";
}).catch(error => {
// Handle error
});
}
}
});
</script>

#Nr. 36 - Passwort-Überprüfung
Verwenden Sie diese einfache Methode, um zu bestätigen, dass Ihre Mitglieder ein sicheres Passwort eingegeben haben.
<!-- 💙 MEMBERSCRIPT #36 v0.1 💙 PASSWORD VALIDATION -->
<script>
window.addEventListener('load', function() {
const passwordInput = document.querySelector('input[data-ms-member="password"]');
const submitButton = document.querySelector('[ms-code-submit-button]');
if (!passwordInput || !submitButton) return; // Return if essential elements are not found
function checkAllValid() {
const validationPoints = document.querySelectorAll('[ms-code-pw-validation]');
return Array.from(validationPoints).every(validationPoint => {
const validIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="true"]');
return validIcon && validIcon.style.display === 'flex'; // Check for validIcon existence before accessing style
});
}
passwordInput.addEventListener('keyup', function() {
const password = passwordInput.value;
const validationPoints = document.querySelectorAll('[ms-code-pw-validation]');
validationPoints.forEach(function(validationPoint) {
const rule = validationPoint.getAttribute('ms-code-pw-validation');
let isValid = false;
// MINIMUM LENGTH VALIDATION POINT
if (rule.startsWith('minlength-')) {
const minLength = parseInt(rule.split('-')[1]);
isValid = password.length >= minLength;
}
// SPECIAL CHARACTER VALIDATION POINT
else if (rule === 'special-character') {
isValid = /[!@#$%^&*(),.?":{}|<>]/g.test(password);
}
// UPPER AND LOWER CASE VALIDATION POINT
else if (rule === 'upper-lower-case') {
isValid = /[a-z]/.test(password) && /[A-Z]/.test(password);
}
// NUMBER VALIDATION POINT
else if (rule === 'number') {
isValid = /\d/.test(password);
}
const validIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="true"]');
const invalidIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="false"]');
if (validIcon && invalidIcon) { // Check for existence before accessing style
if (isValid) {
validIcon.style.display = 'flex';
invalidIcon.style.display = 'none';
} else {
validIcon.style.display = 'none';
invalidIcon.style.display = 'flex';
}
}
});
if (checkAllValid()) {
submitButton.classList.remove('disabled');
} else {
submitButton.classList.add('disabled');
}
});
// Trigger keyup event after adding event listener
var event = new Event('keyup');
passwordInput.dispatchEvent(event);
});
</script>
<!-- 💙 MEMBERSCRIPT #36 v0.1 💙 PASSWORD VALIDATION -->
<script>
window.addEventListener('load', function() {
const passwordInput = document.querySelector('input[data-ms-member="password"]');
const submitButton = document.querySelector('[ms-code-submit-button]');
if (!passwordInput || !submitButton) return; // Return if essential elements are not found
function checkAllValid() {
const validationPoints = document.querySelectorAll('[ms-code-pw-validation]');
return Array.from(validationPoints).every(validationPoint => {
const validIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="true"]');
return validIcon && validIcon.style.display === 'flex'; // Check for validIcon existence before accessing style
});
}
passwordInput.addEventListener('keyup', function() {
const password = passwordInput.value;
const validationPoints = document.querySelectorAll('[ms-code-pw-validation]');
validationPoints.forEach(function(validationPoint) {
const rule = validationPoint.getAttribute('ms-code-pw-validation');
let isValid = false;
// MINIMUM LENGTH VALIDATION POINT
if (rule.startsWith('minlength-')) {
const minLength = parseInt(rule.split('-')[1]);
isValid = password.length >= minLength;
}
// SPECIAL CHARACTER VALIDATION POINT
else if (rule === 'special-character') {
isValid = /[!@#$%^&*(),.?":{}|<>]/g.test(password);
}
// UPPER AND LOWER CASE VALIDATION POINT
else if (rule === 'upper-lower-case') {
isValid = /[a-z]/.test(password) && /[A-Z]/.test(password);
}
// NUMBER VALIDATION POINT
else if (rule === 'number') {
isValid = /\d/.test(password);
}
const validIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="true"]');
const invalidIcon = validationPoint.querySelector('[ms-code-pw-validation-icon="false"]');
if (validIcon && invalidIcon) { // Check for existence before accessing style
if (isValid) {
validIcon.style.display = 'flex';
invalidIcon.style.display = 'none';
} else {
validIcon.style.display = 'none';
invalidIcon.style.display = 'flex';
}
}
});
if (checkAllValid()) {
submitButton.classList.remove('disabled');
} else {
submitButton.classList.add('disabled');
}
});
// Trigger keyup event after adding event listener
var event = new Event('keyup');
passwordInput.dispatchEvent(event);
});
</script>

#Nr. 35 - Einfaches Hinzufügen von FAQ-Schema/Rich Snippets
Fügen Sie ein Skript und 2 Attribute hinzu, um ständig aktualisierte Rich Snippets auf Ihrer Seite zu ermöglichen.
<!-- 💙 MEMBERSCRIPT #35 v0.1 💙 FAQ RICH SNIPPETS -->
<script>
let faqArray = [];
let questionElements = document.querySelectorAll('[ms-code-snippet-q]');
let answerElements = document.querySelectorAll('[ms-code-snippet-a]');
for (let i = 0; i < questionElements.length; i++) {
let question = questionElements[i].innerText;
let answer = '';
for (let j = 0; j < answerElements.length; j++) {
if (questionElements[i].getAttribute('ms-code-snippet-q') === answerElements[j].getAttribute('ms-code-snippet-a')) {
answer = answerElements[j].innerText;
break;
}
}
faqArray.push({
"@type": "Question",
"name": question,
"acceptedAnswer": {
"@type": "Answer",
"text": answer
}
});
}
let faqSchema = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faqArray
}
let script = document.createElement('script');
script.type = "application/ld+json";
script.innerHTML = JSON.stringify(faqSchema);
document.getElementsByTagName('head')[0].appendChild(script);
</script>
<!-- 💙 MEMBERSCRIPT #35 v0.1 💙 FAQ RICH SNIPPETS -->
<script>
let faqArray = [];
let questionElements = document.querySelectorAll('[ms-code-snippet-q]');
let answerElements = document.querySelectorAll('[ms-code-snippet-a]');
for (let i = 0; i < questionElements.length; i++) {
let question = questionElements[i].innerText;
let answer = '';
for (let j = 0; j < answerElements.length; j++) {
if (questionElements[i].getAttribute('ms-code-snippet-q') === answerElements[j].getAttribute('ms-code-snippet-a')) {
answer = answerElements[j].innerText;
break;
}
}
faqArray.push({
"@type": "Question",
"name": question,
"acceptedAnswer": {
"@type": "Answer",
"text": answer
}
});
}
let faqSchema = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": faqArray
}
let script = document.createElement('script');
script.type = "application/ld+json";
script.innerHTML = JSON.stringify(faqSchema);
document.getElementsByTagName('head')[0].appendChild(script);
</script>

#Nr. 34 - Erfordern Sie eine geschäftliche E-Mail für die Übermittlung von Formularen
Sperren Sie Personen für die Übermittlung eines Formulars, wenn deren E-Mail eine persönliche E-Mail wie gmail verwendet.
<!-- 💙 MEMBERSCRIPT #34 v0.1 💙 REQUIRE BUSINESS EMAILS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.9.2/parsley.min.js"> </script>
<script>
function isPersonalEmail(email) {
var personalDomains = [
"gmail.com",
"yahoo.com",
"hotmail.com",
"aol.com",
"msn.com",
"comcast.net",
"live.com",
"outlook.com",
"ymail.com",
"icloud.com"
];
var emailDomain = email.split('@')[1];
return personalDomains.includes(emailDomain);
}
window.Parsley.addValidator('businessEmail', {
validateString: function(value) {
return !isPersonalEmail(value);
},
messages: {
en: 'Please enter a business email.'
}
});
$(document).ready(function() {
$('form[ms-code-validate-form]').attr('data-parsley-validate', '');
$('input[ms-code-business-email]').attr('data-parsley-business-email', '');
$('form').parsley();
});
$('form').parsley().on('form:error', function() {
$('.parsley-errors-list').addClass('ms-code-validation-error');
});
</script>
<!-- 💙 MEMBERSCRIPT #34 v0.1 💙 REQUIRE BUSINESS EMAILS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.9.2/parsley.min.js"> </script>
<script>
function isPersonalEmail(email) {
var personalDomains = [
"gmail.com",
"yahoo.com",
"hotmail.com",
"aol.com",
"msn.com",
"comcast.net",
"live.com",
"outlook.com",
"ymail.com",
"icloud.com"
];
var emailDomain = email.split('@')[1];
return personalDomains.includes(emailDomain);
}
window.Parsley.addValidator('businessEmail', {
validateString: function(value) {
return !isPersonalEmail(value);
},
messages: {
en: 'Please enter a business email.'
}
});
$(document).ready(function() {
$('form[ms-code-validate-form]').attr('data-parsley-validate', '');
$('input[ms-code-business-email]').attr('data-parsley-business-email', '');
$('form').parsley();
});
$('form').parsley().on('form:error', function() {
$('.parsley-errors-list').addClass('ms-code-validation-error');
});
</script>

#33 - Formulareingaben automatisch formatieren
Erzwingen Sie Formulareingaben in einem bestimmten Format, z. B. DD/MM/YYYYY.
<!-- 💙 MEMBERSCRIPT #33 v0.2 💙 AUTOMATICALLY FORMAT FORM INPUTS -->
<script src="https://cdn.jsdelivr.net/npm/cleave.js@1.6.0"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cleave.js/1.6.0/addons/cleave-phone.us.js"> </script>
<script>
document.addEventListener('DOMContentLoaded', function(){
// SELECT ALL ELEMENTS WITH THE ATTRIBUTE "ms-code-autoformat" OR "ms-code-autoformat-prefix"
const elements = document.querySelectorAll('[ms-code-autoformat], [ms-code-autoformat-prefix]');
for (let element of elements) {
const formatType = element.getAttribute('ms-code-autoformat');
const prefix = element.getAttribute('ms-code-autoformat-prefix');
// SET PREFIX
let cleaveOptions = {
prefix: prefix || '',
blocks: [Infinity]
};
// BASED ON THE VALUE OF "ms-code-autoformat", FORMAT THE INPUT
if (formatType) {
switch (formatType) {
// FORMAT PHONE NUMBERS
case 'phone-number':
cleaveOptions.phone = true;
cleaveOptions.phoneRegionCode = 'US';
break;
// FORMAT DATES IN 'YYYY-MM-DD' FORMAT
case 'date-yyyy-mm-dd':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['Y', 'm', 'd'];
break;
// FORMAT DATES IN 'MM-DD-YYYY' FORMAT
case 'date-mm-dd-yyyy':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['m', 'd', 'Y'];
break;
// FORMAT DATES IN 'DD-MM-YYYY' FORMAT
case 'date-dd-mm-yyyy':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['d', 'm', 'Y'];
break;
// FORMAT TIMES IN 'HH-MM-SS' FORMAT
case 'time-hh-mm-ss':
cleaveOptions.time = true;
cleaveOptions.timePattern = ['h', 'm', 's'];
break;
// FORMAT TIMES IN 'HH-MM' FORMAT
case 'time-hh-mm':
cleaveOptions.time = true;
cleaveOptions.timePattern = ['h', 'm'];
break;
// FORMAT NUMBERS WITH THOUSANDS SEPARATORS
case 'number-thousand':
cleaveOptions.numeral = true;
cleaveOptions.numeralThousandsGroupStyle = 'thousand';
break;
}
}
new Cleave(element, cleaveOptions);
}
});
</script>
<!-- 💙 MEMBERSCRIPT #33 v0.2 💙 AUTOMATICALLY FORMAT FORM INPUTS -->
<script src="https://cdn.jsdelivr.net/npm/cleave.js@1.6.0"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cleave.js/1.6.0/addons/cleave-phone.us.js"> </script>
<script>
document.addEventListener('DOMContentLoaded', function(){
// SELECT ALL ELEMENTS WITH THE ATTRIBUTE "ms-code-autoformat" OR "ms-code-autoformat-prefix"
const elements = document.querySelectorAll('[ms-code-autoformat], [ms-code-autoformat-prefix]');
for (let element of elements) {
const formatType = element.getAttribute('ms-code-autoformat');
const prefix = element.getAttribute('ms-code-autoformat-prefix');
// SET PREFIX
let cleaveOptions = {
prefix: prefix || '',
blocks: [Infinity]
};
// BASED ON THE VALUE OF "ms-code-autoformat", FORMAT THE INPUT
if (formatType) {
switch (formatType) {
// FORMAT PHONE NUMBERS
case 'phone-number':
cleaveOptions.phone = true;
cleaveOptions.phoneRegionCode = 'US';
break;
// FORMAT DATES IN 'YYYY-MM-DD' FORMAT
case 'date-yyyy-mm-dd':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['Y', 'm', 'd'];
break;
// FORMAT DATES IN 'MM-DD-YYYY' FORMAT
case 'date-mm-dd-yyyy':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['m', 'd', 'Y'];
break;
// FORMAT DATES IN 'DD-MM-YYYY' FORMAT
case 'date-dd-mm-yyyy':
cleaveOptions.date = true;
cleaveOptions.datePattern = ['d', 'm', 'Y'];
break;
// FORMAT TIMES IN 'HH-MM-SS' FORMAT
case 'time-hh-mm-ss':
cleaveOptions.time = true;
cleaveOptions.timePattern = ['h', 'm', 's'];
break;
// FORMAT TIMES IN 'HH-MM' FORMAT
case 'time-hh-mm':
cleaveOptions.time = true;
cleaveOptions.timePattern = ['h', 'm'];
break;
// FORMAT NUMBERS WITH THOUSANDS SEPARATORS
case 'number-thousand':
cleaveOptions.numeral = true;
cleaveOptions.numeralThousandsGroupStyle = 'thousand';
break;
}
}
new Cleave(element, cleaveOptions);
}
});
</script>

#Nr. 32 - Eingabe auf erforderlich setzen, wenn sichtbar
Erstellen Sie bedingte Formulare, indem Sie erforderliche Eingaben ein- und ausblenden.
<!-- 💙 MEMBERSCRIPT #32 v0.1 💙 REQUIRE INPUT IF VISIBLE -->
<script>
document.addEventListener("DOMContentLoaded", function() {
// Function to check if an element is visible
function isElementVisible(element) {
return element.offsetParent !== null;
}
// Every time the user clicks on the document
document.addEventListener('click', function() {
// Get all inputs with the ms-code attribute
const inputs = document.querySelectorAll('[ms-code="required-if-visible"]');
// Loop through each input
inputs.forEach(function(input) {
// Check if the input or its parent is visible
if (isElementVisible(input)) {
// If the input is visible, add the required attribute
input.required = true;
} else {
// If the input is not visible, remove the required attribute
input.required = false;
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #32 v0.1 💙 REQUIRE INPUT IF VISIBLE -->
<script>
document.addEventListener("DOMContentLoaded", function() {
// Function to check if an element is visible
function isElementVisible(element) {
return element.offsetParent !== null;
}
// Every time the user clicks on the document
document.addEventListener('click', function() {
// Get all inputs with the ms-code attribute
const inputs = document.querySelectorAll('[ms-code="required-if-visible"]');
// Loop through each input
inputs.forEach(function(input) {
// Check if the input or its parent is visible
if (isElementVisible(input)) {
// If the input is visible, add the required attribute
input.required = true;
} else {
// If the input is not visible, remove the required attribute
input.required = false;
}
});
});
});
</script>

#Nr. 31 - Öffnen einer Webflow-Registerkarte mit einem Link
Dieses Skript erzeugt automatisch Links zu Ihren Webflow-Registerkarten.
<!-- 💙 MEMBERSCRIPT #31 v0.2 💙 OPEN WEBFLOW TAB w/ LINK -->
<!-- You can link to tabs like this 👉 www.yoursite.com#tab-name-lowercase -->
<!-- And sub tabs like this 👉 www.yoursite.com#tab-name/sub-tab-name -->
<script>
var Webflow = Webflow || [];
Webflow.push(() => {
function changeTab(shouldScroll = false) {
const hashSegments = window.location.hash.substring(1).split('/');
const offset = 90; // change this to match your fixed header height if you have one
let lastTabTarget;
for (const segment of hashSegments) {
const tabTarget = document.querySelector(`[data-w-tab="${segment}"]`);
if (tabTarget) {
tabTarget.click();
lastTabTarget = tabTarget;
}
}
if (shouldScroll && lastTabTarget) {
window.scrollTo({
top: $(lastTabTarget).offset().top - offset, behavior: 'smooth'
});
}
}
const tabs = document.querySelectorAll('[data-w-tab]');
tabs.forEach(tab => {
const dataWTabValue = tab.dataset.wTab;
const parsedDataTab = dataWTabValue.replace(/\s+/g,"-").toLowerCase();
tab.dataset.wTab = parsedDataTab;
tab.addEventListener('click', () => {
history.pushState({}, '', `#${parsedDataTab}`);
});
});
if (window.location.hash) {
requestAnimationFrame(() => { changeTab(true); });
}
window.addEventListener('hashchange', () => { changeTab() });
});
</script>
<!-- 💙 MEMBERSCRIPT #31 v0.2 💙 OPEN WEBFLOW TAB w/ LINK -->
<!-- You can link to tabs like this 👉 www.yoursite.com#tab-name-lowercase -->
<!-- And sub tabs like this 👉 www.yoursite.com#tab-name/sub-tab-name -->
<script>
var Webflow = Webflow || [];
Webflow.push(() => {
function changeTab(shouldScroll = false) {
const hashSegments = window.location.hash.substring(1).split('/');
const offset = 90; // change this to match your fixed header height if you have one
let lastTabTarget;
for (const segment of hashSegments) {
const tabTarget = document.querySelector(`[data-w-tab="${segment}"]`);
if (tabTarget) {
tabTarget.click();
lastTabTarget = tabTarget;
}
}
if (shouldScroll && lastTabTarget) {
window.scrollTo({
top: $(lastTabTarget).offset().top - offset, behavior: 'smooth'
});
}
}
const tabs = document.querySelectorAll('[data-w-tab]');
tabs.forEach(tab => {
const dataWTabValue = tab.dataset.wTab;
const parsedDataTab = dataWTabValue.replace(/\s+/g,"-").toLowerCase();
tab.dataset.wTab = parsedDataTab;
tab.addEventListener('click', () => {
history.pushState({}, '', `#${parsedDataTab}`);
});
});
if (window.location.hash) {
requestAnimationFrame(() => { changeTab(true); });
}
window.addEventListener('hashchange', () => { changeTab() });
});
</script>

#Nr. 30 - Elemente auf der Seite zählen und Anzahl aktualisieren
Überprüfen Sie, wie viele Elemente mit einem bestimmten Attribut auf der Seite vorhanden sind, und wenden Sie diese Zahl auf einen Text an.
<!-- 💙 MEMBERSCRIPT #30 v0.1 💙 COUNT ITEMS AND DISPLAY COUNT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
setTimeout(function() {
const rollupItems = document.querySelectorAll('[ms-code-rollup-item]');
const rollupNumbers = document.querySelectorAll('[ms-code-rollup-number]');
const updateRollupNumbers = function() {
const rollupCountMap = new Map();
rollupItems.forEach(item => {
const rollupKey = item.getAttribute('ms-code-rollup-item');
const count = rollupCountMap.get(rollupKey) || 0;
rollupCountMap.set(rollupKey, count + 1);
});
rollupNumbers.forEach(number => {
const rollupKey = number.getAttribute('ms-code-rollup-number');
const count = rollupCountMap.get(rollupKey) || 0;
number.textContent = count;
});
};
updateRollupNumbers(); // Initial update
// Polling function to periodically update rollup numbers
const pollRollupNumbers = function() {
updateRollupNumbers();
setTimeout(pollRollupNumbers, 1000); // Adjust the polling interval as needed (in milliseconds)
};
pollRollupNumbers(); // Start polling
}, 2000);
});
</script>
<!-- 💙 MEMBERSCRIPT #30 v0.1 💙 COUNT ITEMS AND DISPLAY COUNT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
setTimeout(function() {
const rollupItems = document.querySelectorAll('[ms-code-rollup-item]');
const rollupNumbers = document.querySelectorAll('[ms-code-rollup-number]');
const updateRollupNumbers = function() {
const rollupCountMap = new Map();
rollupItems.forEach(item => {
const rollupKey = item.getAttribute('ms-code-rollup-item');
const count = rollupCountMap.get(rollupKey) || 0;
rollupCountMap.set(rollupKey, count + 1);
});
rollupNumbers.forEach(number => {
const rollupKey = number.getAttribute('ms-code-rollup-number');
const count = rollupCountMap.get(rollupKey) || 0;
number.textContent = count;
});
};
updateRollupNumbers(); // Initial update
// Polling function to periodically update rollup numbers
const pollRollupNumbers = function() {
updateRollupNumbers();
setTimeout(pollRollupNumbers, 1000); // Adjust the polling interval as needed (in milliseconds)
};
pollRollupNumbers(); // Start polling
}, 2000);
});
</script>

#29 - Elementhöhe beim Laden vorübergehend fixieren
Erzwingen, dass ein Element beim Laden der Seite für eine bestimmte Dauer eine bestimmte Höhe hat.
<!-- 💙 MEMBERSCRIPT #29 v0.1 💙 TEMPORARILY FIX ELEMENT HEIGHT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const elements = document.querySelectorAll('[ms-code-temp-height]');
elements.forEach(element => {
const attributeValue = element.getAttribute('ms-code-temp-height');
if (attributeValue) {
const [time, height] = attributeValue.split(':');
if (!isNaN(time) && !isNaN(height)) {
const defaultHeight = element.style.height;
setTimeout(() => {
element.style.height = defaultHeight;
}, parseInt(time));
element.style.height = height + 'px';
}
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #29 v0.1 💙 TEMPORARILY FIX ELEMENT HEIGHT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const elements = document.querySelectorAll('[ms-code-temp-height]');
elements.forEach(element => {
const attributeValue = element.getAttribute('ms-code-temp-height');
if (attributeValue) {
const [time, height] = attributeValue.split(':');
if (!isNaN(time) && !isNaN(height)) {
const defaultHeight = element.style.height;
setTimeout(() => {
element.style.height = defaultHeight;
}, parseInt(time));
element.style.height = height + 'px';
}
}
});
});
</script>

#28 - Anzeigeelement basierend auf JSON Datumsübergabe
Überprüfen Sie das einmalige Datum aus #27 und zeigen/verstecken Sie ein Element basierend auf diesem.
<!-- 💙 MEMBERSCRIPT #28 v0.1 💙 CHECK ONE-TIME DATE AND UPDATE ELEMENT DISPLAY -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
const updateElementVisibility = async function() {
const member = await memberstack.getMemberJSON();
if (!member.data || !member.data['one-time-date']) {
// Member data or expiration date not available, do nothing
return;
}
const expirationDate = new Date(member.data['one-time-date']);
const currentDate = new Date();
if (currentDate < expirationDate) {
// Expiration date has not passed, update element visibility
const elements = document.querySelectorAll('[ms-code-element-temporary]');
elements.forEach(element => {
const displayValue = element.getAttribute('ms-code-element-temporary');
// Update element visibility based on the attribute value
element.style.display = displayValue;
});
}
};
updateElementVisibility();
});
</script>
<!-- 💙 MEMBERSCRIPT #28 v0.1 💙 CHECK ONE-TIME DATE AND UPDATE ELEMENT DISPLAY -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
const updateElementVisibility = async function() {
const member = await memberstack.getMemberJSON();
if (!member.data || !member.data['one-time-date']) {
// Member data or expiration date not available, do nothing
return;
}
const expirationDate = new Date(member.data['one-time-date']);
const currentDate = new Date();
if (currentDate < expirationDate) {
// Expiration date has not passed, update element visibility
const elements = document.querySelectorAll('[ms-code-element-temporary]');
elements.forEach(element => {
const displayValue = element.getAttribute('ms-code-element-temporary');
// Update element visibility based on the attribute value
element.style.display = displayValue;
});
}
};
updateElementVisibility();
});
</script>

#Nr. 27 - Einmaliges Datum bei der Anmeldung festlegen
Wenden Sie ein Datum auf Ihr Mitglied JSON nach der Anmeldung, die für alles verwendet werden kann.
Nur JSON
Wenn Sie das Datum nicht auch in ein benutzerdefiniertes Feld einfügen müssen, verwenden Sie dies.
<!-- 💙 MEMBERSCRIPT #27 v0.1 💙 SET ONE TIME DATE -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
const updateDate = async function() {
const member = await memberstack.getMemberJSON();
if (!member.data) {
member.data = {};
}
if (!member.data['one-time-date']) {
const currentTime = new Date();
const expirationTime = new Date(currentTime.getTime() + (3 * 60 * 60 * 1000)); // Set the expiration time to 3 hours (adjust as needed)
member.data['one-time-date'] = expirationTime.toISOString();
// Update member JSON
await memberstack.updateMemberJSON({
json: member.data
});
}
};
updateDate();
});
</script>
JSON + Benutzerdefiniertes Feld
Verwenden Sie diese Option, wenn Sie das Datum zu einem benutzerdefinierten Feld hinzufügen müssen (normalerweise für die Verwendung mit Automatisierungen).
<!-- 💙💙 MEMBERSCRIPT #27 v0.1.1 (CUSTOM FIELD) 💙 SET ONE TIME DATE -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const msMem = JSON.parse(localStorage.getItem('_ms-mem'));
const member = await memberstack.getMemberJSON();
if (!member.data) {
member.data = {};
}
// Check if the user has the 'one-time-date' custom field in Memberstack
if (!msMem.customFields || !msMem.customFields['one-time-date']) {
const currentTime = new Date();
const expirationTime = new Date(currentTime.getTime() + (3 * 60 * 60 * 1000)); // Set the expiration time to 3 hours (adjust as needed)
const updatedCustomFields = {
...msMem.customFields,
'one-time-date': expirationTime.toISOString()
};
member.data['one-time-date'] = expirationTime.toISOString();
await memberstack.updateMemberJSON({
json: member.data
});
await memberstack.updateMember({
customFields: updatedCustomFields
});
}
});
</script>
Nur JSON
Wenn Sie das Datum nicht auch in ein benutzerdefiniertes Feld einfügen müssen, verwenden Sie dies.
<!-- 💙 MEMBERSCRIPT #27 v0.1 💙 SET ONE TIME DATE -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
const memberstack = window.$memberstackDom;
const updateDate = async function() {
const member = await memberstack.getMemberJSON();
if (!member.data) {
member.data = {};
}
if (!member.data['one-time-date']) {
const currentTime = new Date();
const expirationTime = new Date(currentTime.getTime() + (3 * 60 * 60 * 1000)); // Set the expiration time to 3 hours (adjust as needed)
member.data['one-time-date'] = expirationTime.toISOString();
// Update member JSON
await memberstack.updateMemberJSON({
json: member.data
});
}
};
updateDate();
});
</script>
JSON + Benutzerdefiniertes Feld
Verwenden Sie diese Option, wenn Sie das Datum zu einem benutzerdefinierten Feld hinzufügen müssen (normalerweise für die Verwendung mit Automatisierungen).
<!-- 💙💙 MEMBERSCRIPT #27 v0.1.1 (CUSTOM FIELD) 💙 SET ONE TIME DATE -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const msMem = JSON.parse(localStorage.getItem('_ms-mem'));
const member = await memberstack.getMemberJSON();
if (!member.data) {
member.data = {};
}
// Check if the user has the 'one-time-date' custom field in Memberstack
if (!msMem.customFields || !msMem.customFields['one-time-date']) {
const currentTime = new Date();
const expirationTime = new Date(currentTime.getTime() + (3 * 60 * 60 * 1000)); // Set the expiration time to 3 hours (adjust as needed)
const updatedCustomFields = {
...msMem.customFields,
'one-time-date': expirationTime.toISOString()
};
member.data['one-time-date'] = expirationTime.toISOString();
await memberstack.updateMemberJSON({
json: member.data
});
await memberstack.updateMember({
customFields: updatedCustomFields
});
}
});
</script>

#Nr. 26 - Inhalte mit benutzerdefinierten Modals verwalten
Verwenden Sie benutzerdefinierte Modals, um Ihre Besucher dazu zu bewegen, ein kostenpflichtiges Konto zu eröffnen!
<!-- 💙 MEMBERSCRIPT #26 v0.1 💙 GATE CONTENT WITH MODALS -->
<script>
$memberstackDom.getCurrentMember().then(({ data }) => {
if (!data) {
// Member is not logged in
const triggers = document.querySelectorAll('[ms-code-gate-modal-trigger]');
const boxes = document.querySelectorAll('[ms-code-gate-modal-box]');
triggers.forEach(trigger => {
trigger.addEventListener('click', () => {
const targetId = trigger.getAttribute('ms-code-gate-modal-trigger');
const box = document.querySelector(`[ms-code-gate-modal-box="${targetId}"]`);
if (box) {
box.style.display = 'flex';
}
});
// Remove links and attributes from trigger
// Uncomment the lines below to enable this functionality
// trigger.removeAttribute('href');
// trigger.removeAttribute('target');
// trigger.removeAttribute('rel');
// trigger.removeAttribute('onclick');
});
}
});
</script>
<!-- 💙 MEMBERSCRIPT #26 v0.1 💙 GATE CONTENT WITH MODALS -->
<script>
$memberstackDom.getCurrentMember().then(({ data }) => {
if (!data) {
// Member is not logged in
const triggers = document.querySelectorAll('[ms-code-gate-modal-trigger]');
const boxes = document.querySelectorAll('[ms-code-gate-modal-box]');
triggers.forEach(trigger => {
trigger.addEventListener('click', () => {
const targetId = trigger.getAttribute('ms-code-gate-modal-trigger');
const box = document.querySelector(`[ms-code-gate-modal-box="${targetId}"]`);
if (box) {
box.style.display = 'flex';
}
});
// Remove links and attributes from trigger
// Uncomment the lines below to enable this functionality
// trigger.removeAttribute('href');
// trigger.removeAttribute('target');
// trigger.removeAttribute('rel');
// trigger.removeAttribute('onclick');
});
}
});
</script>

#Nr. 25 - Element basierend auf den Kindern eines anderen Elements ausblenden
Ein Element aus der Seite entfernen, wenn ein anderes definiertes Element keine untergeordneten Elemente hat.
<!-- 💙 MEMBERSCRIPT #25 v0.1 💙 HIDE ELEMENT BASED ON OTHER ELEMENT CHILDREN -->
<script>
window.addEventListener('DOMContentLoaded', function() {
const subjectAttribute = 'ms-code-visibility-subject';
const targetAttribute = 'ms-code-visibility-target';
const subjectElement = document.querySelector(`[${subjectAttribute}]`);
const targetElement = document.querySelector(`[${targetAttribute}]`);
if (!subjectElement || !targetElement) {
console.error('Subject or target element not found');
return;
}
function checkVisibility() {
const children = subjectElement.children;
let allHidden = true;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const computedStyle = window.getComputedStyle(child);
if (computedStyle.display !== 'none') {
allHidden = false;
break;
}
}
if (children.length === 0 || allHidden) {
targetElement.style.display = 'none';
} else {
targetElement.style.display = '';
}
}
// Check visibility initially
checkVisibility();
// Check visibility whenever the subject element or its children change
const observer = new MutationObserver(checkVisibility);
observer.observe(subjectElement, { childList: true, subtree: true });
});
</script>
<!-- 💙 MEMBERSCRIPT #25 v0.1 💙 HIDE ELEMENT BASED ON OTHER ELEMENT CHILDREN -->
<script>
window.addEventListener('DOMContentLoaded', function() {
const subjectAttribute = 'ms-code-visibility-subject';
const targetAttribute = 'ms-code-visibility-target';
const subjectElement = document.querySelector(`[${subjectAttribute}]`);
const targetElement = document.querySelector(`[${targetAttribute}]`);
if (!subjectElement || !targetElement) {
console.error('Subject or target element not found');
return;
}
function checkVisibility() {
const children = subjectElement.children;
let allHidden = true;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const computedStyle = window.getComputedStyle(child);
if (computedStyle.display !== 'none') {
allHidden = false;
break;
}
}
if (children.length === 0 || allHidden) {
targetElement.style.display = 'none';
} else {
targetElement.style.display = '';
}
}
// Check visibility initially
checkVisibility();
// Check visibility whenever the subject element or its children change
const observer = new MutationObserver(checkVisibility);
observer.observe(subjectElement, { childList: true, subtree: true });
});
</script>

#Nr. 24 - Listen nach Element filtern
Filtern Sie jede Art von Liste auf der Grundlage des Vorhandenseins eines Elements innerhalb seiner Kinder.
Standard-Option
Dies funktioniert in den meisten Anwendungsfällen.
<!-- 💙 MEMBERSCRIPT #24 v0.1 💙 FILTER ITEMS WITHIN LIST BASED ON ELEMENT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const filterListItems = function(list, filterAttribute) {
const items = list.querySelectorAll(`[ms-code-filter-item="${filterAttribute}"]`);
items.forEach(item => {
const target = item.querySelector(`[ms-code-filter-target="${filterAttribute}"]`);
if (!target || window.getComputedStyle(target).display === 'none') {
item.style.display = 'none';
} else {
item.style.display = '';
}
});
};
const filterLists = document.querySelectorAll('[ms-code-filter-list]');
const updateFiltering = function() {
filterLists.forEach(list => {
const filterAttribute = list.getAttribute('ms-code-filter-list');
filterListItems(list, filterAttribute);
});
};
const observeListChanges = function() {
const observer = new MutationObserver(updateFiltering);
filterLists.forEach(list => observer.observe(list, { childList: true, subtree: true }));
};
updateFiltering();
observeListChanges();
});
</script>
Option "Abruf
Wenn der Standard nicht funktioniert, versuchen Sie dies.
<!-- 💙 MEMBERSCRIPT #24 v0.1.1 💙 FILTER ITEMS WITHIN LIST BASED ON ELEMENT (POLLING) -->
<script>
window.addEventListener("DOMContentLoaded", function() {
const filterListItems = function(list, filterAttribute) {
const items = list.querySelectorAll(`[ms-code-filter-item="${filterAttribute}"]`);
items.forEach(item => {
const target = item.querySelector(`[ms-code-filter-target="${filterAttribute}"]`);
if (!target || window.getComputedStyle(target).display === 'none') {
item.style.display = 'none';
} else {
item.style.display = '';
}
});
};
const filterLists = document.querySelectorAll('[ms-code-filter-list]');
const updateFiltering = function() {
filterLists.forEach(list => {
const filterAttribute = list.getAttribute('ms-code-filter-list');
filterListItems(list, filterAttribute);
});
};
const pollPage = function() {
updateFiltering();
setTimeout(pollPage, 1000); // Poll every 1 second
};
pollPage();
});
</script>
Standard-Option
Dies funktioniert in den meisten Anwendungsfällen.
<!-- 💙 MEMBERSCRIPT #24 v0.1 💙 FILTER ITEMS WITHIN LIST BASED ON ELEMENT -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const filterListItems = function(list, filterAttribute) {
const items = list.querySelectorAll(`[ms-code-filter-item="${filterAttribute}"]`);
items.forEach(item => {
const target = item.querySelector(`[ms-code-filter-target="${filterAttribute}"]`);
if (!target || window.getComputedStyle(target).display === 'none') {
item.style.display = 'none';
} else {
item.style.display = '';
}
});
};
const filterLists = document.querySelectorAll('[ms-code-filter-list]');
const updateFiltering = function() {
filterLists.forEach(list => {
const filterAttribute = list.getAttribute('ms-code-filter-list');
filterListItems(list, filterAttribute);
});
};
const observeListChanges = function() {
const observer = new MutationObserver(updateFiltering);
filterLists.forEach(list => observer.observe(list, { childList: true, subtree: true }));
};
updateFiltering();
observeListChanges();
});
</script>
Option "Abruf
Wenn der Standard nicht funktioniert, versuchen Sie dies.
<!-- 💙 MEMBERSCRIPT #24 v0.1.1 💙 FILTER ITEMS WITHIN LIST BASED ON ELEMENT (POLLING) -->
<script>
window.addEventListener("DOMContentLoaded", function() {
const filterListItems = function(list, filterAttribute) {
const items = list.querySelectorAll(`[ms-code-filter-item="${filterAttribute}"]`);
items.forEach(item => {
const target = item.querySelector(`[ms-code-filter-target="${filterAttribute}"]`);
if (!target || window.getComputedStyle(target).display === 'none') {
item.style.display = 'none';
} else {
item.style.display = '';
}
});
};
const filterLists = document.querySelectorAll('[ms-code-filter-list]');
const updateFiltering = function() {
filterLists.forEach(list => {
const filterAttribute = list.getAttribute('ms-code-filter-list');
filterListItems(list, filterAttribute);
});
};
const pollPage = function() {
updateFiltering();
setTimeout(pollPage, 1000); // Poll every 1 second
};
pollPage();
});
</script>

#Nr. 23 - Skelett-Bildschirme / Content Loader
Fügen Sie diese branchenüblichen Ladezustände in nur wenigen Sekunden zu Ihrer Website hinzu.
Modus Licht
Verwenden Sie dies auf einem weißen Hintergrund
<!-- 💙 MEMBERSCRIPT #23 v0.1 💙 SKELETON SCREENS/CONTENT LOADERS -->
<script>
window.addEventListener("DOMContentLoaded", (event) => {
const skeletonElements = document.querySelectorAll('[ms-code-skeleton]');
skeletonElements.forEach(element => {
// Create a skeleton div
const skeletonDiv = document.createElement('div');
skeletonDiv.classList.add('skeleton-loader');
// Add the skeleton div to the current element
element.style.position = 'relative';
element.appendChild(skeletonDiv);
// Get delay from the attribute
let delay = element.getAttribute('ms-code-skeleton');
// If attribute value is not a number, set default delay as 2000ms
if (isNaN(delay)) {
delay = 2000;
}
setTimeout(() => {
// Remove the skeleton loader div after delay
const skeletonDiv = element.querySelector('.skeleton-loader');
element.removeChild(skeletonDiv);
}, delay);
});
});
</script>
<style>
.skeleton-loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: inherit; /* Inherit the border-radius of the parent element */
background: linear-gradient(to right, #f6f7f8 25%, #e0e0e0 50%, #f6f7f8 75%);
background-size: 200% 100%; /* Increase the size of the background image */
z-index: 1; /* Make sure the skeleton loader is on top of the content */
animation: skeleton 1s infinite linear;
}
@keyframes skeleton {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
[ms-code-skeleton] {
background-clip: padding-box;
}
</style>
Dunkler Modus
Verwenden Sie dies auf einem schwarzen Hintergrund
<!-- 💙 MEMBERSCRIPT #23 v0.1 💙 SKELETON SCREENS/CONTENT LOADERS -->
<script>
window.addEventListener("DOMContentLoaded", (event) => {
const skeletonElements = document.querySelectorAll('[ms-code-skeleton]');
skeletonElements.forEach(element => {
// Create a skeleton div
const skeletonDiv = document.createElement('div');
skeletonDiv.classList.add('skeleton-loader');
// Add the skeleton div to the current element
element.style.position = 'relative';
element.appendChild(skeletonDiv);
// Get delay from the attribute
let delay = element.getAttribute('ms-code-skeleton');
// If attribute value is not a number, set default delay as 2000ms
if (isNaN(delay)) {
delay = 2000;
}
setTimeout(() => {
// Remove the skeleton loader div after delay
const skeletonDiv = element.querySelector('.skeleton-loader');
element.removeChild(skeletonDiv);
}, delay);
});
});
</script>
<style>
.skeleton-loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: inherit;
background: linear-gradient(to right, #222222 25%, #333333 50%, #222222 75%); /* Updated background colors */
background-size: 200% 100%;
z-index: 1;
animation: skeleton 1s infinite linear;
}
@keyframes skeleton {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
[ms-code-skeleton] {
background-clip: padding-box;
}
</style>
Modus Licht
Verwenden Sie dies auf einem weißen Hintergrund
<!-- 💙 MEMBERSCRIPT #23 v0.1 💙 SKELETON SCREENS/CONTENT LOADERS -->
<script>
window.addEventListener("DOMContentLoaded", (event) => {
const skeletonElements = document.querySelectorAll('[ms-code-skeleton]');
skeletonElements.forEach(element => {
// Create a skeleton div
const skeletonDiv = document.createElement('div');
skeletonDiv.classList.add('skeleton-loader');
// Add the skeleton div to the current element
element.style.position = 'relative';
element.appendChild(skeletonDiv);
// Get delay from the attribute
let delay = element.getAttribute('ms-code-skeleton');
// If attribute value is not a number, set default delay as 2000ms
if (isNaN(delay)) {
delay = 2000;
}
setTimeout(() => {
// Remove the skeleton loader div after delay
const skeletonDiv = element.querySelector('.skeleton-loader');
element.removeChild(skeletonDiv);
}, delay);
});
});
</script>
<style>
.skeleton-loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: inherit; /* Inherit the border-radius of the parent element */
background: linear-gradient(to right, #f6f7f8 25%, #e0e0e0 50%, #f6f7f8 75%);
background-size: 200% 100%; /* Increase the size of the background image */
z-index: 1; /* Make sure the skeleton loader is on top of the content */
animation: skeleton 1s infinite linear;
}
@keyframes skeleton {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
[ms-code-skeleton] {
background-clip: padding-box;
}
</style>
Dunkler Modus
Verwenden Sie dies auf einem schwarzen Hintergrund
<!-- 💙 MEMBERSCRIPT #23 v0.1 💙 SKELETON SCREENS/CONTENT LOADERS -->
<script>
window.addEventListener("DOMContentLoaded", (event) => {
const skeletonElements = document.querySelectorAll('[ms-code-skeleton]');
skeletonElements.forEach(element => {
// Create a skeleton div
const skeletonDiv = document.createElement('div');
skeletonDiv.classList.add('skeleton-loader');
// Add the skeleton div to the current element
element.style.position = 'relative';
element.appendChild(skeletonDiv);
// Get delay from the attribute
let delay = element.getAttribute('ms-code-skeleton');
// If attribute value is not a number, set default delay as 2000ms
if (isNaN(delay)) {
delay = 2000;
}
setTimeout(() => {
// Remove the skeleton loader div after delay
const skeletonDiv = element.querySelector('.skeleton-loader');
element.removeChild(skeletonDiv);
}, delay);
});
});
</script>
<style>
.skeleton-loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
border-radius: inherit;
background: linear-gradient(to right, #222222 25%, #333333 50%, #222222 75%); /* Updated background colors */
background-size: 200% 100%;
z-index: 1;
animation: skeleton 1s infinite linear;
}
@keyframes skeleton {
0% { background-position: -100% 0; }
100% { background-position: 100% 0; }
}
[ms-code-skeleton] {
background-clip: padding-box;
}
</style>

#22 - Schaltfläche "Senden" deaktivieren, bis die erforderlichen Felder ausgefüllt sind
Grauen Sie Ihre Schaltfläche "Senden" aus, bis alle erforderlichen Werte etwas enthalten.
<!-- 💙 MEMBERSCRIPT #22 v0.1 💙 DISABLE SUBMIT BUTTON UNTIL REQUIRED FIELDS ARE COMPLETE -->
<script>
window.onload = function() {
const forms = document.querySelectorAll('form[ms-code-submit-form]');
forms.forEach(form => {
const submitButton = form.querySelector('input[type="submit"]');
const requiredFields = form.querySelectorAll('input[required]');
form.addEventListener('input', function() {
const allFilled = Array.from(requiredFields).every(field => field.value.trim() !== '');
if (allFilled) {
submitButton.classList.add('submit-enabled');
} else {
submitButton.classList.remove('submit-enabled');
}
});
});
};
</script>
<!-- 💙 MEMBERSCRIPT #22 v0.1 💙 DISABLE SUBMIT BUTTON UNTIL REQUIRED FIELDS ARE COMPLETE -->
<script>
window.onload = function() {
const forms = document.querySelectorAll('form[ms-code-submit-form]');
forms.forEach(form => {
const submitButton = form.querySelector('input[type="submit"]');
const requiredFields = form.querySelectorAll('input[required]');
form.addEventListener('input', function() {
const allFilled = Array.from(requiredFields).every(field => field.value.trim() !== '');
if (allFilled) {
submitButton.classList.add('submit-enabled');
} else {
submitButton.classList.remove('submit-enabled');
}
});
});
};
</script>

#Nr. 21 - Benutzerdefinierte Toast-Benachrichtigungen
Zeigen Sie benutzerdefinierte Toast-Boxen auf Element Klick!
<!-- 💙 MEMBERSCRIPT #21 v0.1 💙 CUSTOM TOAST BOXES -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const toastTriggers = document.querySelectorAll("[ms-code-toast-trigger]");
toastTriggers.forEach(trigger => {
trigger.addEventListener("click", function() {
const triggerId = trigger.getAttribute("ms-code-toast-trigger");
const toastBox = document.querySelector(`[ms-code-toast-box="${triggerId}"]`);
if (toastBox) {
const fadeInDuration = 200;
const fadeOutDuration = 200;
const staticDuration = 2000;
const totalDuration = fadeInDuration + staticDuration + fadeOutDuration;
toastBox.style.opacity = "0";
toastBox.style.display = "block";
let currentTime = 0;
const fade = function() {
currentTime += 10;
const opacity = currentTime < fadeInDuration
? currentTime / fadeInDuration
: currentTime < fadeInDuration + staticDuration
? 1
: 1 - (currentTime - fadeInDuration - staticDuration) / fadeOutDuration;
toastBox.style.opacity = opacity;
if (currentTime < totalDuration) {
setTimeout(fade, 10);
} else {
toastBox.style.display = "none";
}
};
fade();
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #21 v0.1 💙 CUSTOM TOAST BOXES -->
<script>
document.addEventListener("DOMContentLoaded", function() {
const toastTriggers = document.querySelectorAll("[ms-code-toast-trigger]");
toastTriggers.forEach(trigger => {
trigger.addEventListener("click", function() {
const triggerId = trigger.getAttribute("ms-code-toast-trigger");
const toastBox = document.querySelector(`[ms-code-toast-box="${triggerId}"]`);
if (toastBox) {
const fadeInDuration = 200;
const fadeOutDuration = 200;
const staticDuration = 2000;
const totalDuration = fadeInDuration + staticDuration + fadeOutDuration;
toastBox.style.opacity = "0";
toastBox.style.display = "block";
let currentTime = 0;
const fade = function() {
currentTime += 10;
const opacity = currentTime < fadeInDuration
? currentTime / fadeInDuration
: currentTime < fadeInDuration + staticDuration
? 1
: 1 - (currentTime - fadeInDuration - staticDuration) / fadeOutDuration;
toastBox.style.opacity = opacity;
if (currentTime < totalDuration) {
setTimeout(fade, 10);
} else {
toastBox.style.display = "none";
}
};
fade();
}
});
});
});
</script>

#Nr. 19 - URL aus benutzerdefiniertem Feld zu IFrame SRC hinzufügen
Erstellen Sie eine mitgliederspezifische Einbettungsfunktionalität mit dieser iframe-Lösung für benutzerdefinierte Felder!
<!-- 💙 MEMBERSCRIPT #19 v0.1 💙 ADD CUSTOM FIELD AS AN IFRAME SRC -->
<script>
document.addEventListener("DOMContentLoaded", function() {
// Parse member data from local storage
const memberData = JSON.parse(localStorage.getItem('_ms-mem') || '{}');
// Check if the user is logged in
if(memberData && memberData.id) {
// Get custom fields
const customFields = memberData.customFields;
// Select all elements with 'ms-code-field-link' attribute
const elements = document.querySelectorAll('[ms-code-field-link]');
// Iterate over all selected elements
elements.forEach(element => {
// Get custom field key from 'ms-code-field-link' attribute
const fieldKey = element.getAttribute('ms-code-field-link');
// If key exists in custom fields, set element src to the corresponding value
if(customFields.hasOwnProperty(fieldKey)) {
element.setAttribute('src', customFields[fieldKey]);
}
});
}
});
</script>
<!-- 💙 MEMBERSCRIPT #19 v0.1 💙 ADD CUSTOM FIELD AS AN IFRAME SRC -->
<script>
document.addEventListener("DOMContentLoaded", function() {
// Parse member data from local storage
const memberData = JSON.parse(localStorage.getItem('_ms-mem') || '{}');
// Check if the user is logged in
if(memberData && memberData.id) {
// Get custom fields
const customFields = memberData.customFields;
// Select all elements with 'ms-code-field-link' attribute
const elements = document.querySelectorAll('[ms-code-field-link]');
// Iterate over all selected elements
elements.forEach(element => {
// Get custom field key from 'ms-code-field-link' attribute
const fieldKey = element.getAttribute('ms-code-field-link');
// If key exists in custom fields, set element src to the corresponding value
if(customFields.hasOwnProperty(fieldKey)) {
element.setAttribute('src', customFields[fieldKey]);
}
});
}
});
</script>

#18 - Text einfach abschneiden
Fügen Sie ein Attribut und ein einfaches Skript hinzu, um Text programmgesteuert abzuschneiden!
<!-- 💙 MEMBERSCRIPT #18 v0.2 💙 - EASILY TRUNCATE TEXT -->
<script>
const elements = document.querySelectorAll('[ms-code-truncate]');
elements.forEach((element) => {
const charLimit = parseInt(element.getAttribute('ms-code-truncate'));
// Create a helper function that will recursively traverse the DOM tree
const traverseNodes = (node, count) => {
for (let child of node.childNodes) {
// If the node is a text node, truncate if necessary
if (child.nodeType === Node.TEXT_NODE) {
if (count + child.textContent.length > charLimit) {
child.textContent = child.textContent.slice(0, charLimit - count) + '...';
return count + child.textContent.length;
}
count += child.textContent.length;
}
// If the node is an element, recurse through its children
else if (child.nodeType === Node.ELEMENT_NODE) {
count = traverseNodes(child, count);
}
}
return count;
}
// Create a deep clone of the element to work on. This is so that we don't modify the original element
// until we have completely finished processing.
const clone = element.cloneNode(true);
// Traverse and truncate the cloned node
traverseNodes(clone, 0);
// Replace the original element with our modified clone
element.parentNode.replaceChild(clone, element);
});
</script>
<!-- 💙 MEMBERSCRIPT #18 v0.2 💙 - EASILY TRUNCATE TEXT -->
<script>
const elements = document.querySelectorAll('[ms-code-truncate]');
elements.forEach((element) => {
const charLimit = parseInt(element.getAttribute('ms-code-truncate'));
// Create a helper function that will recursively traverse the DOM tree
const traverseNodes = (node, count) => {
for (let child of node.childNodes) {
// If the node is a text node, truncate if necessary
if (child.nodeType === Node.TEXT_NODE) {
if (count + child.textContent.length > charLimit) {
child.textContent = child.textContent.slice(0, charLimit - count) + '...';
return count + child.textContent.length;
}
count += child.textContent.length;
}
// If the node is an element, recurse through its children
else if (child.nodeType === Node.ELEMENT_NODE) {
count = traverseNodes(child, count);
}
}
return count;
}
// Create a deep clone of the element to work on. This is so that we don't modify the original element
// until we have completely finished processing.
const clone = element.cloneNode(true);
// Traverse and truncate the cloned node
traverseNodes(clone, 0);
// Replace the original element with our modified clone
element.parentNode.replaceChild(clone, element);
});
</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.

#Nr. 78 - Eingaben löschen OnClick
Erstellen Sie eine Schaltfläche, die die Werte eines oder mehrerer Eingänge löschen kann.
<!-- 💙 MEMBERSCRIPT #78 v0.1 💙 CLEAR INPUT VALUES ONCLICK -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const clearBtns = document.querySelectorAll('[ms-code-clear-value]');
clearBtns.forEach(btn => {
btn.addEventListener('click', () => {
const fieldIds = btn.getAttribute('ms-code-clear-value').split(',');
fieldIds.forEach(fieldId => {
const input = document.querySelector(`[data-ms-member="${fieldId}"]`);
if (input) {
input.value = '';
}
});
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #78 v0.1 💙 CLEAR INPUT VALUES ONCLICK -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const clearBtns = document.querySelectorAll('[ms-code-clear-value]');
clearBtns.forEach(btn => {
btn.addEventListener('click', () => {
const fieldIds = btn.getAttribute('ms-code-clear-value').split(',');
fieldIds.forEach(fieldId => {
const input = document.querySelector(`[data-ms-member="${fieldId}"]`);
if (input) {
input.value = '';
}
});
});
});
});
</script>

#Nr. 77 - Universal-Emojis
Machen Sie Ihre Emojis vor Ort auf allen Geräten/OS gleich.
<!-- 💙 MEMBERSCRIPT #77 v0.1 💙 UNIVERSAL EMOJIS -->
<script>
document.querySelectorAll('[ms-code-emoji]').forEach(element => {
var imageUrl = element.getAttribute('ms-code-emoji');
var img = document.createElement('img');
img.src = imageUrl;
var textStyle = window.getComputedStyle(element);
var adjustedHeight = parseFloat(textStyle.fontSize) * 1.0;
img.style.height = adjustedHeight + 'px';
img.style.width = 'auto';
img.style.verticalAlign = 'text-top';
element.innerHTML = ''; // Clears the text content inside the span
element.appendChild(img);
});
</script>
<!-- 💙 MEMBERSCRIPT #77 v0.1 💙 UNIVERSAL EMOJIS -->
<script>
document.querySelectorAll('[ms-code-emoji]').forEach(element => {
var imageUrl = element.getAttribute('ms-code-emoji');
var img = document.createElement('img');
img.src = imageUrl;
var textStyle = window.getComputedStyle(element);
var adjustedHeight = parseFloat(textStyle.fontSize) * 1.0;
img.style.height = adjustedHeight + 'px';
img.style.width = 'auto';
img.style.verticalAlign = 'text-top';
element.innerHTML = ''; // Clears the text content inside the span
element.appendChild(img);
});
</script>

#Nr. 76 - Zeitbasierte Sichtbarkeit
Zeigen Sie je nach aktueller Tageszeit unterschiedliche Elemente an.
<!-- 💙 MEMBERSCRIPT #76 v0.1 💙 TIME-BASED VISIBILITY -->
<script>
function hideElements() {
const elements = document.querySelectorAll('[ms-code-time]');
elements.forEach(element => {
element.style.display = 'none';
});
}
function displayBasedOnTime() {
const elements = document.querySelectorAll('[ms-code-time]');
const currentTime = new Date();
elements.forEach(element => {
const timeRange = element.getAttribute('ms-code-time');
const [start, end] = timeRange.split(' - ');
const [startHour, startMinute] = start.split(':').map(Number);
const [endHour, endMinute] = end.split(':').map(Number);
let startTime = new Date(currentTime);
startTime.setHours(startHour, startMinute, 0, 0);
let endTime = new Date(currentTime);
endTime.setHours(endHour, endMinute, 0, 0);
// If the end time is earlier than the start time, add a day to the end time
if (endTime < startTime) {
endTime.setDate(endTime.getDate() + 1);
}
if (currentTime >= startTime && currentTime <= endTime) {
element.style.display = 'flex';
}
});
}
// Call the functions
hideElements();
displayBasedOnTime();
</script>
<!-- 💙 MEMBERSCRIPT #76 v0.1 💙 TIME-BASED VISIBILITY -->
<script>
function hideElements() {
const elements = document.querySelectorAll('[ms-code-time]');
elements.forEach(element => {
element.style.display = 'none';
});
}
function displayBasedOnTime() {
const elements = document.querySelectorAll('[ms-code-time]');
const currentTime = new Date();
elements.forEach(element => {
const timeRange = element.getAttribute('ms-code-time');
const [start, end] = timeRange.split(' - ');
const [startHour, startMinute] = start.split(':').map(Number);
const [endHour, endMinute] = end.split(':').map(Number);
let startTime = new Date(currentTime);
startTime.setHours(startHour, startMinute, 0, 0);
let endTime = new Date(currentTime);
endTime.setHours(endHour, endMinute, 0, 0);
// If the end time is earlier than the start time, add a day to the end time
if (endTime < startTime) {
endTime.setDate(endTime.getDate() + 1);
}
if (currentTime >= startTime && currentTime <= endTime) {
element.style.display = 'flex';
}
});
}
// Call the functions
hideElements();
displayBasedOnTime();
</script>

#Nr. 75 - Unzulässige Zeicheneingaben
Zeigen Sie eine benutzerdefinierte Fehlermeldung an, wenn ein Benutzer etwas eingibt, das Sie in einer Eingabe festgelegt haben.
<!-- 💙 MEMBERSCRIPT #75 v0.1 💙 DISALOWED CHARACTER INPUTS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const inputFields = document.querySelectorAll('[ms-code-disallow]');
inputFields.forEach(inputField => {
const errorBlock = inputField.nextElementSibling;
errorBlock.innerHTML = ''; // Use innerHTML to interpret <br> tags
inputField.addEventListener('input', function() {
const rules = inputField.getAttribute('ms-code-disallow').split(')');
let errorMessage = '';
rules.forEach(rule => {
const parts = rule.trim().split('=');
const ruleType = parts[0].substring(1); // Remove the opening parenthesis
const disallowedValue = parts[1];
if (ruleType.startsWith('custom')) {
const disallowedChar = ruleType.split('-')[1]; // Extract the character after the '-'
if (inputField.value.includes(disallowedChar)) {
errorMessage += disallowedValue + '<br>'; // Add line break
}
} else if (ruleType === 'space' && inputField.value.includes(' ')) {
errorMessage += disallowedValue + '<br>'; // Add line break
} else if (ruleType === 'number' && /\d/.test(inputField.value)) {
errorMessage += disallowedValue + '<br>'; // Add line break
} else if (ruleType === 'special' && /[^a-zA-Z0-9\s]/.test(inputField.value)) { // Notice the \s here
errorMessage += disallowedValue + '<br>'; // Add line break
}
});
errorBlock.innerHTML = errorMessage || ''; // Use innerHTML to interpret <br> tags
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #75 v0.1 💙 DISALOWED CHARACTER INPUTS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const inputFields = document.querySelectorAll('[ms-code-disallow]');
inputFields.forEach(inputField => {
const errorBlock = inputField.nextElementSibling;
errorBlock.innerHTML = ''; // Use innerHTML to interpret <br> tags
inputField.addEventListener('input', function() {
const rules = inputField.getAttribute('ms-code-disallow').split(')');
let errorMessage = '';
rules.forEach(rule => {
const parts = rule.trim().split('=');
const ruleType = parts[0].substring(1); // Remove the opening parenthesis
const disallowedValue = parts[1];
if (ruleType.startsWith('custom')) {
const disallowedChar = ruleType.split('-')[1]; // Extract the character after the '-'
if (inputField.value.includes(disallowedChar)) {
errorMessage += disallowedValue + '<br>'; // Add line break
}
} else if (ruleType === 'space' && inputField.value.includes(' ')) {
errorMessage += disallowedValue + '<br>'; // Add line break
} else if (ruleType === 'number' && /\d/.test(inputField.value)) {
errorMessage += disallowedValue + '<br>'; // Add line break
} else if (ruleType === 'special' && /[^a-zA-Z0-9\s]/.test(inputField.value)) { // Notice the \s here
errorMessage += disallowedValue + '<br>'; // Add line break
}
});
errorBlock.innerHTML = errorMessage || ''; // Use innerHTML to interpret <br> tags
});
});
});
</script>

#Nr. 74 - Gestaltung mit Link-Parametern
Aktualisierung der Seitengestaltung auf der Grundlage eines Linkparameters. Bsp. ?ms-code-target=CLASSNAME&ms-code-style=display:block
<!-- 💙 MEMBERSCRIPT #74 v0.1 💙 UPDATE STYLING WITH LINK PARAMS -->
<script>
// Function to parse URL parameters
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
// Function to apply styles
function applyStylesFromURL() {
const targetClass = getURLParameter('ms-code-target');
const rawStyles = getURLParameter('ms-code-style');
if (targetClass && rawStyles) {
const elements = document.querySelectorAll(`.${targetClass}`);
const styles = rawStyles.split(';').filter(style => style.trim() !== ''); // filter out any empty strings
styles.forEach(style => {
const [property, value] = style.split(':');
elements.forEach(element => {
element.style[property] = value;
});
});
}
}
// Call the function once the DOM is loaded
window.addEventListener('DOMContentLoaded', (event) => {
applyStylesFromURL();
});
</script>
<!-- 💙 MEMBERSCRIPT #74 v0.1 💙 UPDATE STYLING WITH LINK PARAMS -->
<script>
// Function to parse URL parameters
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
// Function to apply styles
function applyStylesFromURL() {
const targetClass = getURLParameter('ms-code-target');
const rawStyles = getURLParameter('ms-code-style');
if (targetClass && rawStyles) {
const elements = document.querySelectorAll(`.${targetClass}`);
const styles = rawStyles.split(';').filter(style => style.trim() !== ''); // filter out any empty strings
styles.forEach(style => {
const [property, value] = style.split(':');
elements.forEach(element => {
element.style[property] = value;
});
});
}
}
// Call the function once the DOM is loaded
window.addEventListener('DOMContentLoaded', (event) => {
applyStylesFromURL();
});
</script>

#Nr. 73 - Datum und Uhrzeit anzeigen
Anzeige der aktuellen Uhrzeit, der Tageszeit, des Tages, des Monats oder des Jahres für einen Benutzer. Funktioniert, wenn er angemeldet oder abgemeldet ist.
<!-- 💙 MEMBERSCRIPT #73 v0.1 💙 DATES AND TIMES -->
function getCurrentDateInfo(attribute) {
const now = new Date();
const options = { hour12: true };
switch(attribute) {
case "day":
return now.toLocaleDateString('en-US', { weekday: 'long' });
case "time":
return now.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }).toLowerCase();
case "month":
return now.toLocaleDateString('en-US', { month: 'long' });
case "year":
return now.getFullYear().toString();
case "time-of-day":
const hour = now.getHours();
if (5 <= hour && hour < 12) return "morning";
if (12 <= hour && hour < 17) return "afternoon";
if (17 <= hour && hour < 21) return "evening";
return "night";
default:
return "Invalid attribute";
}
}
function updateDateInfoOnPage() {
const spanTags = document.querySelectorAll('span[ms-code-date]');
spanTags.forEach(tag => {
const attributeValue = tag.getAttribute('ms-code-date');
const dateInfo = getCurrentDateInfo(attributeValue);
tag.textContent = dateInfo;
});
}
// Call the function to update the content on the page
updateDateInfoOnPage();
</script>
<!-- 💙 MEMBERSCRIPT #73 v0.1 💙 DATES AND TIMES -->
function getCurrentDateInfo(attribute) {
const now = new Date();
const options = { hour12: true };
switch(attribute) {
case "day":
return now.toLocaleDateString('en-US', { weekday: 'long' });
case "time":
return now.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }).toLowerCase();
case "month":
return now.toLocaleDateString('en-US', { month: 'long' });
case "year":
return now.getFullYear().toString();
case "time-of-day":
const hour = now.getHours();
if (5 <= hour && hour < 12) return "morning";
if (12 <= hour && hour < 17) return "afternoon";
if (17 <= hour && hour < 21) return "evening";
return "night";
default:
return "Invalid attribute";
}
}
function updateDateInfoOnPage() {
const spanTags = document.querySelectorAll('span[ms-code-date]');
spanTags.forEach(tag => {
const attributeValue = tag.getAttribute('ms-code-date');
const dateInfo = getCurrentDateInfo(attributeValue);
tag.textContent = dateInfo;
});
}
// Call the function to update the content on the page
updateDateInfoOnPage();
</script>

#Nr. 72 - Originalwerte validieren
Erlaube nur das Absenden eines Formulars, wenn der Eingabewert ein Originalwert ist (z. B. Benutzernamen)
<!-- 💙 MEMBERSCRIPT #72 v0.1 💙 VALIDATE ORIGINAL VALUES -->
<style>
[ms-code-available="true"],
[ms-code-available="false"],
[ms-code-available="invalid"]{
display: none;
}
.disabled {
opacity: 0.5;
pointer-events: none;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
let input = document.querySelector('[ms-code-available="input"]');
let trueElement = document.querySelector('[ms-code-available="true"]');
let falseElement = document.querySelector('[ms-code-available="false"]');
let invalidElement = document.querySelector('[ms-code-available="invalid"]');
let listElements = Array.from(document.querySelectorAll('[ms-code-available="list"]'));
let submitButton = document.querySelector('[ms-code-available="submit"]');
function checkUsername() {
// Check if the input matches any of the list items
let isTaken = listElements.some(elem => elem.textContent.trim() === input.value.trim());
if (isTaken) {
trueElement.style.display = 'none';
falseElement.style.display = 'flex';
submitButton.classList.add('disabled'); // disable the button if username is taken
} else {
trueElement.style.display = 'flex';
falseElement.style.display = 'none';
submitButton.classList.remove('disabled');
}
}
input.addEventListener('input', function() {
// Display the invalid element if input length is between 1 and 3
if (input.value.length >= 1 && input.value.length <= 3) {
invalidElement.style.display = 'flex';
} else {
invalidElement.style.display = 'none';
}
// Add the .disabled class to the submit button if input is empty or less than 3 characters
if (input.value.length <= 3) {
submitButton.classList.add('disabled');
trueElement.style.display = 'none';
falseElement.style.display = 'none';
} else {
checkUsername();
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #72 v0.1 💙 VALIDATE ORIGINAL VALUES -->
<style>
[ms-code-available="true"],
[ms-code-available="false"],
[ms-code-available="invalid"]{
display: none;
}
.disabled {
opacity: 0.5;
pointer-events: none;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
let input = document.querySelector('[ms-code-available="input"]');
let trueElement = document.querySelector('[ms-code-available="true"]');
let falseElement = document.querySelector('[ms-code-available="false"]');
let invalidElement = document.querySelector('[ms-code-available="invalid"]');
let listElements = Array.from(document.querySelectorAll('[ms-code-available="list"]'));
let submitButton = document.querySelector('[ms-code-available="submit"]');
function checkUsername() {
// Check if the input matches any of the list items
let isTaken = listElements.some(elem => elem.textContent.trim() === input.value.trim());
if (isTaken) {
trueElement.style.display = 'none';
falseElement.style.display = 'flex';
submitButton.classList.add('disabled'); // disable the button if username is taken
} else {
trueElement.style.display = 'flex';
falseElement.style.display = 'none';
submitButton.classList.remove('disabled');
}
}
input.addEventListener('input', function() {
// Display the invalid element if input length is between 1 and 3
if (input.value.length >= 1 && input.value.length <= 3) {
invalidElement.style.display = 'flex';
} else {
invalidElement.style.display = 'none';
}
// Add the .disabled class to the submit button if input is empty or less than 3 characters
if (input.value.length <= 3) {
submitButton.classList.add('disabled');
trueElement.style.display = 'none';
falseElement.style.display = 'none';
} else {
checkUsername();
}
});
});
</script>

#71 - Umleiten, wenn bestimmte Felder leer sind
Leiten Sie ein Mitglied auf eine Onboarding-Seite um, wenn bestimmte benutzerdefinierte Felder leer sind.
<!-- 💙 MEMBERSCRIPT #71 v0.1 💙 REDIRECT IF FIELDS ARE EMPTY -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const onboardingPageUrl = '/onboarding'; // replace
const customFieldKeys = 'custom-field-1,custom-field-2'; // replace
// No need to edit past this line
const member = await memberstack.getCurrentMember();
if (!member) {
return;
}
// If current page slug matches the redirect slug, exit the script
const currentPageSlug = window.location.pathname;
if (currentPageSlug === onboardingPageUrl) {
return;
}
async function checkOnboardingStatus() {
try {
const memberData = await memberstack.updateMember({});
const customFields = customFieldKeys.split(',');
for (let field of customFields) {
if (!memberData.data.customFields[field.trim()]) {
// Redirect to onboarding page if the custom field is empty
window.location.href = onboardingPageUrl;
return;
}
}
} catch (error) {
console.error(`Error in checkOnboardingStatus function: ${error}`);
}
}
// Check onboarding status and potentially redirect
checkOnboardingStatus().catch(error => {
console.error(`Error in MemberScript #71 initial functions: ${error}`);
});
});
</script>
<!-- 💙 MEMBERSCRIPT #71 v0.1 💙 REDIRECT IF FIELDS ARE EMPTY -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
const onboardingPageUrl = '/onboarding'; // replace
const customFieldKeys = 'custom-field-1,custom-field-2'; // replace
// No need to edit past this line
const member = await memberstack.getCurrentMember();
if (!member) {
return;
}
// If current page slug matches the redirect slug, exit the script
const currentPageSlug = window.location.pathname;
if (currentPageSlug === onboardingPageUrl) {
return;
}
async function checkOnboardingStatus() {
try {
const memberData = await memberstack.updateMember({});
const customFields = customFieldKeys.split(',');
for (let field of customFields) {
if (!memberData.data.customFields[field.trim()]) {
// Redirect to onboarding page if the custom field is empty
window.location.href = onboardingPageUrl;
return;
}
}
} catch (error) {
console.error(`Error in checkOnboardingStatus function: ${error}`);
}
}
// Check onboarding status and potentially redirect
checkOnboardingStatus().catch(error => {
console.error(`Error in MemberScript #71 initial functions: ${error}`);
});
});
</script>

#70 - Alte/gesehene CMS-Elemente ausblenden
Zeigen Sie nur CMS-Elemente an, die für ein bestimmtes Mitglied neu sind. Wenn sie es schon gesehen haben, blenden Sie es aus.
<!-- 💙 MEMBERSCRIPT #70 v0.1 💙 HIDE OLD CMS ITEMS -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
// Only proceed if a member is found
const member = await memberstack.getCurrentMember();
if (!member) {
console.log('No member found in MemberScript #70, exiting script');
return;
}
async function getCmsItemsFromJson() {
try {
const memberData = await memberstack.getMemberJSON();
return memberData?.data?.cmsItems || [];
} catch (error) {
console.error(`Error in getCmsItemsFromJson function: ${error}`);
}
}
async function updateCmsItemsInJson(newCmsItems) {
try {
const memberData = await memberstack.getMemberJSON();
memberData.data = memberData.data || {};
memberData.data.cmsItems = newCmsItems;
console.log(`CMS items in JSON after update: ${JSON.stringify(newCmsItems)}`);
await memberstack.updateMemberJSON({ json: memberData.data });
} catch (error) {
console.error(`Error in updateCmsItemsInJson function: ${error}`);
}
}
async function hideSeenCmsItems() {
try {
const cmsItemsElements = document.querySelectorAll('[ms-code-cms-item]');
const cmsItemsFromJson = await getCmsItemsFromJson();
cmsItemsElements.forEach(element => {
const cmsValue = element.getAttribute('ms-code-cms-item');
if (cmsItemsFromJson.includes(cmsValue)) {
element.style.display = 'none';
} else {
cmsItemsFromJson.push(cmsValue);
}
});
// Update the CMS items in JSON after the checks
await updateCmsItemsInJson(cmsItemsFromJson);
} catch (error) {
console.error(`Error in hideSeenCmsItems function: ${error}`);
}
}
// Hide seen CMS items when the page loads
hideSeenCmsItems().catch(error => {
console.error(`Error in MemberScript #70 initial functions: ${error}`);
});
});
</script>
<!-- 💙 MEMBERSCRIPT #70 v0.1 💙 HIDE OLD CMS ITEMS -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
// Only proceed if a member is found
const member = await memberstack.getCurrentMember();
if (!member) {
console.log('No member found in MemberScript #70, exiting script');
return;
}
async function getCmsItemsFromJson() {
try {
const memberData = await memberstack.getMemberJSON();
return memberData?.data?.cmsItems || [];
} catch (error) {
console.error(`Error in getCmsItemsFromJson function: ${error}`);
}
}
async function updateCmsItemsInJson(newCmsItems) {
try {
const memberData = await memberstack.getMemberJSON();
memberData.data = memberData.data || {};
memberData.data.cmsItems = newCmsItems;
console.log(`CMS items in JSON after update: ${JSON.stringify(newCmsItems)}`);
await memberstack.updateMemberJSON({ json: memberData.data });
} catch (error) {
console.error(`Error in updateCmsItemsInJson function: ${error}`);
}
}
async function hideSeenCmsItems() {
try {
const cmsItemsElements = document.querySelectorAll('[ms-code-cms-item]');
const cmsItemsFromJson = await getCmsItemsFromJson();
cmsItemsElements.forEach(element => {
const cmsValue = element.getAttribute('ms-code-cms-item');
if (cmsItemsFromJson.includes(cmsValue)) {
element.style.display = 'none';
} else {
cmsItemsFromJson.push(cmsValue);
}
});
// Update the CMS items in JSON after the checks
await updateCmsItemsInJson(cmsItemsFromJson);
} catch (error) {
console.error(`Error in hideSeenCmsItems function: ${error}`);
}
}
// Hide seen CMS items when the page loads
hideSeenCmsItems().catch(error => {
console.error(`Error in MemberScript #70 initial functions: ${error}`);
});
});
</script>

#Nr. 69 - Mitglieder über neue CMS-Elemente benachrichtigen
Ein Element anzeigen, wenn es neue CMS-Elemente gibt.
<!-- 💙 MEMBERSCRIPT #69 v0.1 💙 DISPLAY ELEMENT IF NEW CMS ITEMS -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
// Set this variable to 'YES' or 'NO' depending on whether you want the UI to be displayed for new users
const displayForNewUsers = 'YES';
// Only proceed if a member is found
const member = await memberstack.getCurrentMember();
if (!member) {
console.log('No member found, exiting script');
return;
}
async function getUpdatesIDFromJson() {
try {
const memberData = await memberstack.getMemberJSON();
console.log(`Member data: ${JSON.stringify(memberData)}`);
return memberData?.data?.updatesID || '';
} catch (error) {
console.error(`Error in getUpdatesIDFromJson function: ${error}`);
}
}
async function updateUpdatesIDInJson(newUpdatesID) {
try {
const memberData = await memberstack.getMemberJSON();
memberData.data = memberData.data || {};
memberData.data.updatesID = newUpdatesID;
console.log(`Updates ID in JSON after update: ${newUpdatesID}`);
await memberstack.updateMemberJSON({ json: memberData.data });
} catch (error) {
console.error(`Error in updateUpdatesIDInJson function: ${error}`);
}
}
async function checkAndUpdateUI() {
try {
const element = document.querySelector('[ms-code-update-item]');
const cmsItem = element.textContent;
console.log(`CMS item: ${cmsItem}`);
// Get the current updates ID from JSON
const updatesIDFromJson = await getUpdatesIDFromJson();
console.log(`Updates ID from JSON: ${updatesIDFromJson}`);
// Check displayForNewUsers variable to decide behavior
if (displayForNewUsers === 'NO' && !updatesIDFromJson) {
console.log('Updates ID from JSON is undefined, null, or empty, not changing UI');
return;
}
if (cmsItem !== updatesIDFromJson) {
const uiElements = document.querySelectorAll('[ms-code-update-ui]');
uiElements.forEach(uiElement => {
uiElement.style.display = 'block';
uiElement.style.opacity = '1';
});
}
// Update the updates ID in JSON after the UI has been updated
await updateUpdatesIDInJson(cmsItem);
} catch (error) {
console.error(`Error in checkAndUpdateUI function: ${error}`);
}
}
// Check and update UI when the page loads
checkAndUpdateUI().catch(error => {
console.error(`Error in initial functions: ${error}`);
});
});
</script>
<!-- 💙 MEMBERSCRIPT #69 v0.1 💙 DISPLAY ELEMENT IF NEW CMS ITEMS -->
<script>
document.addEventListener('DOMContentLoaded', async function() {
const memberstack = window.$memberstackDom;
// Set this variable to 'YES' or 'NO' depending on whether you want the UI to be displayed for new users
const displayForNewUsers = 'YES';
// Only proceed if a member is found
const member = await memberstack.getCurrentMember();
if (!member) {
console.log('No member found, exiting script');
return;
}
async function getUpdatesIDFromJson() {
try {
const memberData = await memberstack.getMemberJSON();
console.log(`Member data: ${JSON.stringify(memberData)}`);
return memberData?.data?.updatesID || '';
} catch (error) {
console.error(`Error in getUpdatesIDFromJson function: ${error}`);
}
}
async function updateUpdatesIDInJson(newUpdatesID) {
try {
const memberData = await memberstack.getMemberJSON();
memberData.data = memberData.data || {};
memberData.data.updatesID = newUpdatesID;
console.log(`Updates ID in JSON after update: ${newUpdatesID}`);
await memberstack.updateMemberJSON({ json: memberData.data });
} catch (error) {
console.error(`Error in updateUpdatesIDInJson function: ${error}`);
}
}
async function checkAndUpdateUI() {
try {
const element = document.querySelector('[ms-code-update-item]');
const cmsItem = element.textContent;
console.log(`CMS item: ${cmsItem}`);
// Get the current updates ID from JSON
const updatesIDFromJson = await getUpdatesIDFromJson();
console.log(`Updates ID from JSON: ${updatesIDFromJson}`);
// Check displayForNewUsers variable to decide behavior
if (displayForNewUsers === 'NO' && !updatesIDFromJson) {
console.log('Updates ID from JSON is undefined, null, or empty, not changing UI');
return;
}
if (cmsItem !== updatesIDFromJson) {
const uiElements = document.querySelectorAll('[ms-code-update-ui]');
uiElements.forEach(uiElement => {
uiElement.style.display = 'block';
uiElement.style.opacity = '1';
});
}
// Update the updates ID in JSON after the UI has been updated
await updateUpdatesIDInJson(cmsItem);
} catch (error) {
console.error(`Error in checkAndUpdateUI function: ${error}`);
}
}
// Check and update UI when the page loads
checkAndUpdateUI().catch(error => {
console.error(`Error in initial functions: ${error}`);
});
});
</script>

#68 - Mitgliedschaft verschenken
Ermöglichen Sie es den Mitgliedern, Geschenke für ihre Freunde und Familie zu kaufen.

#Nr. 67 - Formular auf Basis von URL-Parametern vorausfüllen
Einfaches Ausfüllen von Eingaben über URL-Parameter.
<!-- 💙 MEMBERSCRIPT #67 v0.1 💙 PREFILL INPUTS WITH URL PARAMETERS -->
<script>
// Function to get URL parameters
function getURLParams() {
const urlParams = new URLSearchParams(window.location.search);
return Object.fromEntries(urlParams.entries());
}
// Function to prefill inputs based on URL parameters
function prefillInputs() {
const urlParams = getURLParams();
const inputElements = document.querySelectorAll('[ms-code-prefill-param]');
inputElements.forEach((inputElement) => {
const paramKey = inputElement.getAttribute('ms-code-prefill-param');
if (paramKey && urlParams[paramKey]) {
inputElement.value = urlParams[paramKey];
}
});
}
// Call the function to prefill inputs when the page loads
prefillInputs();
</script>
<!-- 💙 MEMBERSCRIPT #67 v0.1 💙 PREFILL INPUTS WITH URL PARAMETERS -->
<script>
// Function to get URL parameters
function getURLParams() {
const urlParams = new URLSearchParams(window.location.search);
return Object.fromEntries(urlParams.entries());
}
// Function to prefill inputs based on URL parameters
function prefillInputs() {
const urlParams = getURLParams();
const inputElements = document.querySelectorAll('[ms-code-prefill-param]');
inputElements.forEach((inputElement) => {
const paramKey = inputElement.getAttribute('ms-code-prefill-param');
if (paramKey && urlParams[paramKey]) {
inputElement.value = urlParams[paramKey];
}
});
}
// Call the function to prefill inputs when the page loads
prefillInputs();
</script>

#Nr. 66 - Mitglieder-ID Einladungslinks
Erstellen Sie benutzerdefinierte, einzigartige Einladungs-/Verweisungslinks.
<!-- 💙 MEMBERSCRIPT #66 v0.1 💙 MEMBER ID INVITE LINKS -->
<script>
// Function to get the member ID from local storage
function getMemberIDFromLocalStorage() {
// Assuming "_ms-mem" is the key that holds the member object in local storage
const memberObject = JSON.parse(localStorage.getItem("_ms-mem"));
if (memberObject && memberObject.id) {
return memberObject.id;
}
return null;
}
// Function to update the invite link with the member ID as a URL parameter
function updateInviteLink() {
const inviteLinkElement = document.querySelector('[ms-code-invite-link]');
if (inviteLinkElement) {
const inviteLinkBase = inviteLinkElement.getAttribute('ms-code-invite-link');
const memberID = getMemberIDFromLocalStorage();
if (memberID) {
const inviteLinkWithID = `${inviteLinkBase}?inviteCode=${memberID}`;
inviteLinkElement.textContent = inviteLinkWithID;
inviteLinkElement.href = inviteLinkWithID; // If it's an anchor link
}
}
}
// Call the function to update the invite link when the page loads
updateInviteLink();
</script>
<!-- 💙 MEMBERSCRIPT #66 v0.1 💙 MEMBER ID INVITE LINKS -->
<script>
// Function to get the member ID from local storage
function getMemberIDFromLocalStorage() {
// Assuming "_ms-mem" is the key that holds the member object in local storage
const memberObject = JSON.parse(localStorage.getItem("_ms-mem"));
if (memberObject && memberObject.id) {
return memberObject.id;
}
return null;
}
// Function to update the invite link with the member ID as a URL parameter
function updateInviteLink() {
const inviteLinkElement = document.querySelector('[ms-code-invite-link]');
if (inviteLinkElement) {
const inviteLinkBase = inviteLinkElement.getAttribute('ms-code-invite-link');
const memberID = getMemberIDFromLocalStorage();
if (memberID) {
const inviteLinkWithID = `${inviteLinkBase}?inviteCode=${memberID}`;
inviteLinkElement.textContent = inviteLinkWithID;
inviteLinkElement.href = inviteLinkWithID; // If it's an anchor link
}
}
}
// Call the function to update the invite link when the page loads
updateInviteLink();
</script>

#Nr. 65 - Beendigungsabsichts-Popup
Zeigen Sie Besuchern ein Popup an, wenn sie mit der Maus nach oben gehen.
<!-- 💙 MEMBERSCRIPT #65 v0.1 💙 EXIT INTENT POPUP -->
<script>
const CookieService = {
setCookie(name, value, days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
const expires = days ? '; expires=' + date.toUTCString() : '';
document.cookie = name + '=' + (value || '') + expires + ';';
},
getCookie(name) {
const cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith(name))
?.split('=')[1];
return cookieValue || null;
}
};
const exitPopup = document.querySelector('[ms-code-popup="exit-intent"]');
const mouseEvent = e => {
const shouldShowExitIntent =
!e.toElement &&
!e.relatedTarget &&
e.clientY < 10;
if (shouldShowExitIntent) {
document.removeEventListener('mouseout', mouseEvent);
exitPopup.style.display = 'flex';
CookieService.setCookie('exitIntentShown', true, 30);
}
};
if (!CookieService.getCookie('exitIntentShown')) {
document.addEventListener('mouseout', mouseEvent);
document.addEventListener('keydown', exit);
exitPopup.addEventListener('click', exit);
}
</script>
<!-- 💙 MEMBERSCRIPT #65 v0.1 💙 EXIT INTENT POPUP -->
<script>
const CookieService = {
setCookie(name, value, days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
const expires = days ? '; expires=' + date.toUTCString() : '';
document.cookie = name + '=' + (value || '') + expires + ';';
},
getCookie(name) {
const cookieValue = document.cookie
.split('; ')
.find(row => row.startsWith(name))
?.split('=')[1];
return cookieValue || null;
}
};
const exitPopup = document.querySelector('[ms-code-popup="exit-intent"]');
const mouseEvent = e => {
const shouldShowExitIntent =
!e.toElement &&
!e.relatedTarget &&
e.clientY < 10;
if (shouldShowExitIntent) {
document.removeEventListener('mouseout', mouseEvent);
exitPopup.style.display = 'flex';
CookieService.setCookie('exitIntentShown', true, 30);
}
};
if (!CookieService.getCookie('exitIntentShown')) {
document.addEventListener('mouseout', mouseEvent);
document.addEventListener('keydown', exit);
exitPopup.addEventListener('click', exit);
}
</script>

#Nr. 64 - Radio Form Logic
Anzeige von Set-Elementen, je nachdem, welches Radio ausgewählt ist.
<!-- 💙 MEMBERSCRIPT #64 v0.1 💙 RADIO FORM LOGIC -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// initially hide all divs with 'ms-code-more-info' attribute
$("div[ms-code-more-info]").hide();
// listen for change events on all radios with 'ms-code-radio-option' attribute
$("input[ms-code-radio-option]").change(function() {
// hide all divs again
$("div[ms-code-more-info]").hide();
// get the value of the selected radio button
var selectedValue = $(this).attr("ms-code-radio-option");
// find the div with the 'ms-code-more-info' attribute that matches the selected value and show it
$("div[ms-code-more-info=" + selectedValue + "]").show();
});
});
</script>
<!-- 💙 MEMBERSCRIPT #64 v0.1 💙 RADIO FORM LOGIC -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
// initially hide all divs with 'ms-code-more-info' attribute
$("div[ms-code-more-info]").hide();
// listen for change events on all radios with 'ms-code-radio-option' attribute
$("input[ms-code-radio-option]").change(function() {
// hide all divs again
$("div[ms-code-more-info]").hide();
// get the value of the selected radio button
var selectedValue = $(this).attr("ms-code-radio-option");
// find the div with the 'ms-code-more-info' attribute that matches the selected value and show it
$("div[ms-code-more-info=" + selectedValue + "]").show();
});
});
</script>

#63 - Datumsbereichswähler
Erstellen Sie eine Datumsbereichseingabe in Webflow!
<!-- 💙 MEMBERSCRIPT #62 v0.1 💙 DATE RANGE PICKER -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
<style>
.daterangepicker td.active {
background-color: #006cfa !important ;
}
</style>
<script type="text/javascript">
$(function() {
$('input[ms-code-input="date-range"]').daterangepicker({
"opens": "center",
"locale": {
"format": "MM/DD/YYYY",
"separator": " - ",
"applyLabel": "Apply",
"cancelLabel": "Cancel",
"fromLabel": "From",
"toLabel": "To",
"customRangeLabel": "Custom",
"weekLabel": "W",
"daysOfWeek": [
"Su",
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa"
],
"monthNames": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
},
});
$('input[name="datefilter"]').on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('MM/DD/YYYY') + ' - ' + picker.endDate.format('MM/DD/YYYY'));
});
$('input[name="datefilter"]').on('cancel.daterangepicker', function(ev, picker) {
$(this).val('');
});
});
</script>
<!-- 💙 MEMBERSCRIPT #62 v0.1 💙 DATE RANGE PICKER -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
<style>
.daterangepicker td.active {
background-color: #006cfa !important ;
}
</style>
<script type="text/javascript">
$(function() {
$('input[ms-code-input="date-range"]').daterangepicker({
"opens": "center",
"locale": {
"format": "MM/DD/YYYY",
"separator": " - ",
"applyLabel": "Apply",
"cancelLabel": "Cancel",
"fromLabel": "From",
"toLabel": "To",
"customRangeLabel": "Custom",
"weekLabel": "W",
"daysOfWeek": [
"Su",
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa"
],
"monthNames": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
},
});
$('input[name="datefilter"]').on('apply.daterangepicker', function(ev, picker) {
$(this).val(picker.startDate.format('MM/DD/YYYY') + ' - ' + picker.endDate.format('MM/DD/YYYY'));
});
$('input[name="datefilter"]').on('cancel.daterangepicker', function(ev, picker) {
$(this).val('');
});
});
</script>

#62 - Upvote-Taste
Hinzufügen der Upvote-Funktionalität zum Webflow CMS.
<!-- 💙 MEMBERSCRIPT #62 v0.2 💙 UPVOTE FORM -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const memberstack = window.$memberstackDom;
const upvoteButtons = document.querySelectorAll('[ms-code="upvote-button"]');
const upvoteForms = document.querySelectorAll('[ms-code="upvote-form"]');
const upvotedValues = document.querySelectorAll('[ms-code="upvoted-value"]');
const upvoteCounts = document.querySelectorAll('[ms-code="upvote-count"]');
let clickTimeout; // Variable to store the timer
let lastClickedButton = null; // Variable to store the last clicked button
// Function to handle upvote button click
function handleUpvoteButtonClick(event) {
event.preventDefault();
const button = event.currentTarget;
// Clear the timer if the same button is clicked
if (button === lastClickedButton) {
clearTimeout(clickTimeout);
}
lastClickedButton = button; // Store the reference to the currently clicked button
// Set a new timer
clickTimeout = setTimeout(function() {
const form = button.closest('form');
const cmsId = button.getAttribute('data-cms-id');
const upvotedValue = form.querySelector('[ms-code="upvoted-value"]');
const upvoteCount = form.querySelector('[ms-code="upvote-count"]');
if (button.classList.contains('is-true')) {
// Remove upvote
button.classList.remove('is-true');
upvotedValue.value = 'false';
upvoteCount.textContent = parseInt(upvoteCount.textContent) - 1;
memberstack.getMemberJSON()
.then(function(memberData) {
if (memberData.data && memberData.data.upvotes) {
const upvotes = memberData.data.upvotes;
const index = upvotes.indexOf(cmsId);
if (index !== -1) {
upvotes.splice(index, 1);
memberstack.updateMemberJSON({ json: memberData.data });
}
}
})
.catch(function(error) {
console.error('Error retrieving/updating member data:', error);
});
} else {
// Add upvote
button.classList.add('is-true');
upvotedValue.value = 'true';
upvoteCount.textContent = parseInt(upvoteCount.textContent) + 1;
memberstack.getMemberJSON()
.then(function(memberData) {
memberData.data = memberData.data || {};
memberData.data.upvotes = memberData.data.upvotes || [];
memberData.data.upvotes.push(cmsId);
memberstack.updateMemberJSON({ json: memberData.data });
})
.catch(function(error) {
console.error('Error retrieving/updating member data:', error);
});
}
// Make the API call
fetch(form.action, {
method: form.method,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(new FormData(form))
})
.then(function(response) {
if (response.ok) {
// Handle successful API response
return response.json();
} else {
// Handle API error
throw new Error('API Error');
}
})
.then(function(data) {
// Handle API response to update vote count
upvoteCount.textContent = data.upvoteCount; // Replace with the actual property holding the updated vote count
})
.catch(function(error) {
console.error('API Error:', error);
});
}, 200); // 0.2 seconds
}
// Attach event listeners to upvote buttons
upvoteButtons.forEach(function(button) {
button.addEventListener('click', handleUpvoteButtonClick);
});
// Check if member has upvotes on page load
memberstack.getMemberJSON()
.then(function(memberData) {
if (memberData.data && memberData.data.upvotes) {
const upvotes = memberData.data.upvotes;
upvoteButtons.forEach(function(button) {
const cmsId = button.getAttribute('data-cms-id');
if (upvotes.includes(cmsId)) {
button.classList.add('is-true');
const form = button.closest('form');
const upvotedValue = form.querySelector('[ms-code="upvoted-value"]');
upvotedValue.value = 'true';
}
});
}
})
.catch(function(error) {
console.error('Error retrieving member data:', error);
});
});
</script>
<!-- 💙 MEMBERSCRIPT #62 v0.2 💙 UPVOTE FORM -->
<script>
document.addEventListener('DOMContentLoaded', function() {
const memberstack = window.$memberstackDom;
const upvoteButtons = document.querySelectorAll('[ms-code="upvote-button"]');
const upvoteForms = document.querySelectorAll('[ms-code="upvote-form"]');
const upvotedValues = document.querySelectorAll('[ms-code="upvoted-value"]');
const upvoteCounts = document.querySelectorAll('[ms-code="upvote-count"]');
let clickTimeout; // Variable to store the timer
let lastClickedButton = null; // Variable to store the last clicked button
// Function to handle upvote button click
function handleUpvoteButtonClick(event) {
event.preventDefault();
const button = event.currentTarget;
// Clear the timer if the same button is clicked
if (button === lastClickedButton) {
clearTimeout(clickTimeout);
}
lastClickedButton = button; // Store the reference to the currently clicked button
// Set a new timer
clickTimeout = setTimeout(function() {
const form = button.closest('form');
const cmsId = button.getAttribute('data-cms-id');
const upvotedValue = form.querySelector('[ms-code="upvoted-value"]');
const upvoteCount = form.querySelector('[ms-code="upvote-count"]');
if (button.classList.contains('is-true')) {
// Remove upvote
button.classList.remove('is-true');
upvotedValue.value = 'false';
upvoteCount.textContent = parseInt(upvoteCount.textContent) - 1;
memberstack.getMemberJSON()
.then(function(memberData) {
if (memberData.data && memberData.data.upvotes) {
const upvotes = memberData.data.upvotes;
const index = upvotes.indexOf(cmsId);
if (index !== -1) {
upvotes.splice(index, 1);
memberstack.updateMemberJSON({ json: memberData.data });
}
}
})
.catch(function(error) {
console.error('Error retrieving/updating member data:', error);
});
} else {
// Add upvote
button.classList.add('is-true');
upvotedValue.value = 'true';
upvoteCount.textContent = parseInt(upvoteCount.textContent) + 1;
memberstack.getMemberJSON()
.then(function(memberData) {
memberData.data = memberData.data || {};
memberData.data.upvotes = memberData.data.upvotes || [];
memberData.data.upvotes.push(cmsId);
memberstack.updateMemberJSON({ json: memberData.data });
})
.catch(function(error) {
console.error('Error retrieving/updating member data:', error);
});
}
// Make the API call
fetch(form.action, {
method: form.method,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams(new FormData(form))
})
.then(function(response) {
if (response.ok) {
// Handle successful API response
return response.json();
} else {
// Handle API error
throw new Error('API Error');
}
})
.then(function(data) {
// Handle API response to update vote count
upvoteCount.textContent = data.upvoteCount; // Replace with the actual property holding the updated vote count
})
.catch(function(error) {
console.error('API Error:', error);
});
}, 200); // 0.2 seconds
}
// Attach event listeners to upvote buttons
upvoteButtons.forEach(function(button) {
button.addEventListener('click', handleUpvoteButtonClick);
});
// Check if member has upvotes on page load
memberstack.getMemberJSON()
.then(function(memberData) {
if (memberData.data && memberData.data.upvotes) {
const upvotes = memberData.data.upvotes;
upvoteButtons.forEach(function(button) {
const cmsId = button.getAttribute('data-cms-id');
if (upvotes.includes(cmsId)) {
button.classList.add('is-true');
const form = button.closest('form');
const upvotedValue = form.querySelector('[ms-code="upvoted-value"]');
upvotedValue.value = 'true';
}
});
}
})
.catch(function(error) {
console.error('Error retrieving member data:', error);
});
});
</script>

#61 - Element anzeigen, wenn das Kontrollkästchen aktiviert ist
Erstellen Sie eine bedingte Sichtbarkeit basierend auf einem Kontrollkästchenfeld.
<!-- 💙 MEMBERSCRIPT #61 v0.1 💙 SHOW ELEMENT IF CHECKBOX IS CHECKED -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"> </script>
<script>
$(document).ready(function() {
// Initially hide all elements with the 'ms-code-checkbox-display' attribute
$("[ms-code-checkbox-display]").hide();
// When a checkbox with 'ms-code-checkbox-input' attribute is clicked, perform the following
$("[ms-code-checkbox-input]").click(function() {
// Get the value of the 'ms-code-checkbox-input' attribute
var checkboxVal = $(this).attr('ms-code-checkbox-input');
// Find the corresponding element with the 'ms-code-checkbox-display' attribute and same value
var displayElement = $("[ms-code-checkbox-display=" + checkboxVal + "]");
// If this checkbox is checked, show the corresponding element
if ($(this).is(":checked")) {
displayElement.show();
} else {
// If this checkbox is unchecked, hide the corresponding element
displayElement.hide();
}
});
});
</script>
<!-- 💙 MEMBERSCRIPT #61 v0.1 💙 SHOW ELEMENT IF CHECKBOX IS CHECKED -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"> </script>
<script>
$(document).ready(function() {
// Initially hide all elements with the 'ms-code-checkbox-display' attribute
$("[ms-code-checkbox-display]").hide();
// When a checkbox with 'ms-code-checkbox-input' attribute is clicked, perform the following
$("[ms-code-checkbox-input]").click(function() {
// Get the value of the 'ms-code-checkbox-input' attribute
var checkboxVal = $(this).attr('ms-code-checkbox-input');
// Find the corresponding element with the 'ms-code-checkbox-display' attribute and same value
var displayElement = $("[ms-code-checkbox-display=" + checkboxVal + "]");
// If this checkbox is checked, show the corresponding element
if ($(this).is(":checked")) {
displayElement.show();
} else {
// If this checkbox is unchecked, hide the corresponding element
displayElement.hide();
}
});
});
</script>

#Nr. 60 - Wert erhöhen/verringern auswählen
Erstellen Sie vorherige und nächste Schaltflächen für ein Auswahlfeld.
<!-- 💙 MEMBERSCRIPT #60 v0.1 💙 INCREASE/DECREASE SELECT VALUE -->
<script>
var select = document.querySelector('[ms-code-select="input"]');
var prev = document.querySelector('[ms-code-select="prev"]');
var next = document.querySelector('[ms-code-select="next"]');
function updateButtons() {
prev.style.opacity = select.selectedIndex === 0 ? '0.5' : '1';
next.style.opacity = select.selectedIndex === select.options.length - 1 ? '0.5' : '1';
}
prev.addEventListener('click', function() {
if (select.selectedIndex > 0) {
select.selectedIndex--;
}
updateButtons();
});
next.addEventListener('click', function() {
if (select.selectedIndex < select.options.length - 1) {
select.selectedIndex++;
}
updateButtons();
});
updateButtons();
</script>
<!-- 💙 MEMBERSCRIPT #60 v0.1 💙 INCREASE/DECREASE SELECT VALUE -->
<script>
var select = document.querySelector('[ms-code-select="input"]');
var prev = document.querySelector('[ms-code-select="prev"]');
var next = document.querySelector('[ms-code-select="next"]');
function updateButtons() {
prev.style.opacity = select.selectedIndex === 0 ? '0.5' : '1';
next.style.opacity = select.selectedIndex === select.options.length - 1 ? '0.5' : '1';
}
prev.addEventListener('click', function() {
if (select.selectedIndex > 0) {
select.selectedIndex--;
}
updateButtons();
});
next.addEventListener('click', function() {
if (select.selectedIndex < select.options.length - 1) {
select.selectedIndex++;
}
updateButtons();
});
updateButtons();
</script>

#59 - GIF bei Hover neu starten
Starten Sie ein GIF von Anfang an, wenn Sie den Mauszeiger bewegen.
<!-- 💙 MEMBERSCRIPT #59 v0.1 💙 RESTART GIF -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const hoverElements = document.querySelectorAll('[data-gif-hover]');
hoverElements.forEach((element) => {
element.addEventListener('mouseover', function() {
const gifNum = this.getAttribute('data-gif-hover');
const gifElement = document.querySelector(`[data-gif="${gifNum}"]`);
if (gifElement) {
const gifSrc = gifElement.getAttribute('src');
gifElement.setAttribute('src', '');
gifElement.setAttribute('src', gifSrc);
}
});
});
});
</script>
<!-- 💙 MEMBERSCRIPT #59 v0.1 💙 RESTART GIF -->
<script>
document.addEventListener('DOMContentLoaded', (event) => {
const hoverElements = document.querySelectorAll('[data-gif-hover]');
hoverElements.forEach((element) => {
element.addEventListener('mouseover', function() {
const gifNum = this.getAttribute('data-gif-hover');
const gifElement = document.querySelector(`[data-gif="${gifNum}"]`);
if (gifElement) {
const gifSrc = gifElement.getAttribute('src');
gifElement.setAttribute('src', '');
gifElement.setAttribute('src', gifSrc);
}
});
});
});
</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.