드롭 다운 목록 / 선택에 optgroup 중첩
콘텐츠를 optgroups로 렌더링 할 수있는 고객 c # DropDownList 컨트롤을 만들었습니다 (처음부터는 아니지만 인터넷에서 찾은 일부 코드를 편집했습니다.
그러나 이제 드롭 다운에 두 가지 수준의 들여 쓰기가 필요한 상황에 도달했습니다.
<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 동작을 생성하는 방법이 있습니까?
여기의 HTML 사양은 정말 깨졌습니다. 중첩 된 optgroup을 허용하고 사용자 에이전트가 중첩 된 메뉴로 렌더링하도록 권장해야합니다. 대신 하나의 optgroup 수준 만 허용 됩니다. 그러나 그들은 주제에 대해 다음과 같이 말해야합니다.
노트. 구현자는 HTML의 향후 버전이 그룹화 메커니즘을 확장하여 중첩 된 그룹을 허용 할 수 있음을 권장합니다 (즉, OPTGROUP 요소가 중첩 될 수 있음). 이를 통해 저자는 더 풍부한 선택 계층 구조를 나타낼 수 있습니다.
그리고 사용자 에이전트는 지금처럼 optgroup의 첫 번째 옵션 요소 앞에 제목을 표시하는 대신 하위 메뉴를 사용하여 optgoup을 렌더링 할 수 있습니다.
이것은 괜찮지 만 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>
좋아, 누군가 이것을 읽는다면 : 가장 좋은 방법은
들여 쓰기의 각 추가 수준에서 4를 추가 하는 것입니다.
그래서:
<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>
구조화되고 복잡한 것이 있다면 단일 드롭 다운 상자가 아닌 다른 것을 고려할 수도 있습니다.
이 게시물 위 의 Broken Arrow의 솔루션 이 정말 마음에 듭니다 . 레이블이라고 불리는 것을 토글 할 수 있고 옵션으로 간주되지 않도록 약간 개선 / 변경했습니다. 나는 작은 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;
}
나는 이것이 꽤 오래 전이라는 것을 알고 있지만 추가 할 약간의 추가 사항이 있습니다.
이는 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>
자신을 선택할 수 있음을 의미합니다 . 예를 들어 범주가 세부적으로 분류되는 중첩 된 범주가 있고 사용자가 계층 구조에서 상위 항목을 선택할 수 있도록하려는 경우 유용 할 수 있습니다.
This will all work without JavaScript, however you might wish to add some to hide the radio buttons and then change the background color of the selected item or something.
Bear in mind, this is far from a perfect solution, but if you absolutely need a nested select with reasonable cross-browser compatibility, this is probably as close as you're going to get.
I needed clean and lightweight solution (so no jQuery and alike), which will look exactly like plain HTML, would also continue working when only plain HTML is preset (so javascript will only enhance it), and which will allow searching by starting letters (including national UTF-8 letters) if possible where it does not add extra weight. It also must work fast on very slow browsers (think rPi - so preferably no javascript executing after page load).
In firefox it uses CSS identing and thus allow searching by letters, and in other browsers it will use
prepending (but there it does not support quick search by letters). Anyway, I'm quite happy with results.
You can try it in action here
It goes like this:
CSS:
.i0 { }
.i1 { margin-left: 1em; }
.i2 { margin-left: 2em; }
.i3 { margin-left: 3em; }
.i4 { margin-left: 4em; }
.i5 { margin-left: 5em; }
HTML (class "i1", "i2" etc denote identation level):
<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();
}
}
참고URL : https://stackoverflow.com/questions/1037732/nesting-optgroups-in-a-dropdownlist-select
'development' 카테고리의 다른 글
ActiveRecord를 사용하면 after_update 중에 레코드의 이전 값을 가져올 수있는 방법이 있습니까? (0) | 2020.10.23 |
---|---|
Eclipse“Link with Editor”에 해당하는 IntelliJ IDEA (0) | 2020.10.23 |
Vim에서 파일 찾기 (재귀 적 디렉토리 검색을 통해) (0) | 2020.10.23 |
C ++의 문자열에서 파일 확장자를 얻는 방법 (0) | 2020.10.22 |
NSDate를 사용하여 요일 가져 오기 (0) | 2020.10.22 |