Development
...
PulseCheck - Done
PulseCheck Settings - Done
6 min
view live example https //userfirst factory webflow\ io/360pulse/pulsechecks settings tabs docid\ j6ajv98j1nwdqe1c8avqe docid\ tjdh7vpw7uwalo1lqqvon docid\ ge0u bj8xijgwa 3zy8bj html pulsechecks / {pulsecheck name e g client happiness} / settings {pulsecheck name} settings configure and manage your pulsecheck survey view pulsecheck pulsecheck audience review platforms powered by user first privacy terms of use tabs the pulsecheck settings screen contains a series of tabs docid\ j6ajv98j1nwdqe1c8avqe docid\ tjdh7vpw7uwalo1lqqvon docid\ ge0u bj8xijgwa 3zy8bj scripts toggle uses docid\ zwx7zrei1pamocps88irx rounded corner slider \<script> // rounded corner slider document addeventlistener('domcontentloaded', function() { var slider = document getelementbyid('radius slider'); var example = document getelementbyid('radius example'); // additional classes to update var additionalclasses = \[ ' pulsecheck preview', ' pulsecheck question option', ' pulsecheck question comment', ' referral question option', ' pulsecheck complete button' ]; if (slider && example) { function updateradius() { var radius = parsefloat(slider value) tofixed(2); // update the example element example style borderradius = radius + 'rem'; // update all elements with the additional classes additionalclasses foreach(function(classname) { var elements = document queryselectorall(classname); elements foreach(function(element) { element style borderradius = radius + 'rem'; }); }); } // initial update updateradius(); // add event listeners slider addeventlistener('input', updateradius); slider addeventlistener('change', updateradius); } var arrowsvg = ` \<svg width="16" height="16" fill="currentcolor" xmlns="http //www w3 org/2000/svg" viewbox="0 0 32 32"> \<polygon points="22 6 22 8 9 41 8 26 24 59 24 59 26 8 9 41 8 22 6 22 6 6 22 6" /> \</svg> `; var corners = \[ { top '0 5rem', left '0 5rem', rotation '0deg' }, { top '0 5rem', right '0 5rem', rotation '90deg' }, { bottom '0 5rem', right '0 5rem', rotation '180deg' }, { bottom '0 5rem', left '0 5rem', rotation '270deg' } ]; if (example) { corners foreach(function(corner) { var arrowdiv = document createelement('div'); arrowdiv classlist add('corner arrow'); arrowdiv innerhtml = arrowsvg; if (corner top) arrowdiv style top = corner top; if (corner right) arrowdiv style right = corner right; if (corner bottom) arrowdiv style bottom = corner bottom; if (corner left) arrowdiv style left = corner left; arrowdiv style transform = 'rotate(' + corner rotation + ')'; example appendchild(arrowdiv); }); } }); \</script> \<style> input\[type="range"] { webkit appearance none; width 200px; background transparent; margin 0; } input\[type="range"]\ focus { outline none; } / chrome, safari, opera / input\[type="range"] webkit slider runnable track { width 100%; height 8px; background var( brand colors gray 300); border radius 5px; cursor pointer; } input\[type="range"] webkit slider thumb { webkit appearance none; height 20px; width 20px; margin top 6px; background var( brand colors brand 600); border 1px solid var( brand colors brand 600); border radius 50%; cursor pointer; transition background 0 3s; } input\[type="range"] webkit slider thumb\ hover { background var( brand colors brand 700); } / firefox / input\[type="range"] moz range track { width 100%; height 8px; background var( brand colors gray 300); border radius 5px; cursor pointer; } input\[type="range"] moz range thumb { height 20px; width 20px; background var( brand colors brand 600); border 1px solid var( brand colors brand 600); border radius 50%; cursor pointer; transition background 0 3s; } input\[type="range"] moz range thumb\ hover { background var( brand colors brand 700); } / internet explorer / input\[type="range"] ms track { width 100%; height 8px; background transparent; border color transparent; color transparent; cursor pointer; } input\[type="range"] ms fill lower { background var( brand colors gray 300); border radius 5px; } input\[type="range"] ms fill upper { background var( brand colors gray 300); border radius 5px; } input\[type="range"] ms thumb { height 20px; width 20px; background var( brand colors brand 600); border 1px solid var( brand colors brand 600); border radius 50%; cursor pointer; transition background 0 3s; } input\[type="range"] ms thumb\ hover { background var( brand colors brand 700); } corner arrow { position absolute; width 16px; height 16px; transform origin center center; } \</style> color picker \<script> / enhanced color picker with class update functionality finds all color picker groups on the page and initializes them supports updating css classes when color value changes format for data colorpicker update classes attribute basic "element property" with opacity "element property 0 5" hover state "element\ hover property" focus state "element\ focus property" with modifiers "element modifier property" multiple updates "element1 property1, element2 property2" supported properties color backgroundcolor (converts to background color) bordercolor (converts to border color) outlinecolor (converts to outline color) placeholder (updates text placeholder color for inputs) / document addeventlistener('domcontentloaded', function() { // find all color picker groups on the page const colorpickergroups = document queryselectorall(' color picker'); colorpickergroups foreach(function(group) { try { // find inputs by type within this group const colorinput = group queryselector('input\[type="color"]'); const textinput = group queryselector('input\[type="text"]'); if (!colorinput || !textinput) return; // skip if missing required inputs // get initial color from data attribute or default to black let hexvalue = group getattribute('data colorpicker value') || '#000000'; // ensure hex value is properly formatted if (!hexvalue startswith('#')) { hexvalue = '#' + hexvalue; } // set initial values colorinput value = hexvalue; textinput value = hexvalue; // store rules by selector for opacity tracking const ruleregistry = {}; / updates css classes based on the color picker value @param {string} color the hex color value / function updateclasscolors(color) { try { const updateclassesattr = group getattribute('data colorpicker update classes'); if (!updateclassesattr) return; // parse the attribute value const classupdates = updateclassesattr split(',') map(item => item trim()); // create a unique id for these rules based on the group const groupid = group id || 'color picker ' + math random() tostring(36) substr(2, 9); classupdates foreach(function(update) { try { // initialize variables let selector = ''; let property = ''; let opacityvalue = 1; let propertywithoutopacity = update; // first check if the update includes an opacity value at the end if (update includes(' ')) { const parts = update split(' '); const lastpart = parts\[parts length 1]; // if the last part is a valid opacity value (0 1) if (!isnan(parsefloat(lastpart)) && parsefloat(lastpart) >= 0 && parsefloat(lastpart) <= 1) { opacityvalue = parsefloat(lastpart); // remove the opacity part from the update string propertywithoutopacity = parts slice(0, 1) join(' '); } } // now parse the selector and property if (propertywithoutopacity includes('\ hover ')) { // format class\ hover property const parts = propertywithoutopacity split('\ hover '); selector = ' ' + parts\[0] + '\ hover'; property = parts\[1]; } else if (propertywithoutopacity includes('\ focus ')) { // format class\ focus property const parts = propertywithoutopacity split('\ focus '); selector = ' ' + parts\[0] + '\ focus'; property = parts\[1]; } else if (propertywithoutopacity includes(' ')) { // split by dot const parts = propertywithoutopacity split(' '); // the property is always the last part property = parts pop(); // check if we have css property names that might be mistaken as part of the selector const cssproperties = \['color', 'backgroundcolor', 'bordercolor', 'outlinecolor', 'placeholder']; if (parts length > 0 && cssproperties includes(property tolowercase())) { // create the selector by joining all parts but the last one selector = ' ' + parts join(' '); } else { return; // skip if format is invalid } } else { return; // skip if format is invalid } // convert property to standard css property name let cssproperty = property tolowercase(); // convert camelcase to kebab case for css properties if (cssproperty === 'backgroundcolor') { cssproperty = 'background color'; } else if (cssproperty === 'bordercolor') { cssproperty = 'border color'; } else if (cssproperty === 'outlinecolor') { cssproperty = 'outline color'; } else if (cssproperty === 'placeholder') { // special case for placeholder text color cssproperty = 'color'; // we'll use this for the rule content } // create a rule id for this specific rule (for update tracking) const ruleid = `${groupid} ${selector replace(/\[^a z0 9]/gi, ' ')} ${cssproperty}`; // apply opacity to color if it's a background color property let finalcolor = color; if (cssproperty === 'background color' && opacityvalue !== 1) { // convert hex to rgb const r = parseint(color slice(1, 3), 16); const g = parseint(color slice(3, 5), 16); const b = parseint(color slice(5, 7), 16); finalcolor = `rgba(${r}, ${g}, ${b}, ${opacityvalue})`; } // store the selector and opacity for future reference if (!ruleregistry\[selector]) { ruleregistry\[selector] = {}; } ruleregistry\[selector] opacity = opacityvalue; // special handling for placeholder if (property tolowercase() === 'placeholder') { // for placeholder text, we need to create rules for all browser variants const placeholderselectors = \[ `${selector} placeholder`, `${selector} webkit input placeholder`, `${selector} moz placeholder`, `${selector} ms input placeholder`, `${selector} moz placeholder` ]; // create a rule for each placeholder selector variant placeholderselectors foreach(function(placeholderselector) { const placeholderruleid = `${groupid} ${placeholderselector replace(/\[^a z0 9]/gi, ' ')} color`; // apply opacity if needed let placeholdercolor = color; if (opacityvalue !== 1) { const r = parseint(color slice(1, 3), 16); const g = parseint(color slice(3, 5), 16); const b = parseint(color slice(5, 7), 16); placeholdercolor = `rgba(${r}, ${g}, ${b}, ${opacityvalue})`; } // create or update rule const existingrule = document getelementbyid(placeholderruleid); if (existingrule) { existingrule textcontent = `${placeholderselector} { color ${placeholdercolor} !important; }`; } else { const ruleelement = document createelement('style'); ruleelement id = placeholderruleid; ruleelement textcontent = `${placeholderselector} { color ${placeholdercolor} !important; }`; document head appendchild(ruleelement); } }); return; // skip the regular rule creation below } // check if we already have a style rule for this const existingrule = document getelementbyid(ruleid); if (existingrule) { // update existing rule existingrule textcontent = `${selector} { ${cssproperty} ${finalcolor} !important; }`; } else { // create a new style element for this specific rule const ruleelement = document createelement('style'); ruleelement id = ruleid; ruleelement textcontent = `${selector} { ${cssproperty} ${finalcolor} !important; }`; document head appendchild(ruleelement); } } catch (updateerror) { // silently handle individual update errors to not block other updates } }); } catch (error) { // silently handle errors in the update process } } // apply initial color update updateclasscolors(hexvalue); // update text input and classes when color picker changes colorinput addeventlistener('input', function() { textinput value = this value; group setattribute('data colorpicker value', this value); updateclasscolors(this value); }); // update color picker and classes when text input changes textinput addeventlistener('input', function() { let value = this value; // add # if missing if (value && value charat(0) !== '#') { value = '#' + value; } // only update if valid hex color if (/^#(\[0 9a f]{3}){1,2}$/i test(value)) { colorinput value = value; group setattribute('data colorpicker value', value); updateclasscolors(value); } }); // clean up text input value on blur textinput addeventlistener('blur', function() { try { // revert to color input's value if text is invalid if (!/^#(\[0 9a f]{3}){1,2}$/i test(this value)) { this value = colorinput value; } // ensure lowercase for consistency this value = this value tolowercase(); // update classes one more time in case the value was fixed updateclasscolors(this value); } catch (error) { // silently handle errors } }); } catch (error) { // silently handle errors for robustness } }); }); \</script>