1/** 2 * Returns true when the question is visible to the user. 3 * Hidden questions or questions inside hidden ancestors are skipped. 4 * 5 * @param {HTMLElement} questionEl 6 * @returns {boolean} 7 */ 8function isVisibleQuestion(questionEl) { 9 return !questionEl.hidden && !questionEl.closest('[hidden]'); 10} 11 12/** 13 * Validates visible selection-configuration dropdown questions on the page. 14 * Shows the authored validation message when no value is selected and focuses 15 * the first invalid control. 16 * 17 * @param {ParentNode} [root=document] 18 * @returns {boolean} 19 */ 20export default function validateSelectionConfigurationDropdowns(root = document) { 21 const dropdownQuestions = [...root.querySelectorAll( 22 '.selection-configuration-question[data-question-type="dropdown"]', 23 )].filter(isVisibleQuestion); 24 25 let firstInvalidControl = null; 26 let hasInvalidDropdown = false; 27 28 dropdownQuestions.forEach((questionEl) => { 29 const selectEl = questionEl.querySelector('.selection-configuration-select'); 30 if (!selectEl) return; 31 32 const hasSelection = Boolean(selectEl.value); 33 const validationEl = questionEl.querySelector('.selection-configuration-validation'); 34 35 if (validationEl) { 36 validationEl.hidden = hasSelection; 37 } 38 39 if (hasSelection) return; 40 41 hasInvalidDropdown = true; 42 if (firstInvalidControl) return; 43 44 firstInvalidControl = questionEl.querySelector('.selection-configuration-flag-trigger') 45 || selectEl; 46 }); 47 48 if (firstInvalidControl) { 49 firstInvalidControl.focus(); 50 } 51 52 return !hasInvalidDropdown; 53}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.