Replace dropdown options with only those that match values in an array - javascript

Hi I am struggling with doing this in raw JavaScript. Currently I have two dropdowns a parent and a child like so:
<select id="state" title="" name="state">
<option selected="selected" value="Open" label="Open">Open</option>
<option value="Closed" label="Closed">Closed</option>
</select>
<select id="status" title="" name="status">
<option value="Open_New" label="New">New</option>
<option value="Open_Assigned" label="Assigned">Assigned</option>
<option value="Closed_Closed" label="Closed">Closed</option>
<option value="Open_Pending Input" label="Pending External Input">Pending External Input</option>
<option value="Open_Pending" label="Pending Internal Input">Pending Internal Input</option>
<option value="Closed_Duplicate" label="Duplicate">Duplicate</option>
<option value="Open_CARD" label="CARD">CARD</option>
<option value="Open_Open" label="Open">Open</option>
<option value="Open_DAD" label="DAD">DAD</option>
<option value="Closed_Rejected" label="Rejected">Rejected</option>
</select>
And the child dropdown values are selected based on the parent dropdown values name with and an underscore:
function updateDynamicEnum(field, subfield){
if(document.getElementById(subfield) != null){
var selector = document.getElementById(subfield);
var de_key = document.getElementById(field).value;
var current = [];
for (var i = 0; i < selector.length; i++) {
if (selector.options[i].selected) current.push(selector.options[i].value);
}
if(de_entries[subfield] == null){
de_entries[subfield] = new Array;
for (var i=0; i<selector.options.length; i++){
de_entries[subfield][selector.options[i].value] = selector.options[i].text;
}
}
document.getElementById(subfield).innerHTML = '';
for (var key in de_entries[subfield]) {
if(key.indexOf(de_key+'_') == 0){
selector.options[selector.options.length] = new Option(de_entries[subfield][key], key);
}
}
for (var key in current) {
for (var i = 0; i < selector.length; i++) {
if(selector.options[i].value == current[key])
selector[i].selected = true;
}
}
}
What I need to do is change this code so that child dropdown values are not selected based on the key name with an underscore but selected when they are part of an array that is passed in. The array is called child_strings and looks like this:
'open' => array(
'Open_New',
'Open_Assigned',
'Open_Pending Input',
'Open_Pending',
'Open_CARD',
'Open_Open',
'Open_DAD'
),
'closed' => array(
'Open_Assigned',
'Closed_Closed',
'Closed_Duplicate',
'Closed_Rejected',
),
my new code looks like this:
function updateDynamicEnum(field, subfield, child_strings){
//console.log(child_strings);
if(document.getElementById(subfield) != null){
var de_key = document.getElementById(field).value;
var child = document.getElementById(subfield);
var current = [];
for (var i = 0; i < child.length; i++) {
if (child.options[i].selected) current.push(child.options[i].value);
}
if(de_entries[subfield] == null){
de_entries[subfield] = new Array;
for (var i=0; i<child.options.length; i++){
de_entries[subfield][child.options[i].value] = child.options[i].text;
}
}
document.getElementById(subfield).innerHTML = '';
//this part needs changes
for (var key in de_entries[subfield]) {
if(key.indexOf(de_key+'_') == 0){
child.options[child.options.length] = new Option(de_entries[subfield][key], key);
}
}
But struggling to see how to check child_strings and determine if the vales is in that array etc..

I figured the answer out for myself but if somebody can post a better one please go ahead.
function updateDynamicEnum(field, subfield, child_strings){
if(document.getElementById(subfield) != null){
var de_key = document.getElementById(field).value;
var child = document.getElementById(subfield);
var current = [];
for (var i = 0; i < child.length; i++) {
if (child.options[i].selected) current.push(child.options[i].value);
}
if(de_entries[subfield] == null){
de_entries[subfield] = new Array;
for (var i=0; i<child.options.length; i++){
de_entries[subfield][child.options[i].value] = child.options[i].text;
}
}
document.getElementById(subfield).innerHTML = '';
var arg = child_strings[de_key];
for (var key in de_entries[subfield]) {
if(isInArray(key,arg)){
child.options[child.options.length] = new Option(de_entries[subfield][key], key);
}
}
for (var key in current) {
for (var i = 0; i < child.length; i++) {
if(child.options[i].value == current[key])
child[i].selected = true;
}
}
}
/*Checks if value is in an array*/
function isInArray(value, array) {
return array.indexOf(value) > -1;
}
}

Related

How to Randomly Choose Selected Item in Select Dropdown that wasn't chosen before in JavaScript?

On a button click, I want to run a function that will each time randomly select an option from a select dropdown that wasn't chosen before. And if all options were chosen, I want to reset the used options and start from the beginning.
I have a function that chooses an element that wasn't chosen before randomly from an array (credit to #Rajesh)
function randomize(arr) {
let data = [...arr];
let chosenItems = [];
function getRandomValue() {
if (data.length === 0) {
data = chosenItems;
chosenItems = [];
}
const index = Math.floor(Math.random() * data.length);
const choice = data.splice(index, 1)[0];
chosenItems.push(choice);
return choice;
}
return {
randomItem: getRandomValue
}
}
const dummyData = [ 1,2,3,4,5 ];
const randomizeData = randomize(dummyData);
for (let i = 0; i< 10; i++) {
console.log(randomizeData.randomItem())
}
I have already created a script that randomly chooses an element from a select2 dropdown but it selects the same element very often.
var optionsArray = new Array();
var first = $('select option')[0];
$('select option').each(function () { optionsArray.push(this) });
if (optionsArray.length > 1) {
$('select').html('');
var i = 0;
var random
while (i < optionsArray.length) {
random = Math.floor(Math.random() * optionsArray.length)
//if element hasn't been marked as "selected"
if (optionsArray[random] != "selected") {
$("select").append(optionsArray[random]);
//mark element as selected
optionsArray[random] = "selected"
i++
}
}
var newSelectedOption = $('select option')[0];
$('select').val($(newSelectedOption).val()).trigger('change');
<html>
<body>
<select id="dropdown">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button id="btn">
Generate
</button>
</body>
<script>
let dropdown = document.getElementById('dropdown');
var options = [];
var chosenItems = [];
function setOptions(){
for(var i = 0; i < dropdown.options.length; i++)
options.push(dropdown.options[i].value);
}
document.getElementById('btn').addEventListener("click", function(){
options = options.filter( function( el ) {
return chosenItems.indexOf( el ) < 0;
});
if(options.length == 0){
console.log("reset data")
setOptions();
chosenItems = [];
}
var unSelectedRandom = options[Math.floor(Math.random() * options.length)]
for(var i = 0; i < dropdown.options.length; i++){
var current = dropdown.options[i]
if ( current.value == unSelectedRandom ) {
dropdown.selectedIndex = i;
chosenItems.push(current.value);
console.log("chosen: "+chosenItems)
}
}
});
</script>
</html>

swapping values between two multi select boxes in javascript

How to select the first element in select box a, if I am at last position. if I am in middle of the list I am able to select but not able to select the first item in list if my current position is last.
function MoveSelected(objSourceElement, objTargetElement)
{
var aryTempSourceOptions = new Array();
var x = 0;
var y = 0;
//looping through source element to find selected options
for (var i = 0; i < objSourceElement.length; i++) {
if (objSourceElement.options[i].selected) {
y++;
//need to move this option to target element
var intTargetLen = objTargetElement.length++;
objTargetElement.options[intTargetLen].text = objSourceElement.options[i].text;
objTargetElement.options[intTargetLen].value = objSourceElement.options[i].value;
}
else {
//storing options that stay to recreate select element
var objTempValues = new Object();
objTempValues.text = objSourceElement.options[i].text;
objTempValues.value = objSourceElement.options[i].value;
aryTempSourceOptions[x] = objTempValues;
x++;
}
}
if (y==0) alert("Please select any Course");
//resetting length of source
objSourceElement.length = aryTempSourceOptions.length;
//looping through temp array to recreate source select element
for (var i = 0; i < aryTempSourceOptions.length; i++) {
objSourceElement.options[i].text = aryTempSourceOptions[i].text;
objSourceElement.options[i].value = aryTempSourceOptions[i].value;
//objSourceElement.options[i].selected = false;
}
}
I'm late to this party but I have code that swaps selected values between two containers, taking care to keep track of option groups if they exist:
function MoveSelectedItems(source, destination)
{
var sourceElement = document.getElementById(source);
var destinationElement = document.getElementById(destination);
var toSource = {};
var toDestination = {};
// Move all children from our destination element into our toDestination
// dicationary. This will be used to make sure groups are properly populated
// between source and destination
while (destinationElement.firstChild)
{
var child = destinationElement.firstChild;
destinationElement.removeChild(child);
toDestination[child.label] = child;
}
// Loop through all the children of our source and move them to toDestination if
// they're selected and to toSource if not. Also creates options groups as necessary
while (sourceElement.firstChild)
{
var outerChild = sourceElement.firstChild;
sourceElement.removeChild(outerChild)
// If the current outerChild is an option group...
if (outerChild.nodeName == 'OPTGROUP')
{
// Loop through the children of the current option group outer child
while (outerChild.firstChild)
{
var innerChild = outerChild.firstChild;
outerChild.removeChild(innerChild);
// If the child of the option group is selected...
if (innerChild.selected == true)
{
// If the option group isn't already in the destination dictionary
// add it using the label of the outer child as the key
if (!(outerChild.label in toDestination))
{
toDestination[outerChild.label] = document.createElement('optgroup');
toDestination[outerChild.label].label = outerChild.label;
}
innerChild.selected = false;
// Add the inner child to it's parent group in the destination dictionary
toDestination[outerChild.label].appendChild(innerChild);
}
else // If the child of the option group isn't selected...
{
// If the option group isn't already in the source ditionary
// add it using the label of the outer child as the key
if (!(outerChild.label in toSource))
{
toSource[outerChild.label] = document.createElement('optgroup');
toSource[outerChild.label].label = outerChild.label;
}
innerChild.selected = false;
// Add the inner child to it's parent group in the source dictionary
toSource[outerChild.label].appendChild(innerChild);
}
}
}
else if (outerChild.nodeName == 'OPTION') // If the outer child is an option...
{
// If the outer child is selected, add it to the destination
// dictionary using its label as the key.
// Otherwise, if the the outer child is not selected, add it to
// the source dictionary using it's label as the key.
if (outerChild.selected == true)
{
outerChild.selected = false;
toDestination[outerChild.label] = outerChild;
}
else
{
toSource[outerChild.label] = outerChild;
}
}
}
// Loop through the elements in toSource, sort them and append them to
// the Source element
for (var i in toSource)
{
sourceElement.appendChild(toSource[i]);
}
// Loop through the elements in toDestination, sort them and append them to
// the Destination element
for (var i in toDestination)
{
destinationElement.appendChild(toDestination[i]);
}
}
Java Script Function :
function listbox_move(listID, direction) {
var listbox = document.getElementById(listID);
var selIndex = listbox.selectedIndex;
if (-1 == selIndex) {
alert("Please select an option to move.");
return;
}
var increment = -1;
if (direction == 'up')
increment = -1;
else
increment = 1; if ((selIndex + increment) < 0 || (selIndex + increment) > (listbox.options.length - 1)) {
return;
}
var selValue = listbox.options[selIndex].value;
var selText = listbox.options[selIndex].text;
listbox.options[selIndex].value = listbox.options[selIndex + increment].value
listbox.options[selIndex].text = listbox.options[selIndex + increment].text
listbox.options[selIndex + increment].value = selValue;
listbox.options[selIndex + increment].text = selText;
listbox.selectedIndex = selIndex + increment;
}
function listbox_moveacross(sourceID, destID) {
var src = document.getElementById(sourceID);
var dest = document.getElementById(destID);
for (var count = 0; count < src.options.length; count++) {
if (src.options[count].selected == true) {
var option = src.options[count];
var newOption = document.createElement("option");
newOption.value = option.value;
newOption.text = option.text;
newOption.selected = true;
try {
dest.add(newOption, null);
src.remove(count, null);
} catch (error) {
dest.add(newOption);
src.remove(count);
}
count--;
}
}
}
function listbox_selectall(listID, isSelect) {
var listbox = document.getElementById(listID);
for (var count = 0; count < listbox.options.length; count++) {
listbox.options[count].selected = isSelect;
}
}
HTML Code :
<table>
<tr valign="top">
<td>
<SELECT id="s" size="10" multiple>
<OPTION value="a">Afghanistan</OPTION>
<OPTION value="b">Bahamas</OPTION>
<OPTION value="c">Barbados</OPTION>
<OPTION value="d">Belgium</OPTION>
<OPTION value="e">Bhutan</OPTION>
<OPTION value="f">China</OPTION>
<OPTION value="g">Croatia</OPTION>
<OPTION value="h">Denmark</OPTION>
<OPTION value="i">France</OPTION>
</SELECT>
</td>
<td valign="center">
>>
<br/>
<<
</td>
<td>
<SELECT id="d" size="10" multiple>
<OPTION value="a">Afghanistan</OPTION>
<OPTION value="b">Bahamas</OPTION>
<OPTION value="c">Barbados</OPTION>
<OPTION value="d">Belgium</OPTION>
<OPTION value="e">Bhutan</OPTION>
<OPTION value="f">China</OPTION>
<OPTION value="g">Croatia</OPTION>
<OPTION value="h">Denmark</OPTION>
<OPTION value="i">France</OPTION>
</SELECT>
</td>
</tr>
</table>

how to store value of multiselect listbox in javascript

I have one multiselect listbox in my HTMl.
I want to get values of selected items of listbox in javascript
My html code:
<select id="schools" size="5" multiple="multiple">
<option value="352">Byskovskolen</option>
<option value="355">Heldagsskolen Specialtilbud</option>
<option value="372">Plejecenter Solbakken</option>
</select>
My Javascript code:
function getData()
{
var allSchools = [];
var s = document.getElementById("schools");
alert("schools lenght " + s.options.length);
for (var i = 0; i < s.options.length; i++) {
if (s.options[i].selected == true) {
var schoolid = s.options[i].value;
alert(s.options[i].value);
allSchools.push(schoolid);
}
}
}
Values can be seen alerted with alert box but not getting stored in variable.
How can I store it in variable.
It works fine if you comment/uncomment the right lines. Try this:
function getData() {
var allSchools = [];
var s = document.getElementById("schools");
for (var i = 0; i < s.options.length; i++) {
if (s.options[i].selected == true) {
var schoolid = s.options[i].value;
allSchools.push(schoolid);
}
}
console.log(allSchools);
}
DEMO: http://jsfiddle.net/4qYht/1/
Uncommented one line (var schoolid) and added a print out for the allSchools variable.
function getData()
{
var allSchools = [];
var s = document.getElementById("schools");
alert("schools lenght " + s.options.length);
for (var i = 0; i < s.options.length; i++) {
if (s.options[i].selected == true) {
var schoolid = s.options[i].value;
allSchools.push(schoolid);
}
}
console.log(allSchools);
}
uncomment the schoolid assignment line
var schoolid = s.options[i].value;
allSchools.push(schoolid);
or
use allSchools.push(s.options[i].value); instead of allSchools.push(schoolid);
You have commented out the main line ,which would store the value in a variable.
// var schoolid = s.options[i].value;
apart from that rest of your code is perfect.
here is the corrected code :
function getData()
{
var allSchools = [];
var s = document.getElementById("schools");
alert("schools lenght " + s.options.length);
for (var i = 0; i < s.options.length; i++) {
if (s.options[i].selected == true) {
// var schoolid = s.options[i].value;
alert(s.options[i].value);
allSchools.push(schoolid);
}
}
}
Happy coding:)

Checking for duplicate entries in select box

The following function, will dynamically add a new option value into a selectbox. Great feature, but it does not account and check for duplicate entries before adding new options into the select box. How can the code be modified such that it will alert the user that a duplicate entry has been found and to abort adding the same option value:
function addref() {
var value = document.getElementById('refdocs').value
if (value != "") {
var select = document.getElementById('refdocs_list');
var option = document.createElement('option');
option.text = value
select.add(option,select.option)
select.selectedIndex = select.options.length - 1;
}//end of if
}//end of function
DEMO: http://jsfiddle.net/abc123/rcwgk/2/
this will work this adds to both values and options you likely want to do something differently.
<html>
<head>
<script type="text/javascript">
var values = new Array();
var options = new Array();
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(needle) {
for(var i = 0; i < this.length; i++) {
if(this[i] === needle) {
return i;
}
}
return -1;
};
}
function getOptions() {
var selectobject=document.getElementById("refdocs_list");
for (var i=0; i<selectobject.length; i++){
values.push(selectobject.options[i].value);
options.push(selectobject.options[i].text);
}
}
function addref() {
var value = document.getElementById('refdocs').value
if (value != "" && values.indexOf(value) == -1 && options.indexOf(value) == -1 ) {
values.push(value);
options.push(value);
var select = document.getElementById('refdocs_list');
var option = document.createElement('option');
option.text = value
select.add(option,select.option)
select.selectedIndex = select.options.length - 1;
}//end of if
}//end of function
</script>
</head>
<body onload="getOptions()">
<select id="refdocs_list">
<option value="1">test</option>
</select>
<input type="text" id="refdocs"/>
<input type="button" value="add" onclick="javascript:addref()" />
</body>
</html>

How to show <Select > in sorted order

How can I sort the <option> elements of a <select> tag using JavaScript?
Here is the HTML I have:
<form action="example.asp">
<div>
<select size="3">
<option value="op2" >Option 2</option>
<option value="op1">Option 1</option>
<option value="op4">Option 4</option>
<option value="op3">Option 3</option>
</select>
</div>
</form>
If the value is different than the text, use the following function to sort both of them. This is just an updated version of above solution and will keep both the name and associated value.
<script language="JavaScript" type="text/javascript">
function sortList()
{
var lb = document.getElementById('mylist');
arrTexts = new Array();
arrValues = new Array();
arrOldTexts = new Array();
for(i=0; i<lb.length; i++)
{
arrTexts[i] = lb.options[i].text;
arrValues[i] = lb.options[i].value;
arrOldTexts[i] = lb.options[i].text;
}
arrTexts.sort();
for(i=0; i<lb.length; i++)
{
lb.options[i].text = arrTexts[i];
for(j=0; j<lb.length; j++)
{
if (arrTexts[i] == arrOldTexts[j])
{
lb.options[i].value = arrValues[j];
j = lb.length;
}
}
}
}
</script>
<script language="JavaScript" type="text/javascript">
function sortlist() {
var lb = document.getElementById('mylist');
arrTexts = new Array();
for(i=0; i<lb.length; i++) {
arrTexts[i] = lb.options[i].text;
}
arrTexts.sort();
for(i=0; i<lb.length; i++) {
lb.options[i].text = arrTexts[i];
lb.options[i].value = arrTexts[i];
}
}
</script>
<form action="#">
<select name=mylist id=mylist size=5>
<option value="Anton">Anton
<option value="Mike">Mike
<option value="Peter">Peter
<option value="Bill">Bill
<option value="Carl">Carl
</select>
<br>
sort
</form>
You should think about it on the pre html-creation level. If you are generating them from some kind of list or by dynamic page mechanism then sort them before you generate your option elements - thats the clearest way ;)
A simpler solution, building on Yasir Al-Agl's answer:
function sortList()
{
var lb = document.getElementById('mylist');
arr = new Array();
for(i = 0; i < lb.length; i++) {
arr[i] = lb.options[i];
}
arr.sort(function(a,b) {
return (a.text > b.text)? 1 : ((a.text < b.text)? -1 : 0);
}); // or use localeCompare() if you prefer
for(i = 0; i < lb.length; i++) {
lb.options[i] = arr[i];
}
}
In short, you need only one Array, the elements of which are simply references to the original "options" Objects. The sort() function also has the freedom to choose which option property to sort on (ie, the text property, the value property, etc).
Don't forget, however, that the "selectedIndex" property of the "select" control may no longer be correct after the sort.
This function works as in the last answer, but also keeps the selection of item
// Sorts all entries of a select item (= dropdown) by their visible name, keeping the internal values and the selection
function sortSelectEntries(selItem) {
let formerSel = selItem.value;
let count = selItem.length;
let options = new Array();
for (var i = 0; i < count; i++)
options[i] = selItem.options[i];
options.sort((e1, e2) => e1.text > e2.text ? 1 : (e1.text < e2.text ? -1 : 0));
for (i = 0; i < count; i++)
selItem.options[i] = options[i];
selItem.value = formerSel; // restore selection
}

Categories

Resources