tabla - jquery convertir una lista anidada de botones de opción en el menú desplegable con los encabezados de optgroup
tabla desplegable html (1)
¡Salud!
Creo que la recursividad puede ser de ayuda aquí:
function buildDropDownFromUL(CurrentUL, level) {
var dropDownHTML = "";
CurrentUL.children("li").each(function () { // Cycle through all LI elements
if ($(this).children("ul").length == 0) {
// There is no UL element in this LI so it means LI is a selectable option
dropDownHTML = dropDownHTML + "<option value=''" + $(this).children("label").children("input").attr("value") + "''>" + NBSPs(level) + $(this).children("label").text() + "</option>";
} else {
// There is a UL in the LI so it means the LABEL in the current LI is a OPTGROUP
// and the UL should be again processed
dropDownHTML = dropDownHTML + "<optgroup label=''" + NBSPs(level) + $(this).children("label").text() + "''>" + "</optgroup>" + buildDropDownFromUL($(this).children("ul"), level + 1);
}
});
return dropDownHTML + "<optgroup label='' ''></optgroup>";
}
Hay algo que observar: la función asume que si un elemento LI dado contiene solo un elemento LABEL (y ningún elemento UL), entonces esa ETIQUETA es una opción seleccionable y si el LI contiene una ETIQUETA y una UL, entonces la ETIQUETA es una opción grupo.
Y aquí está el violín
¡Espero que ayude!
He visto más de unas pocas publicaciones en SO que buscan tomar una lista de enlaces y convertirlos en un menú desplegable. Tomé esos ejemplos y no tuve demasiada suerte aplicándolos a mi marcado, que es un poco diferente. Necesito convertir una lista anidada de botones de radio con etiquetas y convertirlos en una lista desplegable con encabezados <optgroup>
, eliminando entradas de radio anidadas y etiquetas.
Básicamente, la lista de botones de radio con los que estoy trabajando está muy fuera de control y una lista desplegable limpia sería mucho mejor usabilidad y pantalla de bienes raíces. Una vez que gestiono la conversión, el plan es ocultar el conjunto de botones de radio originales y luego asignar la selección desplegable del usuario a los botones de opción correspondientes para que se procese al enviar el formulario. Pero primero necesito generar la lista desplegable. . .
Aquí hay una muestra simplificada del marcado inicial:
<ul>
<li>
<label><input type="radio">USA</label>
<ul class="children">
<li>
<label><input type="radio" >Northeast</label>
<ul class="children">
<li>
<label><input itype="radio">Mid-Atlantic</label>
</li>
<li>
<label><input type="radio">New England</label>
</li>
</ul>
</li>
<li>
<label><input type="radio">South</label>
</li>
<li>
<label><input type="radio">West</label>
</li>
</ul>
</li>
<li>
<label><input type="radio" checked="checked">No Venue Region</label>
</li>
</ul>
Estoy tratando de convertir lo anterior a lo siguiente:
<select>
<optgroup label="USA">
<optgroup>Northeast</option>
<option>Mid-Atlantic</option>
<option>New England</option>
<optgroup>
<option>South</option>
<option>West</option>
</optgroup>
<option>No Region</option>
</select>
Puede observar que el nivel superior <ul>
en el primer ejemplo también tiene un botón de radio asociado, pero esto no es deseado ya que queremos que el usuario sea lo más preciso posible en su selección. Estos deberían haber sido los títulos, pero lamentablemente no tengo control de lo que se genera.
El tipo de solución que prefiero es utilizar una función para procesar el marcado existente en una nueva entidad que luego puedo adjuntar al elemento DOM principal después de ocultar el original.
En este SO, @Enki ofrece una solución con este enfoque, pero no he podido aplicarlo, ya que no puedo entender cómo se repiten todos los elementos. Su solución es así:
function sitemapCycle(){
if(typeof(sitemapNode)==="undefined") sitemapNode= $("#sitemap");
if($(this).find("ul").length)
{
sitemapNode= $(sitemapNode).append(''<optgroup label="''+$(this).children().first().text()+''" />'').children().last();
$(this).find("ul li").each(sitemapCycle);
sitemapNode= $(sitemapNode).parent();
}
else
{
$(sitemapNode).append(''<option value="''+$(this).children().attr("href")+''">''+$(this).text()+''</option>'');
}
}
var sitemapNode;
$("#sitemap").removeAttr("id").after(''<select id="sitemap" />'').children().each(sitemapCycle).parent().remove();
Lo más cercano que he podido obtener, que no utiliza el enfoque de @ Enki, y no crea niveles superiores de grupo Optgroup y está verdaderamente incompleto es este :
$(function() {
$(''#venue-regionchecklist'').each(function() {
$(this).find(''label'').each(function() {
var cnt = $(this).contents();
$(this).replaceWith(cnt);
});
var $select = $(''<select />'');
$(this).find(''li'').each(function() {
var $option = $(''<option />'');
$(this).html($(this).html());
$option.attr(''id'', $(this).attr(''id'')).html($(this).html());
$select.append($option);
});
$(this).replaceWith($select);
});
});
Aquí hay una muestra no simplificada de la lista de radio si alguien quiere criticarla . Me encantaría saber cómo abordaría este tipo de problema.