问题描述
我已经看到了更多的 关于SO的帖子获取链接列表并将其变为下拉列表.我已经采用了这些示例,但运气不佳,无法将它们应用于我的标记,这有点不同.我需要打开带有标签的单选按钮的嵌套列表,并将它们转换为带有<optgroup>
标题的下拉列表,删除嵌套的单选输入和标签.
I've seen more then a few a few posts on SO which are looking to take a list of links and turning them into a drop-down. I've taken those examples and have not had too much luck applying them to my markup which is a bit different. I need to turn a nested list of radio buttons with labels and convert them into a drop down list with <optgroup>
headings, removing nested radio inputs and labels.
基本上,Im正在使用的单选按钮列表完全不受控制,并且干净的下拉列表将具有更好的可用性和屏幕空间.一旦处理完转换,计划就是隐藏原始的单选按钮集,然后将用户下拉选择映射到相应的单选按钮,以在提交表单时进行处理.但是首先我需要生成下拉列表. . .
Basically the list of radio buttons Im working with is a wildly out of control and a clean drop down list would be much better usability and screen real estate. Once I handle the conversion, the plan is to hide the original radio button set, and then map the user drop-down selection to the corresponding radio buttons to be process on submission of the form. But first I need to generate the drop-down list . . .
以下是开始标记的简化示例:
Here is a simplified sample of the starting markup:
<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>
我正在尝试将以上内容转换为以下内容:
Im trying to convert the above to the following:
<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>
也具有与之相关的单选按钮-但这不是 所希望的,因为我们希望用户尽可能精确在他们的选择中可能.这些本来应该是标题,但不幸的是,我无法控制生成的内容.
You might notice that the top level <ul>
in the first example, also has a radio button associated with it –– but this is not desired as we want the user to be as precise a possible in their selection. These should have been headings, but unfortunately I have no control of what's generated.
我喜欢的解决方案类型是使用一个函数将现有标记处理成一个新实体,然后在隐藏原始实体后将其附加到父DOM元素.
They type of solution I favour is to use a function to process the existing markup into a new entity which I can then append to the parent DOM element after hiding the original.
在此 SO线程中,@ Enki提供了使用此方法的解决方案,但我无法应用它,因为我无法完全理解其遍历所有元素的方式.他的解决方案是这样的:
In this SO thread @Enki offers a solution with this approach, but I've not been able to apply it, as I just cant quite understand how its iterating though all the elements. His solution goes like this:
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顶层和确实是不完整的:
The closest I've been able to get, which doesn't use @Enki's approach, and doesn't create optgroup top levels and 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);
});
});
如果有人想对轻描淡写,这里是广播列表的简化示例. .我很想知道您将如何解决这种问题.
Here is a unsimplified sample of the radio list if anyone wants to take a whack at it. I would love to know how you would approach this kind of problem.
推荐答案
干杯!
我相信递归可以在这里有所帮助:
I believe recursivity can be of help here:
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>";
}
有一些需要注意的地方:该函数假定,如果给定的LI元素仅包含LABEL元素(而不含UL元素),则LABEL是可选选项;如果LI包含LABEL和UL,则LABEL是一个选项组.
There is something to watch for: the function assumes that if a given LI element contains only a LABEL element (and no UL element) then that LABEL is a selectable option and if the LI contains a LABEL and a UL then the LABEL is a option group.
这是小提琴
希望对您有帮助!
这篇关于jQuery将单选按钮的嵌套列表转换为带有optgroup标题的下拉列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!