jquery将嵌套的单选按钮列表转换为带有optgroup标题的下拉列表

时间:2013-10-06 21:14:46

标签: jquery list radio-button html-select

我已经在SO上看到了更多few posts,它们希望获取链接列表并将其转换为下拉列表。我已经采用了这些例子并且没有太多的运气将它们应用到我的标记中,这有点不同。我需要使用标签打开嵌套的单选按钮列表,并将它们转换为带有<optgroup>标题的下拉列表,删除嵌套的无线电输入和标签。

基本上我正在使用的单选按钮列表是一个非常失控的,一个干净的下拉列表将是更好的可用性和屏幕空间。处理完转换后,计划是隐藏原始单选按钮集,然后将用户下拉选项映射到相应的单选按钮,以便在提交表单时进行处理。但首先我需要生成下拉列表。 。 。

以下是起始标记的简化示例:

<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>

我试图将上述内容转换为以下内容:

<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>

您可能会注意到第一个示例中的顶级<ul>也有一个与之关联的单选按钮 - 但这是,因为我们希望用户像精确的选择可能。这应该是标题,但不幸的是我无法控制生成的内容。

我喜欢的解决方案类型是使用函数将现有标记处理成一个新实体,然后我可以在隐藏原始实体后附加到父DOM元素。

在这个SO thread @Enki提供了这种方法的解决方案,但是我无法应用它,因为我无法理解它是如何迭代所有元素的。他的解决方案是这样的:

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();

我能得到的最接近的,没有使用@Enki的方法,也没有创建optgroup顶级和is truly incomplete is this

$(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);
    });
});

如果有人想拍摄a whack at it,以下是广播列表的简化示例。我很想知道你将如何解决这类问题。

1 个答案:

答案 0 :(得分:1)

干杯队友!

我相信递归可以在这里有所帮助:

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='&nbsp;'></optgroup>";
}

有一些注意事项:该函数假定如果给定的LI元素仅包含LABEL元素(并且没有UL元素),则该LABEL是可选择的选项,如果LI包含LABEL和UL,则LABEL是一个选项组。

这是Fiddle

我希望它有所帮助!