I have a dropdown element with values like these:
<option value="Bulletins">Bulletins, bulletin_type, comments, engineering, keywords, language_type, model_name, offLine_type, option_code, product_code, product_type, security_group</option>
<option value="Communication">Communication, comments, communication_type, engineering, keywords, language_type, model_name, offLine_type, option_code, product_code, product_type, security_group</option>
I can't change the format but I can add javascript to the page. I want to be able to just display the string up to the first comma but have the rest of the string available for other things I need to do.
Is this possible?
Scott
You can move the text into a data attribute and set the text to the portion you want.
document.querySelectorAll("#sel option").forEach((opt) => {
opt.dataset.orgText = opt.textContent;
opt.textContent = opt.textContent.split(",")[0];
});
document.querySelector("#sel").addEventListener("change", (evt) => {
const selectedOption = evt.target.querySelector("option:checked");
console.log({
value: selectedOption.value,
data: selectedOption.dataset.orgText,
text: selectedOption.textContent,
});
});
<select id="sel">
<option></option>
<option value="Bulletins">Bulletins, bulletin_type, comments, engineering, keywords, language_type, model_name, offLine_type, option_code, product_code, product_type, security_group</option>
<option value="Communication">Communication, comments, communication_type, engineering, keywords, language_type, model_name, offLine_type, option_code, product_code, product_type, security_group</option>
</select>
Related
I have a select field with different values :
africa
europe
america
asia
oceania
When selecting a value, I want to add a css class to a specific div, the name of the css class being the value selected. Easy enough :
$(document).on("change", "[data-name='continent'] select", function () {
var continent = $('[data-name="continent"] select').val();
$("#mydiv").addClass(continent);
});
This works fine, but there is a problem : if I change the select field value, the previous classes will not be removed. I can't do :
$("#mydiv").removeClass().addClass(continent);
Because #mydiv already has other important classes.
I could do :
$("#mydiv").removeClass('africa').removeClass('europe').removeClass('america').removeClass('asia').removeClass('oceania').addClass(continent);
But in reality I have more than just 5 options and they might change in the future; I'd rather keep things flexible.
And more than anything, i want to learn javascript.
Is there any way to remove all the classes that are values of the select field ?
Try this:
$('#continent').on('change', (e) => {
let $myDiv = $('#myDiv'),
$continent = $(e.target),
possibleValues = $continent.find('option').toArray().map(item => item.value).join(' ');
$myDiv.removeClass(possibleValues).addClass($continent.val());
});
Explanation:
Gather all possible values from the select:
$continent.find('option').toArray().map(item => item.value)
Join them in a space-separated list into a string:
.join(' ');
Remove all classes from that list from the target element
$myDiv.removeClass(possibleValues)
Add the selected class after it.
Demo:
$('#continent').on('change', (e) => {
let $myDiv = $('#myDiv'),
$continent = $(e.target),
possibleValues = $continent.find('option').toArray().map(item => item.value).join(' ');
$myDiv.removeClass(possibleValues).addClass($continent.val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="continent">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
<option value="d">D</option>
<option value="e">E</option>
</select>
<div id="myDiv" class="other-class keep-me">my div</div>
To get a list of the classes you want to remove, you can use something like this:
[...testEl.querySelectorAll('option')].map(x => x.value).join(' ');
This is vanilla JavaScript...if done in jQuery it would look like this:
$('#my-select > option').map((i,el)=> el.value).toArray().join(' ');
That will pull out a list of the options and give you a space-delimited string. You could then use this list to do your .removeClass().
However I wonder if class is the best option for this. In the following snippet there is an example of using a data attribute instead of class, and how that data attribute could be used in a CSS selector (this would also work in jQuery or querySelector). Maybe an option to consider...
const testEl = document.querySelector('#test');
const allOptions = $('#test > option').map((i,el)=> el.value).toArray().join(' ');
console.log(allOptions);
const testChange = e => {
const el = e.target;
el.dataset.chosen = el.value;
};
testEl.addEventListener('change', testChange);
testChange({ target: testEl });
#test[data-chosen="africa"] {
color: red;
}
#test[data-chosen="america"] {
color: blue;
}
#test {
color: orange;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name='test' id='test' value='europe'>
<option value='africa'>africa</option>
<option value='europe'>europe</option>
<option value='america'>america</option>
<option value='asia'>asia</option>
<option value='oceania'>oceania</option>
</select>
You will have to create a string containing all the classes you want to add/remove seperated by space:
$("#mydiv").removeClass("africa europe america asia oceania");
I'm creating a chrome extension in which I have information in JSON
options.js:
var data = {
"websites" : [
{
id: 1,
'baseURL': 'http://www.monoprice.com/search/index?keyword=',
'spaceValue': '+',
'img': 'monoprice.png',
'name': 'Monoprice'
},
{
id: 2,
'baseURL': 'https://www.youtube.com/results?search_query=',
'spaceValue': '+',
'img': 'youtube.png',
'name': 'Youtube'
},
{
id: 3,
'baseURL': 'http://www.amazon.com/s/field-keywords=',
'spaceValue': '%20',
'img': 'amazon.png',
'name': 'Amazon'
},
{
id: 4,
'baseURL': 'http://stackoverflow.com/search?q=',
'spaceValue': '+',
'img': 'stack.png',
'name': 'Stack'
}
]
};
function save_options() {
var itemOne = document.getElementById('1').value;
var itemTwo = document.getElementById('2').value;
var itemThree = document.getElementById('3').value;
var itemFour = document.getElementById('4').value;
chrome.storage.sync.set({
'One': itemOne,
'Two': itemTwo,
'Three': itemThree,
'Four': itemFour,
}, function() {
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function() {
status.textContent = '';
}, 750);
});
}
// Restores select box and checkbox state using the preferences
// stored in chrome.storage.
function restore_options() {
// Use default value color = 'red' and likesColor = true.
chrome.storage.sync.get({
"One": "none",
"Two": "none",
"Three": "none",
"Four": "none",
}, function(items) {
document.getElementById('1').value = items.One;
document.getElementById('2').value = items.Two;
document.getElementById('3').value = items.Three;
document.getElementById('4').value = items.Four;
});
}
document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click', save_options);
With this information, I want the user to choose the order in which this info is applied to the actual chrome extension.
Image of extension:
I'm using drop down menus in the options.html page:
options.html:
<!DOCTYPE html>
<html>
<head><title>My Test Extension Options</title></head>
<body>
<select id="1">
<option value="">None</option>
<option value="amazon">Amazon</option>
<option value="youtube">Youtube</option>
<option value="monoprice">Monoprice</option>
<option value="stack">Stack</option>
</select>
<select id="2">
<option value="">None</option>
<option value="amazon">Amazon</option>
<option value="youtube">Youtube</option>
<option value="monoprice">Monoprice</option>
<option value="stack">Stack</option>
</select>
<select id="3">
<option value="">None</option>
<option value="amazon">Amazon</option>
<option value="youtube">Youtube</option>
<option value="monoprice">Monoprice</option>
<option value="stack">Stack</option>
</select>
<select id="4">
<option value="">None</option>
<option value="amazon">Amazon</option>
<option value="youtube">Youtube</option>
<option value="monoprice">Monoprice</option>
<option value="stack">Stack</option>
</select>
<div id="status"></div>
<button id="save">Save</button>
<script src="options.js"></script>
</body>
</html>
But I can't figure out how to programatically link between the chosen drop down menus and the JSON array, and then to store and recall that data using chrome.storage.sync.set({});
Thanks!
I know this might be confusing, I'd be happy to provide any clarification required.
So, you already have working, proper code for saving/loading values to storage. It's a question of using that data efficiently and improving the user (and programmer!) experience.
Let's see problems you have here that make it awkward to access data:
You store identifiers from the value attribute, but those do not (yet) mean anything for your data structure. On the other hand, you have id field in your data that you don't anyhow use.
Conclusion: use the same identifier for both. It establishes correlation.
Your unique identifiers in the data are numerical, and yet they are coded by hand. It's probably easier to maintain your data if they were meaningful, and that would also allow you to reorder your data without the IDs losing sense of order.
Conclusion: use unique but meaningful identifiers, like the ones you use for value already.
You have your data organised in an array, yet the intended use for it is to look it up by identifier. That's inefficient: you'll have to loop through the array until you find the identifier. An object solves this problem: it directly maps identifiers to data.
Arrays are easy to add to, but you still want an unique identifier (that persists through adding/deleting data), so that negates the advantage.
Conclusion: Don't use arrays that hold id/value pairs, use objects mapping ids to values.
Putting the three together:
websites: {
amazon: {
baseURL: 'http://www.amazon.com/s/field-keywords=',
spaceValue: '%20',
img: 'amazon.png',
name: 'Amazon'
},
// ...
]
(note that inside JS code, there's no need to quote object identifiers, and certainly one shouldn't mix those, but if you store it in a separate JSON file you want them quoted)
Now you can access whatever properties you need by ID that is stored in storage: data.websites[id].name, for instance.
We could be done here, but let's make the programmer's (yours!) life easier for later.
Suppose you want to add a new website. Not only you have to add it to data, which is of course required, but you also need to copy-paste a new <option> all across your page. Or, if you change the name of a website you'd need to patch it everywhere. This is something that should be avoided, and it's not hard to automate by generating <option>s on the fly.
Let's modify your HTML:
<select class="website-select" id="1"></select>
<!-- ... -->
<select class="website-select" id="4"></select>
And now let's populate it:
// Assumes Chrome 45+ for newer JS things
var selects = Array.from(document.getElementsByClassName('website-select'));
for (var select of selects) {
var noneOption = document.createElement('option');
noneOption.value = '';
noneOption.text = 'None';
select.appendChild(noneOption);
for (id in data.websites) {
var websiteOption = document.createElement('option');
websiteOption.value = id;
websiteOption.text = data.websites[id].name;
select.appendChild(websiteOption);
}
}
In principle, the same applies to <select>s themselves. What if you want to allow a variable number of them, or just change the number later? The IDs for data ("One", "Two", ...) also require hardcoding and don't scale.
Perhaps it's better to save an array in the storage, and build the whole interface based on that. It's going to be easier to access saved preferences as well.
Left as an exercise for the reader.
If you modify your data.websites, it may happen that id you have saved becomes invalid - it no longer maps to any website. That would cause code referencing data.websites[id] to fail.
While it's possible to add checks that it exists everywhere, it's probably better to validate your data once (or as often as your data.websites changes, if you add that functionality) and then rely on the fact it's valid.
Here's a sample validation:
function validate(callback) {
var defaults = {
"One": "",
"Two": "",
"Three": "",
"Four": "",
};
chrome.storage.sync.get(defaults, function(items) {
for (var option in items) {
if (items[option] && !data.websites[items[option]]) {
// Reset invalid data
items[option] = "";
}
}
chrome.storage.sync.set(items, callback);
});
}
You might want to improve your user's experience by not requiring them to click "Save". It involves binding your saving logic to events on change event of the <select> elements instead of click on Save.
Similar to this question here I'd like to find out how to remove duplicate options from drop down lists, however I'd like to map a list of ID's to search from and see if they have duplicate options to splice out as opposed to just one input selector.
An example of this would be as follows:
<select id="MeatList">
<option value="OBgYN7" >Ham</option>
<option value="ELmn5">Beef</option>
<option value="KrUKt6">Chicken</option>
<option value="OBgYN7" selected="selected">Ham</option>
</select>
<select id="Seats">
<option value="2" >Table For Two</option>
<option value="3">Table For Three</option>
<option value="5">Table for Five</option>
<option value="10" >Party Table</option>
</select>
<select id="Lastname">
<option value="Tao" >The Tao's</option>
<option value="Smith">The Smith's</option>
<option value="Samuels">The Samuels'</option>
<option value="Smith" >The Smith's</option>
</select>
As you can see, the inputs MeatList and Lastname have duplicate values, I want to be able to search all drop down boxes for duplicate values (or inner text) and splice them out. Would that be possible through mapping of some sort?
The code to be used would be:
[].slice.call(fruits.options)
.map(function(a){
if(this[a.innerText]){
if(!a.selected) fruits.removeChild(a);
} else {
this[a.innerText]=1;
}
},{});
And to get an idea of what I mean by mapping the drop-down lists, I would use a code like this:
var idlist= ["MeatList", "Seats", "Lastname"];
var handlelists = idlist.join("|");
[].slice.call(handlelists.options)
.map(function(a){
if(this.search([a.innerText])){
if(!a.selected) handlelists.removeChild(a);
} else {
this[a.innerText]=1;
}
},{});
Not sure what you thought was going on in the handleLists part of your script. You just need to wrap the other segment in an iterator (forEach) after finding the elements corresponding to the IDs.
var idList= ["MeatList", "Seats", "Lastname"].map(function(id){return document.getElementById(id)});
idList.forEach(function(select){
[].slice.call(select.options)
.map(function(a){
if(this[a.value]){
select.removeChild(a);
} else {
this[a.value]=1;
}
},{});
});
Of course, this is bad. You should make de-duplicating a function of it's own, eg.:
function deDuplicate(select){
[].slice.call(select.options)
.map(function(a){
if(this[a.value]){
select.removeChild(a);
} else {
this[a.value]=1;
}
},{});
}
and then:
var idList= ["MeatList", "Seats", "Lastname"].map(function(id){return document.getElementById(id)});
idList.forEach(function(select){ deDuplicate(select); });
Personally I recommend learning/using CoffeeScript as it uncrufts Javascript a great deal, the de-dupe looks like this:
deDuplicate = (select)->
[].slice.call(select.options).map (a)->
if #[a.value]
select.removeChild a
else
#[a.value] = 1
, {}
and then wrapped you can do:
deDuplicate select for select in ["MeatList", "Seats", "Lastname"].map (id)->
document.getElementById id
Which reads more plainly as english, at least to me it does. As always YMMV.
I want to be able to set the default/selected value of a select element using the JQuery Select2 plugin.
One more way - just add a selected = "selected" attribute to the select markup and call select2 on it. It must take your selected value. No need for extra JavaScript. Like this :
Markup
<select class="select2">
<option id="foo">Some Text</option>
<option id="bar" selected="selected">Other Text</option>
</select>
JavaScript
$('select').select2(); //oh yes just this!
See fiddle : http://jsfiddle.net/6hZFU/
Edit: (Thanks, Jay Haase!)
If this doesn't work, try setting the val property of select2 to null, to clear the value, like this:
$('select').select2("val", null); //a lil' bit more :)
After this, it is simple enough to set val to "Whatever You Want".
The above solutions did not work for me, but this code from Select2's own website did:
$('select').val('US'); // Select the option with a value of 'US'
$('select').trigger('change'); // Notify any JS components that the value changed
Webpage found here
Hope this helps for anyone who is struggling, like I was.
$("#id").select2("val", null); //this will not work..you can try
You should actually do this...intialise and then set the value..well this is also the way it worked for me.
$("#id").select2().select2("val", null);
$("#id").select2().select2("val", 'oneofthevaluehere');
One way to accomplish this is...
$('select').select2().select2('val', $('.select2 option:eq(1)').val());
So basically you first initalize the plugin then specify the default value using the 'val' parameter. The actual value is taken from the specified option, in this case #1. So the selected value from this example would be "bar".
<select class=".select2">
<option id="foo">Some Text</option>
<option id="bar">Other Text</option>
</select>
Hope this is useful to someone else.
For 4.x version
$('#select2Id').val(__INDEX__).trigger('change');
to select value with INDEX
$('#select2Id').val('').trigger('change');
to select nothing (show placeholder if it is)
Came from the future? Looking for the ajax source default value ?
// Set up the Select2 control
$('#mySelect2').select2({
ajax: {
url: '/api/students'
}
});
// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
type: 'GET',
url: '/api/students/s/' + studentId
}).then(function (data) {
// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true);
studentSelect.append(option).trigger('change');
// manually trigger the `select2:select` event
studentSelect.trigger({
type: 'select2:select',
params: {
data: data
}
});
});
You're welcome.
Reference:
https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2
Step 1: You need to append one blank option with a blank value in your select tag.
Step 2: Add data-placeholder attribute in select tag with a placeholder value
HTML
<select class="select2" data-placeholder='--Select--'>
<option value=''>--Select--</option>
<option value='1'>Option 1</option>
<option value='2'>Option 2</option>
<option value='3'>Option 3</option>
</select>
jQuery
$('.select2').select2({
placeholder: $(this).data('placeholder')
});
OR
$('.select2').select2({
placeholder: 'Custom placeholder text'
});
e.g.
var option = new Option(data.full_name, data.id, true, true);
studentSelect.append(option).trigger('change');
you can see it here https://select2.org/programmatic-control/add-select-clear-items
Don't know others issue, Only this code worked for me.
$('select').val('').select2();
Normally we usually use active but in select2, changes to selected="selected"
Example using Python/Flask
HTML:
<select id="role" name="role[]" multiple="multiple" class="js-example-basic-multiple form-control">
{% for x in list%}
<option selected="selected" value="{{x[0]}}">{{x[1]}}</option>
{% endfor %}
</select>
JQuery:
$(document).ready(function() {
$('.js-example-basic-multiple').select2();
});
$(".js-example-theme-multiple").select2({
theme: "classic",
placeholder: 'Select your option...'
});
It's easy. For example I want to select option with value 2 in default:
HTML:
<select class="select2" id="selectBox">
<option value="1">Some Text</option>
<option value="2">Other Text</option>
</select>
Javascript:
$("#selectBox").val('2').trigger('change')
$('select').select2("val",null);
If you are using an array data source you can do something like below -
$(".select").select2({
data: data_names
});
data_names.forEach(function(name) {
if (name.selected) {
$(".select").select2('val', name.id);
}
});
This assumes that out of your data set the one item which you want to set as default has an additional attribute called selected and we use that to set the value.
For ajax select2 multiple select dropdown i did like this;
//preset element values
//topics is an array of format [{"id":"","text":""}, .....]
$(id).val(topics);
setTimeout(function(){
ajaxTopicDropdown(id,
2,location.origin+"/api for gettings topics/",
"Pick a topic", true, 5);
},1);
// ajaxtopicDropdown is dry fucntion to get topics for diffrent element and url
I have a requirement When selected a dropdown value, it has to filter or remove the values of other dropdown which has index that should be always greater than selected index of first dropdown.
Ex: First Dropdown values:
01:00
01:30
02:00 // suppose i select 02:00 here
02:30
03:00
03:30
04:00
04:30
05:00
05:30
Second Dropdonw Values (on selected 02:00 in the above dropdown should look like below)
02:30
03:00
03:30
04:00
04:30
05:00
05:30
(Im using C# with Asp.net here.)
Any javascript to achieve above would be greatly appreciated
and using script as below as Salman Suggested
<body onload="select()">
<script language="javascript">
function select(){
var select1 = document.getElementById("ddlFrom");
var select2 = document.getElementById("ddlTo");
select1.onchange = function filterDDL() { // empty select2
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
if (select1.selectedIndex == 0)
{
return;
}
for (var i = select1.selectedIndex; i < select1.options.length; i++)
{
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
select2.appendChild(o);
}
}
}</script>
but not working...please help on this
Thanks in advance
Edit (using jQuery to get desired results):
<select id="one">
<option value="01:00">01:00</option>
<option value="01:30">01:30</option>
<option value="02:00">02:00</option>
<option value="02:30">02:30</option>
<option value="03:00">03:00</option>
<option value="03:30">03:30</option>
</select>
<select id="two"></select>
<script type="text/javascript">
$(function () {
$("#one").change(function (e) {
$("#two").empty();
var options =
$("#one option").filter(function(e){
return $(this).attr("value") > $("#one option:selected").val();
}).clone();
$("#two").append(options);
});
});
</script>
Vanilla JavaScript solution and demo.
HTML
<select name="select1" id="select1">
<option value="">-- select an option --</option>
<option value="01:00">01:00</option>
<option value="01:30">01:30</option>
<option value="02:00">02:00</option>
<option value="02:30">02:30</option>
<option value="03:00">03:00</option>
<option value="03:30">03:30</option>
<option value="04:00">04:00</option>
<option value="04:30">04:30</option>
<option value="05:00">05:00</option>
<option value="05:30">05:30</option>
</select>
<select name="select2" id="select2">
</select>
JavaScript
// this function must be wrapped inside onload event
var select1 = document.getElementById("select1");
var select2 = document.getElementById("select2");
select1.onchange = function() {
// empty select2
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
if (select1.selectedIndex == 0) {
return;
}
for (var i = select1.selectedIndex; i < select1.options.length; i++) {
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
select2.appendChild(o);
}
}
There are multiple ways to achieve this, each might be good for a different useage.
Filter by value
#Craig has suggested it already. Give the dropdown options values. When something's selected in the first one, values lower or equal to its value are removed from the second dropdown: http://jsfiddle.net/q8mLH/
Using an array of available pairs
Create an array of the pairs you're interested in, then when select 1 is changed, update select2 available options based on what is defined in your array of allowed pairs: http://jsfiddle.net/AU6hq/
AJAX + database pairs
I'm not going to specify an example here, sorry, but the general idea is this: you need to have some tables in your database, let's say "countries" and "cities", where each country has an ID, and each city has its own unique ID plus the ID of the country where it lies. You'll want to display only the cities in the selected country, probably.
You bind the change() event to the counties select and load the contents of the second select via an ajax call, querying the database for the cities that lie in the selected country.
There might be more, but I don't quite feel like thinking too much today ;). Anyway, I hope this helps.
[EDIT]
My examples use jQuery, I hope it's not a problem.