Syncing 2 multiple choice lists in javascript - javascript

I'm trying to figure out how to sync two multiple choice lists in javascript. Here's the code which works:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
</head>
<script language="JavaScript">
<!--
function SelectEmail(name)
{
var listboxEmails = document.getElementById('emails');
for (var i=0;i<listboxEmails.length;i++)
{
listboxname = listboxEmails[i].innerHTML
if (listboxname == name)
{
listboxEmails.selectedIndex = i;
break;
}
}//end for
}//end function SelectEmail
// -->
</script>
<body>
<select id='names' name ='names' style = "width: 100" multiple="multiple" onClick="SelectEmail(this.value);">
<option value ="joe">joe</option>
<option value ="albert">albert</option>
<option value ="gary">gary</option>
<option value ="ace">ace</option>
</select>
<select id="emails" name ="emails" style = "width: 100;" multiple="multiple">
<option value ="joe#asds.com">joe</option>
<option value ="albert#asds.com">albert</option>
<option value ="gary#asds.com">gary</option>
<option value ="ace#asds.com">ace</option>
</SELECT>
</body>
</html>
However I want to make it show multiple choices. So for example if I choose albert and gary on the left list, I want the right list to select albert and gary as well. Please help me with this. Cheers.

Your function SelectEmail() can't work because it sets selectedIndex of your select, which selects one option and deselects the rest. Also, you are using the text content of the options in #emails in order to map them with the values of #names. That's not a good practice, because text nodes are supposed to show text and not to enable the identification of elements in your script.
Instead, you can access the selected attribute separately for each option you want to select. By adding an additional attribute to your #emails element's options, it could look like:
<select id="emails" name="emails" style="width: 100;" multiple="multiple">
<option value="joe#asds.com" data-name="joe">joe</option>
<option value="albert#asds.com" data-name="albert">albert</option>
<option value="gary#asds.com" data-name="gary">gary</option>
<option value="ace#asds.com" data-name="ace">ace</option>
</select>
You can now use the data-name attribute to map the options, for example in the following way:
function selectEmail() {
// deselect all
$('#emails option').removeAttr('selected');
var names = $('#names').val();
if (names == null) {
// none selected
return;
}
$.each(names, function (i, name) {
var selector = 'option[data-name="' + name + '"]';
$('#emails ' + selector).attr('selected', true);
});
}
Here's a working fiddle (you will notice that I also used the onchange event instead of onclick:
http://jsfiddle.net/H9hNH/2/

Related

D3 select multiple tag- extract values

I have a multi select tag. I would like to extract the selected values into an array, however I seem to only be able to extract the first value.
Please find a simplified version of what I'm trying to achieve below.
I've tried a couple of different options using:
this.value
node().value
but this only seems to extract the first selected value.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
<!-- Build the select boxes -->
<p>Single select tag</p>
<select class="form-control" id = "select_single" >
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
</select>
<p id = "select_single_p"> </p>
<br>
<br>
<p>Multiple select tag</p>
<select multiple class="form-control" id = "select_multiple" >
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
</select>
</body>
<script>
// This works for a single select
d3.select("#select_single")
.on("change",function(d){
console.log("this is the select single value " + this.value)
})
// But for multiple selects I can only extract the first value
d3.select("#select_multiple")
.on("change",function(d){this.value.len;
console.log("this is the select multiple value " + this.value )
console.log(d3.select('#select_multiple').node().value)
})
</script>
</html>
You could take a few approaches, for starters you could use straight javascript within the change function:
d3.select("#select_multiple")
.on("change",function(d){
var values = Array.from(this.options) // create an array from the htmlCollection
.filter(function(option) { return option.selected }) // filter for selected values
.map(function(option) { return option.value; }); // return a new array with the selected values
console.log(values);
})
Another option is to use d3 to select the selected options, and for each of those, grab the value:
d3.select("#select_multiple")
.on("change",function(d){
var values = [];
selected = d3.select(this) // select the select
.selectAll("option:checked") // select the selected values
.each(function() { values.push(this.value) }); // for each of those, get its value
console.log(values)
})

Why select option change event can't have this and event.target to get selected value?

In select option change event,why can't we get this or event.target to get selected value instead of writing clumsy code like $( "select option:selected" ) to get selected value ?
Pure JavaScript
If you want a pure JavaScript approach, then use the event.target. To quote the official MDN documentation...
The target property of the Event interface is a reference to the object onto which the event was dispatched. (Source: MDN Web Docs: Event.target.)
Since that gives us the element selected, all we then need is the value attribute, and getting the text display would be nothing more than event.target[event.target.selectedIndex].text...
function getSelectedValue(event) {
console.log("Value: " + event.target.value + "; Display: " + event.target[event.target.selectedIndex].text + ".");
}
<select onchange="getSelectedValue(event)">
<option selected disabled>--Pick an Option--</option>
<option value="blue1">Blueberry</option>
<option value="rasp2">Raspberry</option>
<option value="straw3">Strawberry</option>
</select>
Using the above approach, it would be trivial to update it to add in other attributes of the selection option value, all in pure JavaScript.
jQuery
If you want a jQuery approach, then try using the :selected query term...
$("#selector").on('change', function(){
console.log("Value: " + $(this).val() + "; Display: " + $(this).find('option:selected').text() + ".");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="selector">
<option selected disabled>--Pick an Option--</option>
<option value="blue1">Blueberry</option>
<option value="rasp2">Raspberry</option>
<option value="straw3">Strawberry</option>
</select>
$("select").on('change', function(){
console.log($(this).val());
console.log($(this).find('option:selected').attr('data-attribute'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select>
<option data-attribute="a">1</option>
<option data-attribute="b">2</option>
<option data-attribute="c">3</option>
<option data-attribute="d">4</option>
</select>
You can't get the selected value, but of course you can get the element and the event.target.
<select onchange="mySelectOnchange(this, event)"></select>
function mySelectOnchange(elm, e) {
// **
}
It exists... take a look at this code for example
var selectElem = document.getElementById('select');
selectElem.addEventListener('change', onSelect_change);
function onSelect_change(domEvent){
// get the selected value :
var selectedValue = domEvent.target[domEvent.target.selectedIndex].value;
// you can also do it using domEvent.target.value but the other solution allows you to get every option's property you want
console.log("Selected: " + selectedValue);
}
<select id="select" name="select">
<option value="value1">Value 1</option>
<option value="value2" selected>Value 2</option>
<option value="value3">Value 3</option>
</select>
Hope it helps ;)
PS: have a look on http://www.w3schools.com/jsref/prop_select_selectedindex.asp if you want more examples
The only property that's automatically transferred from the selected option to the <select> element itself is the value, because that's the main purpose of selecting an option from a drop-down menu. Other attributes like data-* are not automatically copied, because it's possible for the <select> to have its own attributes, e.g.
<select id="x" data-name="select">
<option value="1" data-name="option1">1</option>
<option value="2" data-name="option2">2</option>
</select>
It wouldn't make sense for $("#x").data("name") to return the name of the selected option instead of the name of the <select>.
<select onchange="getSelectedValue(this)"></select>
...
function getSelectedValue(select) {
console.log(select.value)
}

Database value cannot get it to the Dropdownlist jQuery

In my database there's a column, name is Sequence & it consist of numbers(int). In my application's edit function I need to show that selected number in my jQuery dropdown list.
In my AJAX call I sent ProductId and get the specific row.
Html Control
<select class="form-control" id="drpsequence"></select>
My jQuery dropdown
$("#drpsequence option:selected").append($("<option></option>").val(msg._prodlng[0].Sequence).text(msg._prodlng[0].Sequence));
In the above code msg._prodlng[0].Sequence comes as selected number
I'm not sure what you are trying to do but it looks like you are adding an <option> tag into another <option> tag which is most likely not what you want.
If the returned value already exists as a selected option:
$("#drpsequence").val(msg._prodlng[0].Sequence).prop('selected', true);
Or, if you need to add an option:
var opt = $("<option>")
.val(msg._prodlng[0].Sequence)
.text(msg._prodlng[0].Sequence);
$("#drpsequence").append(opt);
Snippet example:
// foo --> select
$('#foo').val('baz').prop('selected', true);
$('#bim').click(function(){
$('#foo').append('<option id="boop" value="boop">boop</option>'); //<-- or loaded value
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="foo">
<option>-- select --</option>
<option id="bar" value="bar">bar</option>
<option id="baz" value="baz">baz</option>
</select>
<button id="bim">Add an option</button>
You need to do one of following.
Either find that option and make that selected = true like this.
$("#sel option").each(function(i) {
if ($(this).val() == "Orange") $(this).attr("selected", "true");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="sel">
<option>Apple</option>
<option>Orange</option>
<option>Banana</option>
</select>
Or if that option is not found then add and make that selected = true.
Like the one, which you had in your question.

How to pass an array from HTML to Javascript?

I have a form which has multiple <select> drop-down boxes. I wish to pass the value in these drop-down boxes as an array to a JavaScript function.
Currently my code is like:
<select name="findByMaterial" onChange="filterFilms('Material',this.value)">
{% for film in all_films %}
<option value="{{film.f_material}}">{{film.f_material}}</option>
{% endfor %}
</select>
Where all_films is a variable from Django framework (Most probably you need not concern yourself with it).
What I want to do is that even if I have multiple selects with different names such as findByMaterial and findByColor, and I change the findByColor, then it should call the filterFilms(String,Value) JS function.
Any pointers in the right direction would be appreciated a lot.
PS: This question is probably similar to how to pass array values to JavaScript function from html onchange action?, but it is definitely not what I am looking for.
CLarification:
I wish to create a filter. Thus I would want to be able to access the attribute of color as well as material.
Online Demo : http://jsfiddle.net/thefourtheye/jRym8/
<html lang = "en">
<head>
<title> Document </title>
<script>
function filterFilms(selectBox) {
var displayArea = document.getElementById("displayArea");
displayArea.innerHTML = selectBox.id + "," + selectBox.value + "," + selectBox.selectedIndex + "," +
selectBox.options[selectBox.selectedIndex].text;
}
</script>
</head>
<body>
<select onchange="filterFilms(this);" id="films">
<option value="film1">Film Text 1</option>
<option value="film2">Film Text 2</option>
<option value="film3">Film Text 3</option>
</select>
<select onchange="filterFilms(this);" id="colors">
<option value="color1">Color 1</option>
<option value="color2">Color 2</option>
<option value="color3">Color 3</option>
</select>
<div id="displayArea"/>
</body>
</html>
You can use the same function to do this. Pass the current element as the parameter. And
You can get the id of the select box clicked with selectBox.id
You can get the selected option's value with selectBox.value
You can get the selected option's index with selectBox.selectedIndex
You can get the selected option's text with selectBox.options[selectBox.selectedIndex].text

Jquery selectmenu plugin with text input option

I need jquery plugin which would transform my simple
<select>
<option>text</option>
</select>
In to fully customizable list something like a <lu> list or list of <div>, i have found quite a lot of this kind of plugins, but none of them have option to type something in and set it as an option.
Lets say i have kind of list:
<select>
<option value="text">text</option>
<option value="other">other</option>
</select>
Now i want other option transform into <input type="text" />, and i'm quite sure there has to be plugin which does just that.
I have made an example how should it look, on the left is my current plugin and on the right is what i need, i know i could edit my current plugin but it's just way to big for me and it would take to much time.
There is no jQuery plugin which does exactly that. However, there is a jQuery UI selectmenu plugin, which converts a select element to a html representation such that you can style the select menu. This plugin also offers a callback for formatting text, such that in our case, we could format our 'other' option into an input box.
Suppose we have the following select:
<select name="otherselect" id="otherselect">
<option value="united-states">United States</option>
<option value="latvia" selected="selected">Latvia</option>
<option value="france">France</option>
<option>Other</option>
</select>
We can create a selectmenu with this plugin using:
$(function(){
selectMenu = $('select#otherselect').selectmenu({
style:'popup',
width: 300,
format: otherFormatting
});
});
In here the function otherFormatting is a function which will format our Other option. This is our function:
var otherFormatting = function(text){
// if text contains 'Other' format into Other input box...
if ( text == "Other" ) {
var button = $('<input type="submit" onclick="selectOther(this)" value="select"/>');
var input = $('<input class="other" type="text" value="Other..."/>');
return $('<span/>')
.append(input)
.append(button)[0].outerHTML;
}
return text;
}
The selectOther function that is called when the button is clicked, is a function we will extend the plugin with. This function, activated when the button is clicked, will set the values of our select, such that we can easily submit it using a form. But also, set the value which is displayed in the new selectmenu (instead of showing an input box in the select box).
We need to extend this plugin, which is a jQuery UI widget basically. However, since the plugin binds some events which make it impossible for us to get the input field and button working, we need to unbind some of these. We do this when we open the select menu. For this we need to override the open function of the widget, call our function that unbinds some events and then open the menu using the original open function.
Putting this all together:
<!DOCTYPE html>
<html>
<head>
<title>Demo Page for jQuery UI selectmenu</title>
<link type="text/css" href="../../themes/base/jquery.ui.all.css" rel="stylesheet" />
<link type="text/css" href="../../themes/base/jquery.ui.selectmenu.css" rel="stylesheet" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="../../ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="../../ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="../../ui/jquery.ui.position.js"></script>
<script type="text/javascript" src="../../ui/jquery.ui.selectmenu.js"></script>
<style type="text/css">
body {font-size: 62.5%; font-family: "Verdana",sans-serif; }
fieldset { border: 0; }
label, select, .ui-select-menu { float: left; margin-right: 10px; }
select { width: 200px; }
</style>
<script type="text/javascript">
// We need to able to call the original open method, save intoIf you need to call original method
var fn_open = $.ui.selectmenu.prototype.open;
$.widget("ui.selectmenu", $.extend({}, $.ui.selectmenu.prototype, {
open : function() {
// Every the selectmenu is opened, unbind some events...
this._unbindEvents();
fn_open.apply(this, arguments);
},
_unbindEvents : function() {
var el = $(this.list).find('li:has(input.other)').eq(0);
// unbind events, we need a different event here...
el.unbind('mouseup');
el.unbind('mousedown');
el.bind('mousedown', function() {
// We need to call focus here explicitly
$(this).find('input.other').eq(0).focus();
// Empty field on click...
if ( $(this).find('input.other').eq(0).val() == 'Other...' )
$(this).find('input.other').eq(0).val("");
});
// Unbind keydown, because otherwise we cannot type in our textfield....
this.list.unbind('keydown');
// We only need to return false on the mousedown event.
this.list.unbind('mousedown.selectmenu mouseup.selectmenu');
this.list.bind('mousedown', function() {
return false;
});
},
selectOther : function(el) {
var button = $(el);
// li item contains the index
var itemIndex = button.parent().parent().parent().data('index');
var changed = itemIndex != this._selectedIndex();
// Get the value of the input field
var newVal = button.prev().val();
this.index(itemIndex);
// Update the display value in the styled select menu.
this.newelement.find('.' + this.widgetBaseClass + '-status').html(newVal);
// Update the value and html of the option in the original select.
$(this.element[0].options[itemIndex]).val(newVal).html(newVal);
// Call the select, change and close methods
var e = jQuery.Event("mouseup");
this.select(e);
if ( changed )
this.change(e);
this.close(e);
}
}));
var selectMenu;
$(function(){
selectMenu = $('select#otherselect').selectmenu({
style:'popup',
width: 300,
format: otherFormatting
});
});
function selectOther(el) {
// Call our self defined selectOther function.
selectMenu.selectmenu('selectOther', el);
}
//a custom format option callback
var otherFormatting = function(text){
// if text contains 'Other' format into Other input box...
if ( text == "Other" ) {
var button = $('<input type="submit" onclick="selectOther(this)" value="select"/>');
var input = $('<input class="other" type="text" value="Other..."/>');
return $('<span/>')
.append(input)
.append(button)[0].outerHTML;
}
return text;
}
</script>
</head>
<body>
<h2>Select with Other option input field</h2>
<fieldset>
<label for="otherselect">Select a value:</label>
<select name="otherselect" id="otherselect">
<option value="united-states">United States</option>
<option value="latvia" selected="selected">Latvia</option>
<option value="france">France</option>
<option>Other</option>
</select>
</fieldset>
<button onclick="console.log($('#otherselect').val());">Test</button>
</body>
</html>
To try this, download the plugin here and make sure the urls to the js/css files are correct. (I have put this html file into the demos/selectmenu folder and it works...). Ofcourse you can replace the button with an image.
Try this, this little script will create a text input after a select box if the select box value is other. The new text input as the same name of the select so that its value overwrite the one set by the select (as it is other)
If the value is something else than other we just check for the text input presence and remove it (so it doesn't overwrite the select value)
http://jsfiddle.net/cW725/1/
HTML
<form>
<p>
<select>
<option value="text">text</option>
<option value="text">text</option>
<option value="text">text</option>
<option value="other">other</option>
</select>
</p>
<p>
<select>
<option value="text">text</option>
<option value="text">text</option>
<option value="text">text</option>
<option value="other">other</option>
</select>
</p>
</form>
​
jQuery
$(function() {
// bind all select on change
$('select').on('change', function() {
// if value is other
if ($(this).val() == 'other') {
// add a text input we match the name so that this input overwrite the select one as after in the form
$(this).after('<input type="text" name="' + $(this).attr('name') + '" class="otherInput" />');
} else {
if ($(this).next().is('input.otherInput')) {
$(this).next().remove();
};
};
});
});​
I was looking for a jquery 'select or edit' solution, and found this can be done with help of select2 plugin.
Turned out to be pretty simple solution that does exactly what I wanted.
HTML:
<select name="otherselect" id="otherselect">
<option value="united-states">United States</option>
<option value="latvia" selected="selected">Latvia</option>
<option value="france">France</option>
</select>
JS:
$('#otherselect').select2({tags: true});
Example:
https://jsfiddle.net/h0qp37jk/
You might check out chosen.js - it might fit your needs. Might be easier that making something from scratch. Good luck.

Categories

Resources