Rendering a hierarchy of OPTIONs in a SELECT tag
deceze way is much better and was my first idea. As an alternative if that doesn't work is that you can use non-breaking spaces in the tag value:
<select>
<option>select me</option>
<option> me indented</option>
<option> even more indentation</option>
</select>
It's far from pretty but it might work for you if the optgroup doesn't.
Best modern way of creating indentation in a <select>?
Prefix your <option>
text with an appropriate amount of
(character code 160, respectively).
How to represent hierarchical data in select input?
The box drawing characters are meant for purposes like this, more or less. At the minimum, you would use U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT “├” and U+2500 BOX DRAWINGS LIGHT HORIZONTAL“─”. For example,
<select>
<option>master
<option> ├─ foo 1
<option> ├─ foo 2
<option> ├─ bar 1
</select>
However, it will be difficult to get the symbols aligned well. Using no-break spaces as above is a coarse tool, and most importantly, character widths vary—so you might consider using a CSS rule like
select, option { font-family: Consolas, monospace }
to get more predictable rendering.
How to indent multiple levels of select optgroup with CSS?
8/29/2016 Edit
The original answer below is no longer functional in modern browsers. For those who still need to use a tag instead of doing magic with HTML lists, a better solution was found on this stackoverflow thread: Rendering a hierarchy of "OPTION"s in a "SELECT" tag
I would recommend the solution suggested by igor-krupitsky who suggests dropping and using the binary instead. At least on Chrome, this does not break using the keyboard to find the first character of an item in the list.
End Edit
The current HTML specification does not provide for nested tags adding any functionality (such as indentation). See this link.
In the mean time, you can manually style your levels with CSS. I tried using styles in your sample, but for some reason they did not render correctly, so at the very least the following will work:
<select name="select_projects" id="select_projects"> <option value="">project.xml</option> <optgroup label="client1"> <option value="">project2.xml</option> </optgroup> <optgroup label="client2"> <option value="">project5.xml</option> <option value="">project6.xml</option> <optgroup label="client2_a"> <option value="" style="margin-left:23px;">project7.xml</option> <option value="" style="margin-left:23px;">project8.xml</option> </optgroup> <option value="">project3.xml</option> <option value="">project4.xml</option> </optgroup> <option value="">project0.xml</option> <option value="">project1.xml</option> </select>
Nesting optgroups in a dropdownlist/select
Ok, if anyone ever reads this: the best option is to add four
s at each extra level of indentation, it would seem!
so:
<select> <optgroup label="Level One"> <option> A.1 </option> <optgroup label=" Level Two"> <option> A.B.1 </option> </optgroup> <option> A.2 </option> </optgroup></select>
Select2 - Can’t select values from a multi-level tree
You have hit a limitation of HTML version 5 and below. <optgroup>
s are not nestable, their only allowed parent is <select>
.
Select2 docs warn against it:
Because Select2 generates an
<optgroup>
when creating nested options, only a single level of nesting is supported. Any additional levels of nesting is not guaranteed to be displayed properly across all browsers and devices.
Furthermore:
Hierarchical options
Only a single level of nesting is allowed per the HTML specification.
If you nest an<optgroup>
within another<optgroup>,
Select2 will
not be able to detect the extra level of nesting and errors may be
triggered as a result.Furthermore,
<optgroup>
elements cannot be made selectable.
This is a limitation of the HTML specification and is not a limitation that Select2 can overcome.If you wish to create a true hierarchy of selectable options, use an
<option>
instead of an<optgroup>
and change the style with
CSS. Please note that this approach may be considered "less
accessible" as it relies on CSS styling, rather than the semantic
meaning of<optgroup>
, to generate the effect.
In practice/Demo
Select2, as said, renders a <select>
. From your fiddle, you can get the one it renders by inspecting the DOM.
I copied the rendered DOM and pasted in the demo below.
Look how the nested <optgroup>
s aren't really nested, no matter the level, they are rendered only one level deep.
$(function() { var theData = [{ "id": "", "text": "" }, { "text": "Group 1", "children": [{ "id": 1, "text": "Option 1.1" }, { "id": 2, "text": "Option 1.2" } ] }, { "text": "Group 2", "children": [{ "id": 3, "text": "Subgroup 2.1", "children": [{ "id": 41, "text": "Option 2.1.1" }, { "id": 42, "text": "Option 2.1.2" } ] }, { "id": 4, "text": "Subgroup 2.2", "children": [{ "id": 41, "text": "Subgroup 2.2.1", "children": [{ "id": 41, "text": "Option 2.2.1.1" }] }, { "id": 42, "text": "Subgroup 2.2.2", "children": [{ "id": 41, "text": "Option 2.2.2.1" }, { "id": 42, "text": "Option 2.2.2.2" } ] } ] } ] } ]; $("#mySelect").select2({ placeholder: "Select a option...", data: theData });});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css">
<select id="mySelect" class="form-control" style="width:400px;"></select>
<br><hr><br>Notice how these nested optgroups are rendered as if they weren't nested at all. They are all only one level deep:<br><select> <option value="" data-select2-id="1"></option> <optgroup label="Group 1" data-select2-id="2"> <option value="1" data-select2-id="3">Option 1.1</option> <option value="2" data-select2-id="4">Option 1.2</option> </optgroup> <optgroup label="Group 2" data-select2-id="5"> <optgroup label="Subgroup 2.1" data-select2-id="6"> <option value="41" data-select2-id="7">Option 2.1.1</option> <option value="42" data-select2-id="8">Option 2.1.2</option> </optgroup> <optgroup label="Subgroup 2.2" data-select2-id="9"> <optgroup label="Subgroup 2.2.1" data-select2-id="10"> <option value="41" data-select2-id="11">Option 2.2.1.1</option> </optgroup> <optgroup label="Subgroup 2.2.2" data-select2-id="12"> <option value="41" data-select2-id="13">Option 2.2.2.1</option> <option value="42" data-select2-id="14">Option 2.2.2.2</option> </optgroup> </optgroup> </optgroup></select>
select2 with hierarchy JSON into option groups?
Here's the solution :
<select class="js-example-basic-single"></select>
<script>
var data = {
"fruit": [
{
"id": 1,
"name": "Orange"
},
{
"id": 2,
"name": "Banana"
},
{
"id": 3,
"name": "Apple"
}
],
"vegetables": [
{
"id": 4,
"name": "Potato"
},
{
"id": 5,
"name": "Carrot"
},
{
"id": 6,
"name": "Broccoli"
}
]
};
$().ready(function(){
var parsedJsonString = JSON.stringify(data); // get json string
var parsedJsonObject = $.parseJSON(parsedJsonString); // convert json string to object
$.each(parsedJsonObject,function(ele)
{
$(".js-example-basic-single").append("<optgroup label='" + ele + "'>");
$.each(parsedJsonObject[ele],function(subEle)
{
$(".js-example-basic-single").append("<option value='" + parsedJsonObject[ele][subEle]["id"] + "'>" + parsedJsonObject[ele][subEle]["name"] + "</option>");
});
$(".js-example-basic-single").append("</optgroup>");
});
$(".js-example-basic-single").select2();
});
http://jsfiddle.net/c1ozynyu/3/
Related Topics
Fast and Responsive Interactive Charts/Graphs: Svg, Canvas, Other
How to Make Input Autofocus in Internet Explorer
How to Create More Than One Repository for Github Pages
Bootstrap Row Class Contains Margin-Left and Margin-Right Which Creates Problems
Centering a Div Between One That's Floated Right and One That's Floated Left
<H1>, <H2>, <H3>... Tags, Inline Within Paragraphs (<P>)
How Might I Force a Floating Div to Match The Height of Another Floating Div
Media Queries Not Working Inside an Iframe
Photoshop Mock Up Font Isn't Same as in HTML
Is There a Vr (Vertical Rule) in HTML
Twitter Bootstrap: Column Re-Ordering for Full Width Divs
@Media Queries and Image Swapping
Flexbox Layout with Two Equal Height Children, One Containing Nested Flexbox with Scrolling Content