v0.1

UX
#95 - Confeti al clic
¡Haz volar un divertido confeti al hacer clic!
Watch the video for step-by-step implementation instructions
<!-- 💙 MEMBERSCRIPT #214 v0.1 💙 DEPENDENT DROPDOWN FIELDS -->
<script>
(function() {
'use strict';
var defined = [];
function init() {
var parents = document.querySelectorAll('[ms-code-dropdown="parent"]');
parents.forEach(function(parent) {
var groupName = parent.getAttribute('ms-code-dropdown-group');
if (!groupName) return;
var children = document.querySelectorAll('[ms-code-dropdown="child"][ms-code-dropdown-parent="' + groupName + '"]');
children.forEach(function(child) {
if (defined.indexOf(child) === -1) {
setupChild(child);
defined.push(child);
}
});
parent.addEventListener('change', function() {
var selectedValue = parent.value;
children.forEach(function(child) {
filterChild(child, selectedValue);
});
});
var initialValue = parent.value;
children.forEach(function(child) {
filterChild(child, initialValue);
});
});
}
function parseOptionsConfig(str) {
if (!str || !str.trim()) return {};
str = str.trim();
if (str.charAt(0) === '{') {
try {
return JSON.parse(str);
} catch (e) {
console.error('MemberScript # number214: Invalid JSON in ms-code-dropdown-options');
return {};
}
}
var config = {};
var pairs = str.split(';');
for (var i = 0; i < pairs.length; i++) {
var part = pairs[i].trim();
if (!part) continue;
var colon = part.indexOf(':');
if (colon === -1) continue;
var key = part.slice(0, colon).trim();
var valuesStr = part.slice(colon + 1).trim();
var values = valuesStr ? valuesStr.split(',').map(function(v) { return v.trim(); }).filter(Boolean) : [];
config[key] = values;
}
return config;
}
function setupChild(child) {
var configAttr = child.getAttribute('ms-code-dropdown-options');
var config = parseOptionsConfig(configAttr || '');
var options = child.querySelectorAll('option');
var optionsData = [];
options.forEach(function(opt) {
optionsData.push({
value: opt.value,
text: opt.textContent,
element: opt
});
});
child._msDropdownConfig = config;
child._msDropdownOptions = optionsData;
}
function filterChild(child, parentValue) {
var config = child._msDropdownConfig;
var optionsData = child._msDropdownOptions;
if (!config || !optionsData) return;
var hideWhenEmpty = child.getAttribute('ms-code-dropdown-hide') === ' keywordtrue';
var wrapper = child.closest('[ms-code-dropdown-wrapper]') || child.parentElement;
var allowedValues = [];
if (config['*']) {
allowedValues = allowedValues.concat(config['*']);
}
if (parentValue && config[parentValue]) {
allowedValues = allowedValues.concat(config[parentValue]);
}
child.innerHTML = '';
var hasVisibleOptions = false;
optionsData.forEach(function(opt) {
if (opt.value === '') {
var placeholder = document.createElement('option');
placeholder.value = '';
placeholder.textContent = opt.text;
child.appendChild(placeholder);
return;
}
if (allowedValues.indexOf(opt.value) !== -1) {
var option = document.createElement('option');
option.value = opt.value;
option.textContent = opt.text;
child.appendChild(option);
hasVisibleOptions = true;
}
});
child.value = '';
if (hideWhenEmpty) {
if (!parentValue || !hasVisibleOptions) {
wrapper.style.display = 'none';
} else {
wrapper.style.display = '';
}
}
child.dispatchEvent(new Event('change', { bubbles: true }));
}
function refresh() {
defined = [];
init();
}
window.msDropdowns = {
refresh: refresh,
filter: function(groupName, value) {
var children = document.querySelectorAll('[ms-code-dropdown="child"][ms-code-dropdown-parent="' + groupName + '"]');
children.forEach(function(child) {
filterChild(child, value);
});
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>More scripts in Forms