【问题标题】:jquery convert nested list of radio buttons to dropdown with optgroup headingsjquery将嵌套的单选按钮列表转换为带有optgroup标题的下拉列表
【发布时间】:2013-10-08 16:21:18
【问题描述】:

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

您可能会注意到,第一个示例中的顶级 &lt;ul&gt; 也有一个与之关联的单选按钮——但这是所希望的,因为我们希望用户与可能在他们的选择。这些应该是标题,但不幸的是我无法控制生成的内容。

我喜欢的解决方案类型是使用一个函数将现有标记处理为一个新实体,然后我可以在隐藏原始标记后附加到父 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,这里是一个未简化的广播列表示例。我很想知道您将如何解决此类问题。

【问题讨论】:

    标签: jquery list radio-button html-select


    【解决方案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

    希望对你有帮助!

    【讨论】:

    • @Fabrico 很抱歉这么长时间才说谢谢。这非常适合我的需求,您的 cmets 认为这对我了解一切如何运作特别有用。
    • @Fabrico 还有NBSPs(level) 函数对于缩进来说非常棒!
    • @orionrush 酷!我很高兴它对你有用。感谢您在这么长时间后回到它! :-)
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多