Actualmente estoy agregando opciones a un elemento de selección de forma dinámica como esta:
const jobs = [{...},{...},{...}]; const jobsInput = document.querySelector(...); jobs.forEach(job => { const option = new Option(`${job.title}`, job.id); jobsInput.add(option, undefined); }); Me gustaría poder agregar un <optgroup> cada vez que cambie una propiedad del objeto de trabajo ( job.companyName ). Estoy bastante seguro de que la lógica detrás de eso es bastante fácil, pero no conozco la sintaxis. Mozilla habla de un HTMLOptGroupElement , pero no sé cómo usarlo. Cuando lo intento, aparece un error illegal constructor .
Habría pensado que lo agregarías así:
const optGroup = new HTMLOptGroupElement('title'); jobsInput.add(optGroup); optGroup.label = 'title';pero obviamente solo estoy inventando esto y no funciona :) No puedo encontrar nada que explique cómo implementar el elemento. Si tuviera que adivinar es porque es una interfaz, pero eso todavía no me ayuda
Gracias
Deberías usar :
const optGroup = document.createElement('optgroup'); que en realidad devuelve un HTMLOptGroupElement .
El error de Illegal constructor ocurre porque HTMLOptGroupElement es una interfaz que no puede instanciar por sí misma (invocando un constructor con la nueva palabra clave), como clases abstractas en general para la mayoría de los lenguajes OO.
Por lo general, se prefiere usar document.createElement en lugar de constructores por coherencia, porque no todos los HTMLElements tienen un constructor, mientras que este método es la forma genérica de crear cualquier elemento HTML.
Además, tenga en cuenta que cada opción (use document.createElement('option') también) debe agregarse a su elemento optGroup (principal) respectivo, y optGroups al elemento de selección principal.
Puede usar forEach y un simple if.
Solo necesita mantener disponible el grupo actual: cuando agrega, el grupo se reemplaza
HTMLOptGroupElement se crea usando document.createElement("optgroup");
const jobs = [ {"companyName":"BMW","title":"Director","id":"1"}, {"companyName":"BMW","title":"Service desk","id":"2"}, {"companyName":"Honda","title":"VP","id":"3"}, {"companyName":"Honda","title":"VP1","id":"4"}, {"companyName":"Honda","title":"VP2","id":"5"}, {"companyName":"Fiat","title":"VP","id":"6"}, {"companyName":"Fiat","title":"VP1","id":"7"}, {"companyName":"Fiat","title":"VP2","id":"8"} ]; const sel = document.getElementById("jobSelect"); jobs.forEach(job => { let group = sel.querySelector(`optgroup[label="${job.companyName}"]`); if (!group) { group = document.createElement("optgroup"); group.label = job.companyName; } const opt = new Option(job.title, job.id); opt.classList.add("colored"); // may not actually do anything in some browsers group.append(opt) sel.appendChild(group) }) .colored{ color: red; } <select id="jobSelect"></select>Chrome 100 Windows 10 Empresa
cromo 100 osx