Вложение оптгрупп в раскрывающийся список / select
Я создал элемент управления customer c# DropDownList, который может отображать его содержимое-это optgroups (не с нуля, я отредактировал некоторый код, найденный в интернете, хотя я точно понимаю, что он делает), и он отлично работает.
однако теперь я столкнулся с ситуацией, когда мне нужно иметь два уровня отступа в моем выпадающем списке, т. е.
<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>однако, в приведенном выше примере фрагмента, это рендеринг, как если бы Level Two был при том же количестве отступов, что и Level One.
есть ли способ создать вложенное поведение optgroup, которое я ищу?
8 ответов:
спецификация HTML здесь действительно сломана. Он должен разрешать вложенные группы опций и рекомендовать агентам пользователей отображать их как вложенные меню. Вместо этого,разрешен только один уровень optgroup. Тем не менее, они должны сказать следующее по этому вопросу:
Примечание. Разработчикам рекомендуется, что будущие версии HTML могут расширить механизм группировки, чтобы разрешить вложенные группы (т. е. элементы OPTGROUP могут быть вложены). Это позволит авторам представить более богатую иерархию выбор.
и агенты пользователей могут начать использовать подменю для визуализации optgoups вместо отображения заголовков перед первым элементом option в optgroup, как это делается сейчас.
Это просто прекрасно, но если вы добавляете опцию ведьма не в optgroup он получает багги.
<select> <optgroup label="Level One"> <option> A.1 </option> <optgroup label=" Level Two"> <option> A.B.1 </option> </optgroup> <option> A.2 </option> </optgroup> <option> A </option> </select>было бы намного лучше, если бы вы использовали css и сразу закрыли optgroup :
<select> <optgroup label="Level One"></optgroup> <option style="padding-left:15px"> A.1 </option> <optgroup label="Level Two" style="padding-left:15px"></optgroup> <option style="padding-left:30px"> A.B.1 </option> <option style="padding-left:15px"> A.2 </option> <option> A </option> </select>
хорошо, если кто-нибудь когда-нибудь читает это: лучший вариант-добавить четыре
s на каждом дополнительном уровне отступа, казалось бы!так:
<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>
<style> .NestedSelect{display: inline-block; height: 100px; border: 1px Black solid; overflow-y: scroll;} .NestedSelect label{display: block; cursor: pointer;} .NestedSelect label:hover{background-color: #0092ff; color: White;} .NestedSelect input[type="radio"]{display: none;} .NestedSelect input[type="radio"] + span{display: block; padding-left: 0px; padding-right: 5px;} .NestedSelect input[type="radio"]:checked + span{background-color: Black; color: White;} .NestedSelect div{margin-left: 15px; border-left: 1px Black solid;} .NestedSelect label > span:before{content: '- ';} </style> <div class="NestedSelect"> <label><input type="radio" name="MySelectInputName"><span>Fruit</span></label> <div> <label><input type="radio" name="MySelectInputName"><span>Apple</span></label> <label><input type="radio" name="MySelectInputName"><span>Banana</span></label> <label><input type="radio" name="MySelectInputName"><span>Orange</span></label> </div> <label><input type="radio" name="MySelectInputName"><span>Drink</span></label> <div> <label><input type="radio" name="MySelectInputName"><span>Water</span></label> <label><input type="radio" name="MySelectInputName"><span>Soft</span></label> <div> <label><input type="radio" name="MySelectInputName"><span>Cola</span></label> <label><input type="radio" name="MySelectInputName"><span>Soda</span></label> <label><input type="radio" name="MySelectInputName"><span>Lemonade</span></label> </div> <label><input type="radio" name="MySelectInputName"><span>Hard</span></label> <div> <label><input type="radio" name="MySelectInputName"><span>Bear</span></label> <label><input type="radio" name="MySelectInputName"><span>Whisky</span></label> <label><input type="radio" name="MySelectInputName"><span>Vodka</span></label> <label><input type="radio" name="MySelectInputName"><span>Gin</span></label> </div> </div> </div>
Я думаю, что если у вас есть что-то структурированное и сложное, вы можете рассмотреть что-то другое, чем один раскрывающийся список.
мне очень нравится решение сломанной стрелки выше в этом посте. Я только что улучшил / изменил его немного, чтобы то, что называлось ярлыками, можно было переключать и не рассматривать варианты. Я использовал небольшой кусок jQuery, но это можно сделать без jQuery.
Я заменил промежуточные метки (без листовых меток) ссылками, которые вызывают функцию по щелчку. Эта функция отвечает за переключение следующего div нажатой ссылки, так что она расширяется / сворачивается опцион. Это позволяет избежать возможности выбора промежуточного элемента в иерархии, который обычно является чем-то желаемым. Сделать вариант, позволяющий выбрать промежуточные элементы, должно быть легко.
это измененный html:
<div class="NestedSelect"> <a onclick="toggleDiv(this)">Fruit</a> <div> <label> <input type="radio" name="MySelectInputName"><span>Apple</span></label> <label> <input type="radio" name="MySelectInputName"><span>Banana</span></label> <label> <input type="radio" name="MySelectInputName"><span>Orange</span></label> </div> <a onclick="toggleDiv(this)">Drink</a> <div> <label> <input type="radio" name="MySelectInputName"><span>Water</span></label> <a onclick="toggleDiv(this)">Soft</a> <div> <label> <input type="radio" name="MySelectInputName"><span>Cola</span></label> <label> <input type="radio" name="MySelectInputName"><span>Soda</span></label> <label> <input type="radio" name="MySelectInputName"><span>Lemonade</span></label> </div> <a onclick="toggleDiv(this)">Hard</a> <div> <label> <input type="radio" name="MySelectInputName"><span>Bear</span></label> <label> <input type="radio" name="MySelectInputName"><span>Whisky</span></label> <label> <input type="radio" name="MySelectInputName"><span>Vodka</span></label> <label> <input type="radio" name="MySelectInputName"><span>Gin</span></label> </div> </div> </div>небольшая функция javascript/jQuery:
function toggleDiv(element) { $(element).next('div').toggle('medium'); }и css:
.NestedSelect { display: inline-block; height: 100%; border: 1px Black solid; overflow-y: scroll; } .NestedSelect a:hover, .NestedSelect span:hover { background-color: #0092ff; color: White; cursor: pointer; } .NestedSelect input[type="radio"] { display: none; } .NestedSelect input[type="radio"] + span { display: block; padding-left: 0px; padding-right: 5px; } .NestedSelect input[type="radio"]:checked + span { background-color: Black; color: White; } .NestedSelect div { display: none; margin-left: 15px; border-left: 1px black solid; } .NestedSelect label > span:before, .NestedSelect a:before{ content: '- '; } .NestedSelect a { display: block; }
мне нужно было чистое и легкое решение (поэтому нет jQuery и т. д.), которое будет выглядеть точно так же, как обычный HTML, также будет продолжать работать, когда только обычный HTML предустановлен (поэтому javascript только улучшит его), и который позволит искать, начиная буквы (включая национальные буквы UTF-8), если это возможно, где он не добавляет дополнительный вес. Он также должен работать быстро на очень медленных браузерах (думаю, rPi - так что желательно не javascript, выполняющийся после загрузки страницы).
в firefox он использует В CSS определить и, таким образом, разрешить поиск по буквам, а в других браузерах он будет использовать
добавляю (но там он не поддерживает быстрый поиск по буквам). Во всяком случае, я вполне доволен результатами.вы можете попробуйте его в действии здесь
это звучит так:
CSS:
.i0 { } .i1 { margin-left: 1em; } .i2 { margin-left: 2em; } .i3 { margin-left: 3em; } .i4 { margin-left: 4em; } .i5 { margin-left: 5em; }HTML (класс "i1", " i2 " и т.д. обозначают уровень идентификации):
<form action="/filter/" method="get"> <select name="gdje" id="gdje"> <option value=1 class="i0">Svugdje</option> <option value=177 class="i1">Bosna i Hercegovina</option> <option value=190 class="i2">Babin Do</option> <option value=258 class="i2">Banja Luka</option> <option value=181 class="i2">Tuzla</option> <option value=307 class="i1">Crna Gora</option> <option value=308 class="i2">Podgorica</option> <option value=2 SELECTED class="i1">Hrvatska</option> <option value=5 class="i2">Bjelovarsko-bilogorska županija</option> <option value=147 class="i3">Bjelovar</option> <option value=79 class="i3">Daruvar</option> <option value=94 class="i3">Garešnica</option> <option value=329 class="i3">Grubišno Polje</option> <option value=368 class="i3">Čazma</option> <option value=6 class="i2">Brodsko-posavska županija</option> <option value=342 class="i3">Gornji Bogićevci</option> <option value=158 class="i3">Klakar</option> <option value=140 class="i3">Nova Gradiška</option> </select> </form> <script> <!-- window.onload = loadFilter; // --> </script>JavaScript:
function loadFilter() { 'use strict'; // indents all options depending on "i" CSS class function add_nbsp() { var opt = document.getElementsByTagName("option"); for (var i = 0; i < opt.length; i++) { if (opt[i].className[0] === 'i') { opt[i].innerHTML = Array(3*opt[i].className[1]+1).join(" ") + opt[i].innerHTML; // this means " " x (3*$indent) } } } // detects browser navigator.sayswho= (function() { var ua= navigator.userAgent, tem, M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i) || []; if(/trident/i.test(M[1])){ tem= /\brv[ :]+(\d+(\.\d+)?)/g.exec(ua) || []; return 'IE '+(tem[1] || ''); } M= M[2]? [M[1], M[2]]:[navigator.appName, navigator.appVersion, '-?']; if((tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1]; return M.join(' '); })(); // quick detection if browser is firefox function isFirefox() { var ua= navigator.userAgent, M= ua.match(/firefox\//i); return M; } // indented select options support for non-firefox browsers if (!isFirefox()) { add_nbsp(); } }
Я знаю, что это было довольно давно, однако у меня есть немного больше, чтобы добавить:
это невозможно в HTML5 или любых предыдущих спецификациях, и это еще не предложено в HTML5.1. Я сделал запрос к
public-html-commentsсписок рассылки, но мы посмотрим, если что-нибудь из этого выйдет.независимо, пока это не возможно с помощью
<select>тем не менее, вы можете достичь аналогичного эффекта со следующим HTML, плюс некоторые CSS для красота:<ul> <li> <input type="radio" name="location" value="0" id="loc_0" /> <label for="loc_0">United States</label> <ul> <li> Northeast <ul> <li> <input type="radio" name="location" value="1" id="loc_1" /> <label for="loc_1">New Hampshire</label> </li> <li> <input type="radio" name="location" value="2" id="loc_2" /> <label for="loc_2">Vermont</label> </li> <li> <input type="radio" name="location" value="3" id="loc_3" /> <label for="loc_3">Maine</label> </li> </ul> </li> <li> Southeast <ul> <li> <input type="radio" name="location" value="4" id="loc_4" /> <label for="loc_4">Georgia</label> </li> <li> <input type="radio" name="location" value="5" id="loc_5" /> <label for="loc_5">Alabama</label> </li> </ul> </li> </ul> </li> <li> <input type="radio" name="location" value="6" id="loc_6" /> <label for="loc_6">Canada</label> <ul> <li> <input type="radio" name="location" value="7" id="loc_7" /> <label for="loc_7">Ontario</label> </li> <li> <input type="radio" name="location" value="8" id="loc_8" /> <label for="loc_8">Quebec</label> </li> <li> <input type="radio" name="location" value="9" id="loc_9" /> <label for="loc_9">Manitoba</label> </li> </ul> </li> </ul>как дополнительное преимущество, это также означает, что вы можете разрешить выбор
<optgroups>сами. Это может быть полезно, если у вас есть, например, вложенные категории, где категории переходят в тяжелые детали, и вы хотите разрешить пользователям выбирать выше в иерархии.все это будет работать без JavaScript, однако вы можете добавить некоторые, чтобы скрыть переключатели, а затем изменить цвет фона выбранный элемент или что-то еще.
имейте в виду, что это далеко не идеальное решение, но если вам абсолютно нужен вложенный выбор с разумной кросс-браузерной совместимостью, это, вероятно, так близко, как вы собираетесь получить.
Comments