Rendering a Hierarchy of "Option"S in a "Select" Tag

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



Leave a reply



Submit