Is it possible to have multiple layers of optgroup on select2?
Basically, an optgroup inside another optgroup.
<select>
<optgroup label="Level_1">
<optgroup label="Level_2">
<option value="option_1">option_1</option>
<option value="option_2">option_2</option>
</optgroup>
</optgroup>
</select>
Fiddle
Thank you.
Nested optgroups are not supported in html, But you can use JavaScript to create them.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
$(document).ready(function () {
$('#NestedOptGroups').select2({
data: [
{
text: 'Level_1', children: [
{
text: 'Level_2', children: [
{id: 'Level2Opt0', text: 'Sub Option 1'},
{id: 'Level2Opt1', text: 'Sub Option 2'}
]
},
{id: 'Level1Opt0', text: 'Main Level option 1'}
]
}
]
});
});
</script>
</head>
<body>
<input class="select2" id="NestedOptGroups" placeholder="select one"/>
</body>
</html>
Try like this:
<select>
<optgroup label="Level_1">
<optgroup label=" Level_2">
<option value="option_1"> option_1</option>
<option value="option_2"> option_2</option>
</optgroup>
</optgroup>
</select>
Check this Demo
Related
I was using Select2 to have a list of brands and categories, each grouped by <optgroup>.
So far so good, because the list was not changing. Now I have to implement a Product search, which will have no specific values, so you can search for everything you type in.
For example, if the user types in "sho", i want to have:
**Products**
- sho (exactly what the user enters)
**Brands** (suggestions from a list)
- Adidas Shoes
- Nike Shoes
**Categories** (suggestions from a list)
- Shoes for women
- Shoes for men
And as the user types more characters, the sho under Products keeps updating to show what they entered.
The code for the previous version was:
<select id="search_bar">
<option></option>
<optgroup label="Stores">
{% for merchant in all_merchants %}
<option value="{% url %}">{{ merchant.display_name }}</option>
{% endfor %}
</optgroup>
<optgroup label="Categories">
{% for category in all_categories %}
<option value="{% url %}">{{ category.name }}</option>
{% endfor %}
</optgroup>
</select>
I tried enabling tags, by doing tags: true, and it works but not entirely, because if I type in something that matches a brand or a category, the tag will disappear. I.E, if i type "Adidas", it will show only the Adidas under brands (so if i click it, I'm taken to the brand page), but not as a tag that i can click and be taken to the product search page.
Does that make sense?
Ok its first try, i you click on new tag to create, i keep it in the list of firstdropdown and you have propagation in the second dropdown (at least 2 character minimun):
$('#source').select2({
tags:true
});
$('#search').select2({
tags:true,
insertTag:function (data, tag) {
data.push(tag);
},
createTag: function (params) {
return {
id: params.term,
text: params.term,
newTag: true
}
},
matcher: matchCustom,
}).on("select2:select", function(e) {
// if( e.params.data.newTag){
select2_search($("#source"), e.params.data.text);
$(this).find('[value="'+e.params.data.id+'"]').replaceWith('<option selected value="'+e.params.data.id+'">'+e.params.data.text+'</option>');
// }
//uncomment if you want to play the same search
//$("#search").val("0").trigger("change");
});
function matchCustom(params, data) {
// If there are no search terms, return all of the data
if ($.trim(params.term) === '') {
return data;
}
// Do not display the item if there is no 'text' property
if (typeof data.text === 'undefined') {
return null;
}
// Return `null` if the term should not be displayed
return null;
}
function select2_search ($el, term) {
$el.select2('open');
// Get the search box within the dropdown or the selection
// Dropdown = single, Selection = multiple
var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;
// This is undocumented and may change in the future
$search.val(term);
$search.trigger('input');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet"/>
<select id ="search" class="myselect" style="width:50%;" >
<option value="0"></option>
</select> <prev><== Type new tag into search</prev>
<br><br><br><br><br><br><br><br>
<select style="width:100%;" id="source" multiple="" tabindex="-1" aria-hidden="true">
<optgroup class="select2-result-selectable" label="Brand" >
<option value="Adidas shoes">Adidas shoes</option>
<option value="Pantalon">Pantalon</option>
<option value="short">short</option>
</optgroup>
<optgroup class="select2-result-selectable" label="Categories" >
<option value="Shoes for men">Shoes for men</option>
<option value="Shoes for women">Shoes for women</option>
<option value="Other things for wommen">Other things for women</option>
<option value="Other things for men">Other things for men</option>
</optgroup>
</select>
I am using Bootstrap multiselect (https://davidstutz.github.io/bootstrap-multiselect/)
I have 2 groups inside the dropdown.
Upon selecting any option in top group, all the items in second group should get disabled.
I should be able to select any of the options from the second group.
My controller to bind the data, the list is grouped by county_category. :
public void CHDSList()
{List<SelectList> CHDSListList = new List<SelectList>();
ViewData["CHDSList"] = new SelectList((from s in objentity.tbl_CountiesMst.ToList().OrderBy(a => a.County_Code)
select new
{
County_Code = s.County_Code,
County_Name = s.County_Code +" - " + s.County_Name,
County_category = s.County_Category
}), "County_Code", "County_Name", "county_category", 1);
}
In the view, I have this...
$('.listbox').multiselect({
includeSelectAllOption: false,
buttonWidth: '100%',
maxHeight: 200,
enableClickableOptGroups: true })
#Html.ListBox("ChdListBox", (SelectList)(IEnumerable<SelectListItem>)ViewData["CHDSList"],
new { #class = "listbox", #style = "text-align:left; multiple=multiple;
width:100px;min-width:100%; height:30px; border-color:lightblue" })
multiselect dropdown image
You can use id property of the optgroup in multiselect to disable the group by using jquery. And dont forget to refresh the multiselect after disabling as shown in the code snippet.
After disabling if you want to select then you must enable it.
Refer this code snippet:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.13/js/bootstrap-multiselect.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-multiselect/0.9.13/css/bootstrap-multiselect.css" type="text/css"/>
<script type="text/javascript">
$(document).ready(function () {
$('#multiselect').multiselect({
onChange: function (option, checked, select) {
var groupId = $(option).closest('optgroup').prop('id')
if (groupId == "optgroup1") {
$('#multiselect optgroup#optgroup2').prop('disabled', true);
$('#multiselect').multiselect('refresh');
}
}
})
});
</script>
</head>
<body>
<select id="multiselect" multiple="multiple">
<optgroup label="Group 1" id="optgroup1">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</optgroup>
<optgroup label="Group 2" id="optgroup2">
<option value="4">Option 4</option>
<option value="5">Option 5</option>
<option value="6">Option 6</option>
</optgroup>
</select>
</body>
</html>
How do you select an option or set the value in a select list that has option groups?
This method does not work: How to change a dropdown in an F# Canopy UI Testing Script
sample code:
<!DOCTYPE html>
<html>
<body>
<select id="test-select">
<optgroup label="Swedish Cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
</optgroup>
<optgroup label="German Cars">
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</optgroup>
</select>
</body>
</html>
Canopy Test:
open canopy
open runner
open Helpers
let all() =
context "OptGroup Tests"
let page = ""
ntest ("Testing page " + page) (fun _ ->
let mUrl = testpage.html
url mUrl
"#test-select" << "Audi"
)
I am using #Html.DropDownListFor to build a select object that looks like this:
<select id="GroupCode" name="GroupCode" tabindex="4"><option value="">Select One</option>
<option value="1">One thing</option>
<option value="17">Another thing</option>
<option value="7">A Third thing</option>
</select>
There comes a time when something else changes on the page, and I want to swap out the options, ending up with something like
<select id="GroupCode" name="GroupCode" tabindex="4"><option value="">Select One</option>
<option value="21">A completely different list</option>
<option value="17">A second item only</option>
</select>
However, when I set a breakpoint in the view and look at $('#GroupCode').html, I see something like this:
$('#GroupCode').html
function(a){return p.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(bm,""):b;if(typeof a=="string"&&!bs.test(a)&&(p.support.htmlSerialize||!bu.test(a))&&(p.support.leadingWhitespace||!bn.test(
__proto__:
function() {
[native code]
}
arguments: null
caller: null
length: 1
prototype: {...}
where I was expecting to see something like the html above.
What I'm concerned about is whether, by replacing the html for #GroupCode, I will lose what was provided by the #Html.DropDownFor code.
Bottom line: what is a good way to replace the contents of a dropdown list like this?
See this Working fiddle example
HTML
<select id="GroupCode" name="GroupCode" tabindex="4">
<option value="">Select One</option>
<option value="1">One thing</option>
<option value="17">Another thing</option>
<option value="7">A Third thing</option>
</select>
<button id="testBtn" type="button">replace list with items with ids (21, 7)</button>
Script:
$(function () {
$(document).on("click", "#testBtn", function () {
$('#GroupCode').empty().append(
$('<option/>', {
value: "",
text: 'Select One'
}),
$('<option/>', {
value: "21",
text: "A completely different list"
}),
$('<option/>', {
value: "17",
text: "A second item only"
}));
});
});
I saved this code as an html file, but I'm not being able to visualize the map. I took the code directly from FusionTablesLayer Wizard 2.0. Is it something wrong with the code? I thought that it would be 'ready to use'. I need some help!
<!DOCTYPE html>
<html>
<head>
<style>
#map-canvas { width:500px; height:400px; }
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript">
var map;
var layerl0;
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(0, 0),
zoom: 1,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layerl0 = new google.maps.FusionTablesLayer({
query: {
select: "'geometry'",
from: 1x46BzbRzLVz2S4_ml5Nx4oto2930DFrH39TM3uc
},
map: map
});
}
function changeMapl0() {
var searchString = document.getElementById('search-string-l0').value.replace(/'/g, "\\'");
layerl0.setOptions({
query: {
select: "'geometry'",
from: 1x46BzbRzLVz2S4_ml5Nx4oto2930DFrH39TM3uc,
where: "'NOME' = '" + searchString + "'"
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div style="margin-top: 10px;">
<label>Escolha a cidade</label>
<select id="search-string-l0" onchange="changeMapl0(this.value);">
<option value="">--Select--</option>
<option value="ALVORADA">ALVORADA</option>
<option value="ARARICA">ARARICA</option>
<option value="ARROIO DOS RATOS">ARROIO DOS RATOS</option>
<option value="CACHOEIRINHA">CACHOEIRINHA</option>
<option value="CAMPO BOM">CAMPO BOM</option>
<option value="CANOAS">CANOAS</option>
<option value="CAPELA DE SANTANA">CAPELA DE SANTANA</option>
<option value="CHARQUEADAS">CHARQUEADAS</option>
<option value="DOIS IRMAOS">DOIS IRMAOS</option>
<option value="ELDORADO DO SUL">ELDORADO DO SUL</option>
<option value="ESTANCIA VELHA">ESTANCIA VELHA</option>
<option value="ESTEIO">ESTEIO</option>
<option value="GLORINHA">GLORINHA</option>
<option value="GRAVATAI">GRAVATAI</option>
<option value="GUAIBA">GUAIBA</option>
<option value="IVOTI">IVOTI</option>
<option value="MONTENEGRO">MONTENEGRO</option>
<option value="NOVA HARTZ">NOVA HARTZ</option>
<option value="NOVA SANTA RITA">NOVA SANTA RITA</option>
<option value="NOVO HAMBURGO">NOVO HAMBURGO</option>
<option value="PAROBE">PAROBE</option>
<option value="PORTAO">PORTAO</option>
<option value="PORTO ALEGRE">PORTO ALEGRE</option>
<option value="ROLANTE">ROLANTE</option>
<option value="SANTO ANTONIO DA PATRULHA">SANTO ANTONIO DA PATRULHA</option>
<option value="SAO JERONIMO">SAO JERONIMO</option>
<option value="SAO LEOPOLDO">SAO LEOPOLDO</option>
<option value="SAPIRANGA">SAPIRANGA</option>
<option value="SAPUCAIA DO SUL">SAPUCAIA DO SUL</option>
<option value="TAQUARA">TAQUARA</option>
<option value="TRIUNFO">TRIUNFO</option>
<option value="VIAMAO">VIAMAO</option>
</select>
</div>
</body>
</html>
The only missing thing are the quotes around the encoded table ids :-)
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(0, 0),
zoom: 1,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layerl0 = new google.maps.FusionTablesLayer({
query: {
select: "'geometry'",
from: "1x46BzbRzLVz2S4_ml5Nx4oto2930DFrH39TM3uc"
},
map: map
});
}
function changeMapl0() {
var searchString = document.getElementById('search-string-l0').value.replace(/'/g, "\\'");
layerl0.setOptions({
query: {
select: "'geometry'",
from: "1x46BzbRzLVz2S4_ml5Nx4oto2930DFrH39TM3uc",
where: "'NOME' = '" + searchString + "'"
}
});
}
I put your code on jsFiddle with my correction.
My understanding was that the encrypted doc id's only apply to the Fusion Table API but not to the GMaps API for Fusion Table layers. Visit your table via the FT UI and select File -> About which will display both the Encrypted Id and the Numeric ID. Try using the Numeric ID instead of the encrypted id:
layerl0 = new google.maps.FusionTablesLayer({
query: {
select: "'geometry'",
from: 1x46BzbRzLVz2S4_ml5Nx4oto2930DFrH39TM3uc // change this to numeric id
},