Form - select

Size
10,146 Kb
Views
6,072

How do I make an form - select?

What is a form - select? How do you make a form - select? This script and codes were developed by Anthony Pothin on 17 January 2023, Tuesday.

Form - select Previews

Form - select - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>form - select</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <link rel="stylesheet" href="css/style.css">
</head>
<body> <!-- dependancies -->
<!-- custom option -->
<link rel="import" href="https://codepen.io/Thorien/pen/LVWwYM.html" />
<!-- custom scroll -->
<link rel="import" href="https://codepen.io/Thorien/pen/xGgMwV.html" />
<template id="overlay-select"> <style scoped="scoped"> /* overlay */ :host { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 10; display: flex; align-items: center; justify-content: center; flex-direction: column; display: -webkit-flex; -webkit-align-items: center; -webkit-justify-content: center; -webkit-flex-direction: column; -moz-user-select: -moz-none; -webkit-user-select: none; -khtml-user-select: none; -o-user-select: none; user-select: none; } /* box */ #select-box { background-color: white; flex: 0 1 auto; display: flex; flex-direction: column; align-items: stretch; -webkit-flex: 0 1 auto; display: -webkit-flex; -webkit-flex-direction: column; -webkit-align-items: stretch; overflow: hidden; } @media (min-width: 1024px) { #select-box { min-width: 300px; border-radius: 10px; } } @media (max-width: 1023px) { #select-box { width: 100%; height: 100%; } } /* label */ label { text-align: center; flex: 0 0 auto; -webkit-flex: 0 0 auto; color: white; } /* option list */ #option-list { display: flex; flex: 1 1 auto; flex-direction: column; align-items: stretch; display: -webkit-flex; -webkit-flex: 1 1 auto; -webkit-flex-direction: column; -webkit-align-items: stretch; color: rgba(0,0,0,0.8); } /* articles */ article { padding-top: 5px; padding-bottom: 5px; flex: 0 0 auto; -webkit-flex: 0 0 auto; overflow: hidden; cursor: pointer; text-align: center; } article:hover { background-color: rgba(0,0,0,0.1); } article.selected { color: #55ACEE; } article.disabled { color: rgb(188, 188, 188); } /* button */ button { flex: 0 0 auto; -webkit-flex: 0 0 auto; padding: 4px; color: rgba(250, 250, 250, 0.5); transition: color 0.2s ease; outline: none; } button:hover { color: white; } button:before { content: "\e607"; } /* divers */ button, label{ background-color: #E78B80; font-size: 30px; border-style: none; } label, article{ white-space: nowrap; text-overflow: ellipsis; } [class^="icon-"], [class*=" icon-"] { font-family: 'icomoon'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; /* Better Font Rendering =========== */ -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* surcharge */ /* overlay */ #overlay-select { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 10; display: flex; align-items: center; justify-content: center; flex-direction: column; display: -webkit-flex; -webkit-align-items: center; -webkit-justify-content: center; -webkit-flex-direction: column; -moz-user-select: -moz-none; -webkit-user-select: none; -khtml-user-select: none; -o-user-select: none; user-select: none; } </style> <div id="select-box"> <label></label> <c-scroll id='option-list'></c-scroll> <!--<div id='option-list'></div>--> <button type='button' class="icon-success"></button> </div>
</template>
<template id="cf-select"> <style scoped="scoped"> /* .valid / .invalid .required .empty .disabled .readonly */ /* host */ :host { min-width: 200px; max-width: 100%; flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: column; -webkit-align-items: stretch; margin-top: 13px; font-size: 18px; position: relative; outline: none; cursor: pointer; } :host(.disabled), :host(.readonly) { pointer-events: none; } :host(.empty), header { color: #BCBCBC; } /* header */ header { font-size: 12px; flex: 0 0 auto; display: flex; flex-direction: row; justify-content: space-between; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: row; -webkit-justify-content: space-between; -moz-user-select: -moz-none; -webkit-user-select: none; -khtml-user-select: none; -o-user-select: none; user-select: none; } :host(.empty.required.blur) header::after { content: "\2731"; color: #55ACEE; } ::content > label { font-size: 12px; color: rgb(188, 188, 188); cursor: pointer; } /* main */ main { position: relative; min-height: 24px; flex: 0 0 auto; display: flex; flex-direction: row; align-items: stretch; -webkit-flex: 0 0 auto; -webkit-display: flex; -webkit-flex-direction: row; -webkit-align-items: stretch; flex-wrap: wrap; } /* option */ cf-option { padding: 0; } ::content > cf-option:not([selected]) { display: none; } :host(.invalid:not(.empty)) ::content > cf-option { color: #ea7166; } :host([multiple]) ::content > cf-option[selected]::after { content: ","; padding-right: 4px; } /* underline */ hr { border-color: #55ACEE; border-style: solid; border-width: 0; border-top-width: 1px; margin: 0; } :host(.focus) hr { border-color: #55ACEE !important; border-top-width: 2px; } :host(.blur) hr { margin-bottom: 1px; } :host(.disabled) hr, :host(.readonly) hr { border-style: dashed; } :host(.disabled) hr { border-color: transparent; } :host(.readonly) hr { border-color: rgba(0, 0, 0, 0.5); } :host(.invalid.blur:not(.empty)) hr { border-color: #ea7166; } /* surcharge */ /* host */ cf-select { min-width: 200px; max-width: 100%; flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: column; -webkit-align-items: stretch; margin-top: 13px; font-size: 18px; position: relative; outline: none; cursor: pointer; } cf-select.disabled, cf-select.readonly { pointer-events: none; } cf-select.empty, header { color: #BCBCBC; } cf-select > header > label { font-size: 12px; color: rgb(188, 188, 188); cursor: pointer; } cf-select.empty.required.blur header::after { content: "\2731"; color: #55ACEE; } /* option */ cf-select cf-option { color: black; } cf-select.invalid:not(.empty) cf-option{ color: #ea7166; } cf-select[multiple] cf-option[selected]::after { content: ","; padding-right: 4px; } cf-option:not([selected]) { display: none; } /* underline */ cf-select.focus hr { border-color: #55ACEE !important; border-top-width: 2px; } cf-select.blur hr { margin-bottom: 1px; } cf-select.disabled hr, cf-select.readonly hr { border-style: dashed; } cf-select.disabled hr { border-color: transparent; } cf-select.readonly hr { border-color: rgba(0, 0, 0, 0.5); } cf-select.invalid hr { border-color: #ea7166; } </style> <header> <content select="label"></content> </header> <main> <content select="cf-option"></content> </main> <hr />
</template>
<script> var HTMLCustomSelectElement = (function() { var parentDoc = (document._currentScript || document.currentScript).ownerDocument; /* notifier custom form */ document.dispatchEvent(new CustomEvent('customFormElementRegistration', { bubbles: false, cancelable: false, detail: 'cf-select' })); /* création de l'overlay */ var overlaySelect = document.createElement('div'); overlaySelect.id = "overlay-select"; overlaySelect.style.display = 'none'; // création shadow root overlaySelect.createShadowRoot(); // ajout contenu template overlaySelect.shadowRoot.appendChild(document.importNode(parentDoc.querySelector('template#overlay-select').content, true)); // ajout propriété overlaySelect.currentSelect = null; // ajout méthodes overlaySelect.open = function(HTMLCustomSelectElement) { if (overlaySelect.currentSelect) { console.error('unable to open overlaySelect for', HTMLCustomSelectElement, 'overlaySelect is currently used for', overlaySelect.currentSelect); return; } overlaySelect.currentSelect = HTMLCustomSelectElement; // stuff var optionList = HTMLCustomSelectElement.querySelectorAll('cf-option'); var articleWrapper = overlaySelect.shadowRoot.querySelector('#option-list'); // créer label var label = HTMLCustomSelectElement.querySelector('label'); overlaySelect.shadowRoot.querySelector('label').textContent = (label ? label.textContent : null); // créer les articles for (var i=0, iMax=optionList.length, article, flag=true ; i<iMax; i++) { article = document.createElement('article'); if (optionList.item(i).hasAttribute('disabled')) { article.classList.add('disabled'); } if (optionList.item(i).hasAttribute('selected') && flag) { article.classList.add('selected'); if (!HTMLCustomSelectElement.multiple) { flag = false; } } article.textContent = optionList.item(i).textContent; article.value = optionList.item(i).value; articleWrapper.appendChild(article); } // s'afficher overlaySelect.style.display = null; }; overlaySelect.close = function() { // stuff var articleWrapper = overlaySelect.shadowRoot.querySelector('#option-list'); var articleList = articleWrapper.querySelectorAll('article'); var optionList = overlaySelect.currentSelect.querySelectorAll('cf-option'); // se cacher overlaySelect.style.display = 'none'; // virer label overlaySelect.shadowRoot.querySelector('label').textContent = null; for (var i=0, iMax=articleList.length, option ; i<iMax; i++) { for (var j=0, jMax=optionList.length; j<jMax; j++) { if (articleList.item(i).value === optionList.item(j).value) { option = optionList.item(j); break; } } // mettre à jour les options if (articleList.item(i).classList.contains('selected')) { option.setAttribute('selected', 'selected'); } else { option.removeAttribute('selected'); } // supprimer les articles articleWrapper.removeChild(articleList.item(i)); } overlaySelect.currentSelect.checkValidity(); overlaySelect.currentSelect = null; }; overlaySelect.onArticlePointered = function(event) { if (event.target.tagName.toLowerCase() !== 'article' || event.target.classList.contains('disabled')) { return; } if (overlaySelect.currentSelect.multiple) { if (event.target.classList.contains('selected')) { event.target.classList.remove('selected'); } else { event.target.classList.add('selected'); } } else if (!event.target.classList.contains('selected')){ var articleList = overlaySelect.shadowRoot.querySelectorAll('.selected'); for (var i=0, iMax=articleList.length; i<iMax; i++) { articleList.item(i).classList.remove('selected'); } //overlaySelect.shadowRoot.querySelector('.selected').remove('selected'); event.target.classList.add('selected'); overlaySelect.close(); } }; // ajout event overlaySelect.shadowRoot.querySelector('button').addEventListener('tap', overlaySelect.close, false); overlaySelect.shadowRoot.querySelector('#option-list').addEventListener('tap', overlaySelect.onArticlePointered, false); // ajout dom document.body.appendChild(overlaySelect); // fonctions privées var onTap = function(event) { if (!event.currentTarget.disabled && !event.currentTarget.readOnly) { overlaySelect.open(event.currentTarget); } } // quand un noeud est ajouté ou retiré ou que son selected change function onMutation(mutationRecords, mutationObserver) { //console.warn('onMutation', mutationRecords, mutationObserver, this) var change = false; for (var k=0, kMax=mutationRecords.length; k<kMax; k++) { var mutationRecord = mutationRecords[k]; // ajout ou retrait d'option if (mutationRecord.target === this && mutationRecord.type === 'childList') { if (mutationRecord.addedNodes.length > 0) { // noeuds ajoutés Array.prototype.forEach.call(mutationRecord.addedNodes, function(option) { if (option.selected) { change = true; } }); } if (mutationRecord.removedNodes.length > 0) { // noeuds supprimés Array.prototype.forEach.call(mutationRecord.removedNodes, function(option) { if (option.selected) { change = true; } }); } } if (mutationRecord.target instanceof HTMLCustomOptionElement && mutationRecord.type === 'attributes' && mutationRecord.attributeName === 'selected') { change = true; } } if (change) { this.checkValidity(); this.dispatchEvent(new Event('change', {bubbles: true})); } } // objet custom return document.registerElement('cf-select', { prototype: Object.create(HTMLElement.prototype, { // constructeur createdCallback: { value: function() { // création shadow root this.createShadowRoot(); // ajout contenu depuis le template var cloneTemplate = document.importNode(parentDoc.querySelector('template#cf-select').content, true); this.shadowRoot.appendChild(cloneTemplate); // ajout event interaction // propriétés custom avec stockage caché // ajout event propriété Object.observe(this, function(changes) { changes.forEach(function(change) { // change === {name (nom propriété), object (l'objet observé), type (add, update, delete), oldValue} //console.info('Object.observe', change.object, change.name, 'qui valait', change.oldValue, 'vaut désormais', change.object[change.name]); // stuff switch (change.name) { case 'active': if (change.object[change.name]) { change.object.classList.add('focus'); change.object.classList.remove('blur'); } else { change.object.classList.add('blur'); change.object.classList.remove('focus'); } change.object.checkValidity(); break; default: break; } }); }); // initialisation (function() { var nodeList = this.querySelectorAll('cf-option'); for (var i=0, iMax=nodeList.length; i<iMax; i++) { this.add(nodeList.item(i)); } }).apply(this); if (this.hasAttribute('required')) { this.classList.add('required'); } else { this.classList.remove('required'); } if (this.hasAttribute('disabled')) { this.classList.add('disabled'); } else { this.classList.remove('disabled'); } if (this.hasAttribute('readonly')) { this.classList.add('readonly'); } else { this.classList.remove('readonly'); } if (this.hasAttribute('disabled') || this.hasAttribute('readonly')) { this.setAttribute('tabindex', '-1'); } else { this.setAttribute('tabindex', '0'); } this.active = false; //this.reset(); // création mutation observer this.mutationObserver = new MutationObserver(onMutation.bind(this)); } }, // propriétés custom active: { value: false, writable: true }, name: { get: function() { return this.getAttribute('name'); }, set: function(value) { var oldValue = this.getAttribute('name'); this.setAttribute('name', value); Object.getNotifier(this).notify({ type: 'update', name: 'name', oldValue: oldValue }); } }, required: { get: function() { return this.hasAttribute('required'); }, set: function(value) { var oldValue = this.hasAttribute('required'); if (value) { this.setAttribute('required', 'required'); } else { this.removeAttribute('required'); } Object.getNotifier(this).notify({ type: 'update', name: 'required', oldValue: oldValue }); } }, disabled: { get: function() { return this.hasAttribute('disabled'); }, set: function(value) { var oldValue = this.hasAttribute('disabled'); if (value) { this.setAttribute('disabled', 'disabled'); } else { this.removeAttribute('disabled'); } Object.getNotifier(this).notify({ type: 'update', name: 'disabled', oldValue: oldValue }); } }, readOnly: { get: function() { return this.hasAttribute('readonly'); }, set: function(value) { var oldValue = this.hasAttribute('readonly'); if (value) { this.setAttribute('readonly', 'readonly'); } else { this.removeAttribute('readonly'); } Object.getNotifier(this).notify({ type: 'update', name: 'readonly', oldValue: oldValue }); } }, multiple: { get: function() { return this.hasAttribute('multiple'); }, set: function(value) { var oldValue = this.hasAttribute('multiple'); if (value) { this.setAttribute('multiple', 'multiple'); } else { this.removeAttribute('multiple'); } Object.getNotifier(this).notify({ type: 'update', name: 'multiple', oldValue: oldValue }); } }, value: { get: function() { if (this.multiple) { var nodeList = this.querySelectorAll('cf-option[selected]'); var values = []; for (var i=0, iMax=nodeList.length; i<iMax; i++) { values.push(nodeList.item(i).value); } if (values.length > 1) { return JSON.stringify(values) } else if (values.length === 1) { return values[0] } else { return null; } } else { return this.querySelector('cf-option[selected]') ? this.querySelector('cf-option[selected]').value : null; } }, set: function(value) { if (typeof value !== 'string') { return; } Array.prototype.forEach.call(this.querySelectorAll('cf-option'), function(option) { option.selected = false; }); var parsedValue = JSON.parse(value); if (parsedValue instanceof Array) { if (!this.multiple) { return; } Array.prototype.forEach.call(this.querySelectorAll('cf-option'), function(option) { if (parsedValue.indexOf(option.value) !== -1) { option.selected = true; } }); } else { Array.prototype.forEach.call(this.querySelectorAll('cf-option'), function(option) { if (value === option.value) { option.selected = true; } }); } return; } }, // méthodes custom checkValidity: { value: function() { var validity = true; if (!this.querySelector('[selected]')) { this.classList.add('empty'); if (this.required) { validity = false; } } else { this.classList.remove('empty'); } if (validity) { this.classList.add('valid'); this.classList.remove('invalid'); } else { this.classList.add('invalid'); this.classList.remove('valid'); } return validity; } }, reset: { value: function() { var nodeList = this.querySelectorAll('cf-option'); for (var i=0, iMax=nodeList.length; i<iMax; i++) { nodeList.item(i).removeAttribute('selected'); if (nodeList.item(i).default) { nodeList.item(i).selected = true; } else { nodeList.item(i).selected = false; } } this.checkValidity(); } }, add: { value: function(HTMLCustomOptionElement) { var nodeList = this.querySelectorAll('cf-option'); var inserted = false; for (var i=0, iMax=nodeList.length; i<iMax; i++) { if (nodeList.item(i) === HTMLCustomOptionElement) { continue; } if (nodeList.item(i).textContent.localeCompare(HTMLCustomOptionElement.textContent) >= 0) { this.insertBefore(HTMLCustomOptionElement, nodeList.item(i)); inserted = true; break; } } if (!inserted) { this.appendChild(HTMLCustomOptionElement); } } }, removeOptions : { value: function() { var nodeList = this.querySelectorAll('cf-option'); for (var i=0, iMax=nodeList.length; i<iMax; i++) { this.removeChild(nodeList.item(i)); } } }, // méthode exécuté à chaque insertion de l'élément custom attachedCallback: { value: function() { // ajout des events this.addEventListener('tap', onTap, false); // ajout event modification noeuds enfants (ajout/sup) this.mutationObserver.observe(this, { childList: true, subtree: true, attributes: true, characterData: false }); } }, // méthode exécuté à chaque détachement de l'élément custom detachedCallback: { value: function() { // retrait des events this.removeEventListener('tap', onTap, false); // retrait event modification noeuds enfants (ajout/sup) this.mutationObserver.disconnect(); } }, // méthode exécuté quand un attribut est modifié attributeChangedCallback: { value: function(attrName, oldValue, newValue) { //console.info('attributeChangedCallback', this, attrName, 'qui valait', oldValue, 'vaut désormais', newValue); switch (attrName) { case 'name': break; case 'required': if (this.hasAttribute('required')) { this.classList.add('required'); } else { this.classList.remove('required'); } break; case 'disabled': if (this.hasAttribute('disabled')) { this.classList.add('disabled'); } else { this.classList.remove('disabled'); } case 'readonly': if (this.hasAttribute('readonly')) { this.classList.add('readonly'); } else { this.classList.remove('readonly'); } if (this.hasAttribute('disabled') || this.hasAttribute('readonly')) { this.setAttribute('tabindex', '-1'); } else { this.setAttribute('tabindex', '0'); } break; } } } }) }); })();
</script> <script src="js/index.js"></script>
</body>
</html>

Form - select - Script Codes CSS Codes

/* .valid / .invalid .required .empty .disabled .readonly */
/* host */
:host { min-width: 200px; max-width: 100%; flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: column; -webkit-align-items: stretch; margin-top: 30px; font-size: 18px; position: relative; outline: none;
}
:host(.disabled),
:host(.readonly) { pointer-events: none;
}
:host(.empty),
header { color: #BCBCBC;
}
:host(:not(.empty)) * { color: rgba(0, 0, 0, 0.8);
}
/* header */
header { flex: 0 0 auto; display: flex; flex-direction: row; justify-content: space-between; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: row; -webkit-justify-content: space-between;
}
::content > label { font-size: 12px; color: rgb(188, 188, 188);
}
::content > cf-cursor { color: black;
}
/* main */
main { position: relative; flex: 0 0 auto; display: flex; flex-direction: row; align-items: stretch; -webkit-flex: 0 0 auto; -webkit-display: flex; -webkit-flex-direction: row; -webkit-align-items: stretch; flex-wrap: wrap;
}
/* option */
cf-option { padding: 0;
}
::content > cf-option:not([selected]) { display: none;
}
:host(.invalid:not(.empty))::content > cf-option { color: #ea7166;
}
:host([multiple])::content > cf-option[selected]::after { content: ","; padding-right: 4px;
}
/* underline */
hr { border-color: rgba(0, 0, 0, 0.5); border-style: solid; border-width: 0; border-top-width: 1px; margin: 0; margin-bottom: 1px;
}
:host(.disabled) hr,
:host(.readonly) hr { border-style: dashed;
}
:host(.invalid) hr { border-color: #ea7166;
}
:host(.required.empty) hr { border-color: #f58e46;
}
/* surcharge */
/* host */
cf-select { min-width: 200px; max-width: 100%; flex: 0 0 auto; display: flex; flex-direction: column; align-items: stretch; -webkit-flex: 0 0 auto; display: -webkit-flex; -webkit-flex-direction: column; -webkit-align-items: stretch; margin-top: 30px; font-size: 18px; position: relative; outline: none;
}
cf-select.disabled,
cf-select.readonly { pointer-events: none;
}
cf-select.empty,
header { color: #BCBCBC;
}
cf-select > label { font-size: 12px; color: rgb(188, 188, 188);
}
cf-select > cf-cursor { color: black;
}
cf-select:not(.empty) * { color: rgba(0, 0, 0, 0.8);
}
/* option */
cf-select.invalid:not(.empty) cf-option { color: #ea7166;
}
cf-select[multiple] cf-option[selected]::after { content: ","; padding-right: 4px;
}
cf-option:not([selected]) { display: none;
}
/* underline */
cf-select.disabled hr,
cf-select.readonly hr { border-style: dashed;
}
cf-select.invalid hr { border-color: #ea7166;
}
cf-select.required.empty hr { border-color: #f58e46;
}

Form - select - Script Codes JS Codes

 var HTMLCustomSelectElement = (function() { var parentDoc = (document._currentScript || document.currentScript).ownerDocument; /* création de l'overlay */ var overlaySelect = document.createElement('div'); overlaySelect.id = "overlay-select"; overlaySelect.style.display = 'none'; // création shadow root overlaySelect.createShadowRoot(); // ajout contenu template overlaySelect.shadowRoot.appendChild(document.importNode(parentDoc.querySelector('template#overlay-select').content, true)); // ajout propriété overlaySelect.currentSelect = null; // ajout méthodes overlaySelect.open = function(HTMLCustomSelectElement) { if (overlaySelect.currentSelect) { console.error('unable to open overlaySelect for', HTMLCustomSelectElement, 'overlaySelect is currently used for', overlaySelect.currentSelect); return; } overlaySelect.currentSelect = HTMLCustomSelectElement; // stuff var optionList = HTMLCustomSelectElement.querySelectorAll('cf-option'); var articleWrapper = overlaySelect.shadowRoot.querySelector('#option-list'); // créer label var label = HTMLCustomSelectElement.querySelector('label'); overlaySelect.shadowRoot.querySelector('label').textContent = (label ? label.textContent : null); // créer les articles for (var i=0, iMax=optionList.length, article, flag=true ; i<iMax; i++) { article = document.createElement('article'); if (optionList.item(i).hasAttribute('disabled')) { article.classList.add('disabled'); } if (optionList.item(i).hasAttribute('selected') && flag) { article.classList.add('selected'); if (!HTMLCustomSelectElement.multiple) { flag = false; } } article.textContent = optionList.item(i).textContent; article.value = optionList.item(i).value; articleWrapper.appendChild(article); } // s'afficher overlaySelect.style.display = null; }; overlaySelect.close = function() { console.info('overlaySelect close'); // stuff var articleWrapper = overlaySelect.shadowRoot.querySelector('#option-list'); var articleList = articleWrapper.querySelectorAll('article'); var optionList = overlaySelect.currentSelect.querySelectorAll('cf-option'); // se cacher overlaySelect.style.display = 'none'; // virer label overlaySelect.shadowRoot.querySelector('label').textContent = null; for (var i=0, iMax=articleList.length, option ; i<iMax; i++) { for (var j=0, jMax=optionList.length; j<jMax; j++) { if (articleList.item(i).value === optionList.item(j).value) { option = optionList.item(j); break; } } // mettre à jour les options if (articleList.item(i).classList.contains('selected')) { option.setAttribute('selected', 'selected'); } else { option.removeAttribute('selected'); } // supprimer les articles articleWrapper.removeChild(articleList.item(i)); } overlaySelect.currentSelect.checkValidity(); overlaySelect.currentSelect = null; }; overlaySelect.onArticlePointered = function(event) { console.info('overlaySelect onArticlePointered', 'event', event, 'overlaySelect', overlaySelect); if (event.target.tagName.toLowerCase() !== 'article' || event.target.classList.contains('disabled')) { console.warn('pas un article ou desactivé'); return; } if (overlaySelect.currentSelect.multiple) { console.info('multiple'); if (event.target.classList.contains('selected')) { event.target.classList.remove('selected'); } else { event.target.classList.add('selected'); } } else if (!event.target.classList.contains('selected')){ console.warn('pas multiple', event); var articleList = overlaySelect.shadowRoot.querySelectorAll('.selected'); console.info('articleList', articleList); for (var i=0, iMax=articleList.length; i<iMax; i++) { console.info('avant', articleList.item(i)); articleList.item(i).classList.remove('selected'); console.info('apres'); } //overlaySelect.shadowRoot.querySelector('.selected').remove('selected'); console.info('tadam'); event.target.classList.add('selected'); console.info('sdfgsdgfs'); overlaySelect.close(); console.info('closed'); } }; // ajout event overlaySelect.shadowRoot.querySelector('button').addEventListener('click', overlaySelect.close, false); overlaySelect.shadowRoot.querySelector('#option-list').addEventListener('click', overlaySelect.onArticlePointered, false); // ajout dom document.body.appendChild(overlaySelect); // fonctions privées var onPointerUp = function(event) { console.info('onPointerUp',event) overlaySelect.open(event.currentTarget); } // quand un noeud est ajouté ou retiré function onMutation(mutationRecords, mutationObserver) { console.warn('onMutation', mutationRecords, mutationObserver) for (var k=0, kMax=mutationRecords.length; k<kMax; k++) { var mutationRecord = mutationRecords[k]; // ajout ou retrait d'option if (mutationRecord.addedNodes || mutationRecord.removedNodes) { this.checkValidity(); break; } } } // objet custom return document.registerElement('cf-select', { prototype: Object.create(HTMLElement.prototype, { // constructeur createdCallback: { value: function() { // création shadow root this.createShadowRoot(); // ajout contenu depuis le template var cloneTemplate = document.importNode(parentDoc.querySelector('template#cf-select').content, true); this.shadowRoot.appendChild(cloneTemplate); // ajout event interaction // propriétés custom avec stockage caché // ajout event propriété Object.observe(this, function(changes) { changes.forEach(function(change) { // change === {name (nom propriété), object (l'objet observé), type (add, update, delete), oldValue} console.info('Object.observe', change.object, change.name, 'qui valait', change.oldValue, 'vaut désormais', change.object[change.name]); // stuff switch (change.name) { case 'active': if (change.object[change.name]) { change.object.classList.add('focus'); change.object.classList.remove('blur'); } else { change.object.classList.add('blur'); change.object.classList.remove('focus'); } change.object.checkValidity(); break; default: break; } }); }); // initialisation (function() { var nodeList = this.querySelectorAll('cf-option'); console.error('nodeList',nodeList); for (var i=0, iMax=nodeList.length; i<iMax; i++) { this.add(nodeList.item(i)); } console.error('nodeList',this.querySelectorAll('cf-option')); }).apply(this); if (this.hasAttribute('required')) { this.classList.add('required'); } else { this.classList.remove('required'); } if (this.hasAttribute('disabled')) { this.classList.add('disabled'); } else { this.classList.remove('disabled'); } if (this.hasAttribute('readonly')) { this.classList.add('readonly'); } else { this.classList.remove('readonly'); } if (this.hasAttribute('disabled') || this.hasAttribute('readonly')) { this.setAttribute('tabindex', '-1'); } else { this.setAttribute('tabindex', '0'); } this.active = false; //this.reset(); // création mutation observer this.mutationObserver = new MutationObserver(onMutation.bind(this)); } }, // propriétés custom active: { value: false, writable: true }, name: { get: function() { return this.getAttribute('name'); }, set: function(value) { var oldValue = this.getAttribute('name'); this.setAttribute('name', value); Object.getNotifier(this).notify({ type: 'update', name: 'name', oldValue: oldValue }); } }, required: { get: function() { return this.hasAttribute('required'); }, set: function(value) { var oldValue = this.hasAttribute('required'); if (value) { this.setAttribute('required', 'required'); } else { this.removeAttribute('required'); } Object.getNotifier(this).notify({ type: 'update', name: 'required', oldValue: oldValue }); } }, disabled: { get: function() { return this.hasAttribute('disabled'); }, set: function(value) { var oldValue = this.hasAttribute('disabled'); if (value) { this.setAttribute('disabled', 'disabled'); } else { this.removeAttribute('disabled'); } Object.getNotifier(this).notify({ type: 'update', name: 'disabled', oldValue: oldValue }); } }, readOnly: { get: function() { return this.hasAttribute('readonly'); }, set: function(value) { var oldValue = this.hasAttribute('readonly'); if (value) { this.setAttribute('readonly', 'readonly'); } else { this.removeAttribute('readonly'); } Object.getNotifier(this).notify({ type: 'update', name: 'readonly', oldValue: oldValue }); } }, multiple: { get: function() { return this.hasAttribute('multiple'); }, set: function(value) { var oldValue = this.hasAttribute('multiple'); if (value) { this.setAttribute('multiple', 'multiple'); } else { this.removeAttribute('multiple'); } Object.getNotifier(this).notify({ type: 'update', name: 'multiple', oldValue: oldValue }); } }, value: { get: function() { if (this.multiple) { var nodeList = this.querySelectorAll('cf-option[selected]'); var values = []; for (var i=0, iMax=nodeList.length; i<iMax; i++) { values.push(nodeList.item(i).value); } return JSON.stringify(values); } else { return this.querySelector('cf-option[selected]').value; } }, set: function() { return; } }, // méthodes custom checkValidity: { value: function() { console.warn('checkValidity', this); var validity = true; if (!this.querySelector('[selected]')) { this.classList.add('empty'); if (this.required) { validity = false; } } else { this.classList.remove('empty'); } if (validity) { this.classList.add('valid'); this.classList.remove('invalid'); } else { this.classList.add('invalid'); this.classList.remove('valid'); } console.warn(validity); return validity; } }, reset: { value: function() { var nodeList = this.querySelectorAll('cf-option'); for (var i=0, iMax=nodeList.length; i<iMax; i++) { nodeList.item(i).removeAttribute('selected'); } this.checkValidity(); } }, add: { value: function(HTMLCustomOptionElement) { var nodeList = this.querySelectorAll('cf-option'); var inserted = false; for (var i=0, iMax=nodeList.length; i<iMax; i++) { if (nodeList.item(i) === HTMLCustomOptionElement) { continue; } if (nodeList.item(i).textContent.localeCompare(HTMLCustomOptionElement.textContent) >= 0) { this.insertBefore(HTMLCustomOptionElement, nodeList.item(i)); inserted = true; break; } } if (!inserted) { this.appendChild(HTMLCustomOptionElement); } } }, // méthode exécuté à chaque insertion de l'élément custom attachedCallback: { value: function() { // ajout des events this.addEventListener('mouseup', onPointerUp, false); // ajout event modification noeuds enfants (ajout/sup) this.mutationObserver.observe(this, { childList: true, subtree: false, attributes: false, characterData: false }); } }, // méthode exécuté à chaque détachement de l'élément custom detachedCallback: { value: function() { // retrait des events this.removeEventListener('mouseup', onPointerUp, false); // retrait event modification noeuds enfants (ajout/sup) this.mutationObserver.disconnect(); } }, // méthode exécuté quand un attribut est modifié attributeChangedCallback: { value: function(attrName, oldValue, newValue) { console.info('attributeChangedCallback', this, attrName, 'qui valait', oldValue, 'vaut désormais', newValue); switch (attrName) { case 'name': break; case 'required': if (this.hasAttribute('required')) { this.classList.add('required'); } else { this.classList.remove('required'); } break; case 'disabled': if (this.hasAttribute('disabled')) { this.classList.add('disabled'); } else { this.classList.remove('disabled'); } case 'readonly': if (this.hasAttribute('readonly')) { this.classList.add('readonly'); } else { this.classList.remove('readonly'); } if (this.hasAttribute('disabled') || this.hasAttribute('readonly')) { this.setAttribute('tabindex', '-1'); } else { this.setAttribute('tabindex', '0'); } break; } } } }) }); })();
Form - select - Script Codes
Form - select - Script Codes
Home Page Home
Developer Anthony Pothin
Username Thorien
Uploaded January 17, 2023
Rating 3
Size 10,146 Kb
Views 6,072
Do you need developer help for Form - select?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Anthony Pothin (Thorien) Script Codes
Create amazing art & images with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!