How to do a multi-level select field? - javascript

As in my title mentioned I would like to have a select field where I can click on a option Item and then it shows me the suboptions. I only found solutions where you divide it in optgroups but then all the options are visible or I found something which is formatted.
My idea to solve this was the following:
Html
<select data-role="select" data-filter="false" v-on:change="boolValueChanger(testSelector)">
<option value="testSelector">vegetable</option>
<optgroup v-if="testSelector" label="vegetable">
<option value="123123">pepper</option>
<option value="4565">spinach</option>
<option value="64734">broccoli</option>
</optgroup>
<optgroup label="fruits">
<option value="43534">banana</option>
<option value="3345">apple</option>
<option value="45645">orange</option>
</optgroup>
</select>
JS
setup(props) {
return {testSelector: ref(false) };
},
methods: {
boolValueChanger: function (x) {
if (x === true) this.testSelector = false;
else this.testSelector = true;
}
}
My idea was to make a "main menu" where I can select my optgroup (in my example that would be vegetable). If I select that the testSelector would be changed and the optgroups would display but unfortunately that didn't work. My example would be look ok but if I have like 200 options this would be look not so good anymore and a user would have to scroll a lot(I could use a search filter but if the options are unknown to the user this is also not nice).
Does anyone have an idea how I could realize something like that?

Related

jquery change() event acting strange

So I am making two dropdowns. One is dependent on the other one, as in when you choose an option in the first dropdown, the values in the other should change. I am rendering my form with Symfony3.4, so I do not have much control over it. (I do not think I can add dynamic class names/value names to it). If it is relevant, I am using Bulma css framework.
Here is what my selectboxes look like:
states:
<select name="state" id="stateSelect">
<option value="1">Lagos</option>
<option value="2">Abuja</option>
<option value="3">Rivers</option>
<option value="4">Ogun</option>
<option value="5">Oyo</option>
<option value="6">Anambra</option>
<option value="7">Enugu</option>
<option value="8">Akwa Ibom</option>
<option value="9">Adamawa</option>
...
<option value="37">Zamfara</option>
</select>
LGA (local government areas):
<select id="lgaSelect" name="areas_registration[lga]">
<optgroup label="Lagos">
<option value="1">Abule Egba</option>
<option value="2">Agege</option>
<option value="3">Ajah</option>
<option value="4">Alimosho</option>
<option value="5">Amuwo Odofin</option>
...
</optgroup>
<optgroup label="Abuja">
<option value="38">Apo</option>
<option value="39">Asokoro</option>
<option value="40">Central Area</option>
<option value="41">Chika</option>
<option value="42">Dakibiyu</option>
...
</optgroup>
....35 more optgroups
</select>
My goal is when a user chooses an option from States dropdown, the LGA dropdown should only have options relevant to the selected state. I am using optgroup label for this. What I tried in my javascript is that when the page loads, I clone the LGA dropdown, hide it, call it lgaSelectSeed and use it for seeding the original LGA dropdown: (#hiddenLgas is just an empty div)
$(function () {
var stateSelect = $("#stateSelect") || null;
var lgaSelect = $("#lgaSelect") || null;
var hiddenLga = $("#hiddenLgas") || null;
$(hiddenLga).html(lgaSelect.clone().prop('id', 'lgaSelectSeed'));
stateSelect.change(function () {
var select_class = $(this).find('option:selected').text();
var options = $(lgaSelectSeed).find('optgroup[label="' + select_class + '"]');
$(lgaSelect).html(options.children());
}
This works but there is a bug in it. If you select random options in the state dropdown, and then go up and select Lagos or Abuja, the LGA dropdown becomes blank. I have been trying to figure out for a few days why this is happening, but still cant. Is there any jquery plugin to handle this instead?
DEMO: https://jsfiddle.net/gafyvbL9/
How to replicate the bug: In the states dropdown (left), choose Lagos. Then choose Anambra. Then choose Lagos again, then choose Anambra. You can see that the LGA dropdown (right) becomes empty. Why is this happening? Thanks in advance
Make a clone of the stored options so you don't remove the originals from $(hiddenLga)
Change:
$(lgaSelect).html(options.children());
To
$(lgaSelect).html(options.children().clone());
Playing with your fiddle, I think the issue is when you perform $(lgaSelect).html(), you're deleting all of the information stored there. Try storing that outside of your handler.
let $options = $('#lgaSelect').clone();
$("#stateSelect").on('change',function() {
let state = $(this).find('option:selected').text();
$("#lgaSelect").html($options.find(`optgroup[label="${state}"]`).html());
});
EDIT:
Notice the double quote in optgroup[label="${state}"]. This prevents issue with states that contain a space, like Akwa Ibom.

JavsScript can not click on element "option"

Below is the HTML code for the element I want to click:
<select id = "per-page-xxxxxxxx" //xxxxxxx is a dynamic string
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
It is basically a dropdown list that allow you to choose how many items to be displayed on current page.
My code to click <option value="100">100</option> is:
var dropdownListXpath = "//select[starts-with(#id,'per-page-')]";
var PublicationPerPageOptionXpath = "//select[starts-with(#id,'per-page-')]/option[#value='100']";
var dropdownList;
var PublicationPerPageOption;
aqUtils.Delay(500);
try {
dropdownList = PageObj.EvaluateXpath(dropdownListXpath);
dropdownList[0].Click();
aqUtils.Delay(500);
PublicationPerPageOption = PageObj.EvaluateXpath(PublicationPerPageOptionXpath);
PublicationPerPageOption[0].Click();
}
catch(err) {
Log.Message("Can not find options to show 100 publications per page.");
}
The result:
Dropdown list is clicked and expanded, then nothing happens afterwards, e.g. option 100 is not clicked
Can anyone please provide any help?

Can I have my list tile as first option with null value?

So here is my code
<select id="BVT STUFF" onChange="jumpTo(getSelected(this));">
<option>HardRock Catalog</option>
<option value="http://link">BVT WIKI</option>
<option value="http://link">BVT CALENDAR</option>
<option value="https://link">Sustainment</option>
<option value="link">UVerse Dispatch Servlet</option>
This is a tool that I created for my team.
My problem is that I have the list "Title" as the first option and tried to give it a null value but whenever it is selected it tries to open a page. i.e. HardRock Catalog
Is there anything I could do with this to allow the list title to really have no value?
I'll suggest to add value="" for the first option. Then in your jumpTo function check
<option value="">HardRock Catalog</option>
function jumpTo(url) {
if(url === "") return;
// other stuff here
}
You could add selected and disabled attributes.
jsfiddle
HTML
<option selected="selected" disabled>HardRock Catalog</option>
You may try this
HTML :
<select onchange="jumpTo(this)">
<option value='0'>HardRock Catalog</option>
<option value="http:\\google.com">Goto Google</option>
<option value="http:\\yahoo.com">Goto Yahoo</option>
</select>
JS :
function jumpTo(select)
{
if(select.value != '0'){
// code goes here
location.href = select.value;
}
}
DEMO.

JQuery drop down menu on change show div when certain menu items are selected

I am trying to get a Div to show when certain items are selected from a drop down menu. For some reason it is showing when any of the items in the menu are selected and I cant figure out why. Thanks for your help!
<select class="selectDesign" id="designOne" name="design1">
<option value="none">None</option>
<option value="ace">Ace</option>
<option value="aerialist">Aerialist</option>
<option value="anthropologie">Anthropologie</option>
<option value="clare">Clare</option>
<option value="darcy">Darcy</option>
<option value="dauphine">Dauphine</option>
<option value="derby">Derby</option>
<option value="signature">Signature</option>
</select>
<div id="showPaints" style="display: none"><p>My Stuff</p></div>
javaScript
jQuery("#designOne").change(function(){
jQuery("#showPaints").hide("slow");
if (jQuery("#designOne").val() == "signature" , "ace" ) {
jQuery("#showPaints").show("slow");
}
});
This line is.. odd syntax.
if (jQuery("#designOne").val() == "signature" , "ace" )
Try:
var chosenValue = jQuery("#designOne").val();
if (chosenValue == "signature" || chosenValue == "ace" )
I think the , 'ace' might be getting translated to boolean true therefore the if always gets hit. I might just run a test in jsfiddle.

recreate an array based on options selected

I need help solving a simple requirement.
<select id="my-select1">
<option value="1">This is option 1 ({myop1}|OP)</option>
<option value="2" selected>This is option 2 ({myop1}|OQ)</option>
<option value="3">This is option 3 ({myop1}|OR)</option>
</select>
<select id="my-select2">
<option value="1">This is option 1 ({myop2}|PP)</option>
<option value="2">This is option 2 ({myop2}|PQ)</option>
<option value="3" selected>This is option 3 ({myop2}|PR)</option>
</select>
<select id="my-select3">
<option value="1">This is option 1 ({myop3}|QP)</option>
<option value="2">This is option 2 ({myop3}|QQ)</option>
<option value="3" selected>This is option 3 ({myop3}|QR)</option>
</select>
See the HTML above, I want to recreate my array:
combo = ["abc-{myop1}-{myop2}", "def-{myop2}"];
INTO
combo = ["abc-OQ-PR", "def-PR"];
based on the selected options.
Another thing to note is that I cannot simply change the value of the options of the select box, meaning to say the HTML is somewhat as it is, if it would help, the only part i can restructure on that HTML is the text content between <option></option>
I'm not sure, but I'm already spending a couple of hrs just to solve this problem. Maybe due to my limited jQuery knowledge.
Please help. thanks
Get the selected values into an associative array:
var pattern = {};
var s = $('select option:selected').each(function(){
var m = /\((.*?)\|(.*)\)/.exec($(this).text());
pattern[m[1]] = m[2];
});
Then you can replace each place holder in each string in the array with the corresponding value:
combo = $.map(combo, function(e){
return e.replace(/\{.*?\}/g, function(m){
return pattern[m];
});
});
Demo: jsfiddle.net/C97ma/
Based on the information you provided I'm don't get it 100% I guess. But whatever you're trying to do, I guess jQuerys .map() and $.map() would help you here.
Like
var arr = $('select').find('option:selected').map(function(index, elem) {
return elem.textContent || elem.text;
}).get();
Demo: http://www.jsfiddle.net/4yUqL/78/
Within the callback you can modify/match the text in any way you want/need. In your case I could imagine you want to use a regular expression to match the selected strings and recreate those somehow.
I figure you're using javascript for combining those (it can be done with PHP also)..
You need references to your selects, e.g. :
<script type="text/javascript">
a=document.getElementById("myselect").options[1];
</script>
This will assign the 2nd option value from the 'myselect' select element to the variable 'a'
To begin with I would change the values in the select box like this:
<select id="my-select1">
<option value="OP">This is option 1 ({myop1}|OP)</option>
<option value="OQ" selected>This is option 2 ({myop1}|OQ)</option>
<option value="OR">This is option 3 ({myop1}|OR)</option>
</select>
<select id="my-select2">
<option value="PP">This is option 1 ({myop2}|PP)</option>
<option value="PQ">This is option 2 ({myop2}|PQ)</option>
<option value="PR" selected>This is option 3 ({myop2}|PR)</option>
</select>
<select id="my-select3">
<option value="QP">This is option 1 ({myop3}|QP)</option>
<option value="QQ">This is option 2 ({myop3}|QQ)</option>
<option value="QR" selected>This is option 3 ({myop3}|QR)</option>
</select>
Now to update your array:
var comboDef = ["abc-{myop1}-{myop2}", "def-{myop2}"];
var combo = ["abc-{myop1}-{myop2}", "def-{myop2}"];
function updateArray() {
combo = comboDef;
for (i in combo)
{
combo[i] = combo[i].replace("{myop1}",document.getElementById("my-select1").value);
combo[i] = combo[i].replace("{myop2}",document.getElementById("my-select2").value);
combo[i] = combo[i].replace("{myop3}",document.getElementById("my-select3").value);
}
}
Of course, this could be done better with proper arrays (if you gave your select boxes the same name you could iterate through them using document.getElementsByName()). The basic idea is the replace though which I trust is what you're looking for.

Categories