I have a javascript that seems to only run once. I am using this to select the colour of a letter inside a div. When I select the colour initially it works but then will not select a different colour.
This is the select:
<div style = "position: absolute; left: 360px; top: 590px;" >
<select id="selectcolor1" name="selectcolor1" style="width: 150px;">
<option value="null">Select a Motif Color...</option>
<option value="black">Black</option>
<option value="blue">Blue</option>
<option value="darkblue">Dark Blue</option>
<option value="pink">Pink</option>
<option value="green">Green</option>
<option value="orange">Orange</option>
<option value="seagreen">Sea Green</option>
<option value="red">Red</option>
<option value="darkgreen">Dark Green</option>
<option value="bergundy">Bergundy</option>
<option value="cyan">Cyan</option>
<option value="magenta">Magenta</option>
<option value="mustard">mustard</option>
<option value="purple">Purple</option>
This is the javascript:
$('#selectcolor1').change(function() {
var color = this.value || '';
$('.selectcolor1').attr('class', function(i, classes) {
var cls = classes.split(/[\s]/);
cls[2] = color;
return cls.join(' ');
});
e.preventDefault();
});
I probably should have mentioned I am using the script to change to different Div's colours apologies my fault:
<div style = "position: absolute; left: 750px; top: 313px;"
class="selected-value selectcolor1" id ="motif" ></div>
<div style = "position: absolute; left: 750px; top: 313px;"
class="selected-value1 selectcolor1" id ="motif1" ></div>
Any help would be great thank you!
Couple of problems here.
As #cport noted, you are not declaring the e variable you are referring to in e.preventDefault(). This needs to come in the change function handler.
As #dsuess noted, your code is changing the class on a tag with class="selectcolor1", which isn't in your pasted code - please make sure this is correct.
Also, this code will work with the jsfiddle provided below since it sets the target's third class and the target has two classes initially. However, if you change the target HTML to have three or more classes from the start, the Javascript code will overwrite the third class.
But having said that, this works with the current code:
$('#selectcolor1').change(function(e) {
var color = this.value || '';
$('.selectcolor1').attr('class', function(i, classes) {
var cls = classes.split(/[\s]/);
cls[2] = color; // third class becomes the color value
return cls.join(' ');
});
e.preventDefault();
});
As #cport1 stated, the anonymous function is missing the e parameter:
$('#selectcolor1').change(function(e) { ...
This will cause the JS to be fired only once and then error because there is no reference to e in that function's scope.
You are missing the e parameter in your event binding:
$('#selectcolor1').change(function()
replace with
$('#selectcolor1').change(function(e)
Related
I am using Select2 jQuery Plugin.
https://select2.github.io/ for reference
When I am using the multiple dropdown option. The result of selected items is shown as tags in a box but, I just want to show the number of items selected.
Is it possible with Select2 jQuery plugin
HTML
<select multiple style="width:100%">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
<option value="5">Name5</option>
<option value="6">Name6</option>
<option value="7">Name7</option>
</select>
JS
$('select').select2();
I want output as below
instead of tag like output.
Example working Fiddle
You can add this code after initializing select2
$('select').on('select2:close', function (evt) {
var uldiv = $(this).siblings('span.select2').find('ul')
var count = $(this).select2('data').length
if(count==0){
uldiv.html("")
}
else{
uldiv.html("<li>"+count+" items selected</li>")
}
Ref: jsfiddle
Reference to select2 events: Here
Edit: If you want to display a blank when user deselects everything,
Use this fiddle: here
Edit: Updated to remove flaw in deselection of data and changed it to main answer.
Fiddle: here
Selectors can certainly be improved, but as a blueprint, adding a counter element on change and hiding the tags like this seems to work as asked.
$('select').select2({closeOnSelect: false}).on("change", function(e) {
$('.select2-selection__rendered li:not(.select2-search--inline)').hide();
$('.counter').remove();
var counter = $(".select2-selection__choice").length;
$('.select2-selection__rendered').after('<div style="line-height: 28px; padding: 5px;" class="counter">'+counter+' selected</div>');
});
.counter{
position:absolute;
top:0px;
right:5px;
}
.select2-search--inline{
background-color:Gainsboro;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.full.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet"/>
<select multiple style="width:100%" id="mySelect">
<option value="1">Name1</option>
<option value="2">Name2</option>
<option value="3">Name3</option>
<option value="4">Name4</option>
<option value="5">Name5</option>
<option value="6">Name6</option>
<option value="7">Name7</option>
</select>
although the answer is given.
you can try this code. first initialize than on close call it.
jQuery('.multi-select-pbwp').select2();
$('.multi-select-pbwp').on('select2:close', function() {
const $select = $(this);
const numSelected = $select.select2('data').length;
$select.next('span.select2').find('ul').html(function() {
return `<li class="class="select2-selection__choice">${numSelected} selected</li>`;
})
});
I have a "state" select and a few "carrier" selects. for simplicity I'm using only two carrier selects here.
My jquery is suppose to show the carrier selects based on the the state selected.
The state select value is appended to the carrier select name so I can choose which carrier select to add a specific class to.
MY PROBLEM: My carrier selects wont show up. I had this working at one point, and I must've changed something along the way. Not sure whats happening here. Any help would be great. Thanks!
EDIT: I've added my original JS to show where I was, and how I want to change to Jquery.
HTML:
<div style="width:160px;">
<select name="state_select" id="state_select">
<option value="0" selected>Choose a state</option>
<option value="1">Connecticut</option>
<option value="2">New Hampshire</option>
<option value="3">New Jersey</option>
<option value="4">New York</option>
</select>
</div>
<div id="select-div1" class="select-div">
<select name="carrier_select" id="carrier_select1" class="carrier_select">
<option selected disabled>Select a carrier - Conn</option>
<!--PHP GENERATED OPTIONS-->
</select>
</div>
<div id="select-div" class="select-div">
<select name="carrier_select" id="carrier_select2" class="carrier_select">
<option selected disabled>Select a carrier - NH</option>
<!--PHP GENERATED OPTIONS-->
</select>
</div>
JQUERY:
$('#state_select').prop('selectedIndex', 0);
$('.carrier_select').prop('selectedIndex', 0);
function optionCheck() {
stateVal = $('div.select-div select').val();
selectDiv = $('#carrier_select')[0] + stateVal;
if ($(stateVal).attr('selected', 'selected')) {
$(selectDiv).attr('class', "conn_select", "nh_select", "nj_select", "ny_select");
$(selectDiv).addClass("dropdown-box");
} else {
$(selectDiv).attr('class', 'carrier_select');
}
}
$('#state_select').change(function(e) {
$('.carrier_select').prop('selectedIndex', 0);
optionCheck();
});
MY JAVASCRIPT (WORKS) BEFORE TRYING JQUERY:
function optionCheck() {
var i, len, optionVal, selectDiv,
selectOptions = document.getElementById("state_select");
// loop through the options in case there
// are multiple selected values
for (i = 0, len = selectOptions.options.length; i < len; i++) {
// get the selected option value
optionVal = selectOptions.options[i].value;
// find the corresponding help div
selectDiv = document.getElementById("carrier_select" + optionVal);
// move on if I didn't find one
if (!selectDiv) { continue; }
// set CSS classes to show/hide help div
if (selectOptions.options[i].selected) {
selectDiv.className = "conn_select nh_select nj_select ny_select";
$(selectDiv).addClass("dropdown-box");
} else {
//Hide carrier select on page load
selectDiv.className = "carrier_select";
}
}
}
// bind the onchange handler
document.getElementById("state_select").onchange = optionCheck;
CSS:
.select-div select {
border: none;
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: '';
}
.carrier_select {
display: none;
}
First off, your code has some redundancies and some questionable decisions in it in my humble opinion that you could work around in order to simplify and/or make it more usable. However, there is a way to achieve what you want with most of it untouched, using Javascript/jQuery code. For the full thing, check this fiddle, the script is below as well along with its explanation:
$('#state_select').prop('selectedIndex', 0);
$('.carrier_select').prop('selectedIndex', 0);
function optionCheck() {
stateVal = $('#state_select').val();
selectDiv = $('#carrier_select'+ stateVal);
$('.dropdown-box:not(#state_select_box)').removeClass('dropdown-box').addClass('carrier_select');
$(selectDiv).removeClass('carrier_select').addClass('dropdown-box');
$($selectDiv).val('0');
}
$('#state_select').change(function(e) {
optionCheck();
});
What this does is it gets the val() of #state_select, appends it to the #carrier_select so that the selector targets the right id, then changes all active selectors, except the #state_selector_box (which I made to wrap around #state_select) to ones with the .carrier_select class, thus making them invisible and then it finally makes the one that corresponds to the selected state visible using the dropdown-box class. Also the val() of the selector that just appeared is set to 0.
You are telling css to hide the element
.carrier_select {
display: none;
}
Both of your select elements have the class "carrier_select" and as a result of this css definition, they are not displayed. Remove or change this definition for them to be shown.
Edited in such a way that you can see the carrier selections. But other part of your question - appending to carrier name, showing carriers depending on the state needs more inputs.
$('#state_select').prop('selectedIndex', 0);
$('.carrier_select').prop('selectedIndex', 0);
function optionCheck() {
stateVal = $('div.select-div select').val();
selectDiv = $('#carrier_select')[0] + stateVal;
if ($(stateVal).attr('selected', 'selected')) {
$(selectDiv).attr('class', "conn_select", "nh_select", "nj_select", "ny_select");
$(selectDiv).addClass("dropdown-box");
} else {
$(selectDiv).attr('class', 'carrier_select');
}
}
$('#state_select').change(function(e) {
$('.carrier_select').prop('selectedIndex', 0);
optionCheck();
});
.select-div select {
border: none;
-webkit-appearance: none;
-moz-appearance: none;
text-indent: 1px;
text-overflow: '';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="dropdown-box" style="width:160px;">
<select name="state_select" id="state_select">
<option value="0" selected>Choose a state</option>
<option value="1">Connecticut</option>
<option value="2">New Hampshire</option>
<option value="3">New Jersey</option>
<option value="4">New York</option>
</select>
</div>
<div id="select-div1" class="select-div">
<select name="carrier_select" id="carrier_select1" class="carrier_select">
<option selected disabled>Select a carrier - Conn</option>
<!--PHP GENERATED OPTIONS-->
</select>
</div>
<div id="select-div" class="select-div">
<select name="carrier_select" id="carrier_select2" class="carrier_select">
<option selected disabled>Select a carrier - NH</option>
<!--PHP GENERATED OPTIONS-->
</select>
</div>
Without commenting on the rest of the code, try removing
.carrier_select {
display: none;
}
looked around for this for a while and can't find anything that seems to suit what I need. I want to be able to change the image of a t-shirt to one of a different colour, depending which colour is selected in the drop down menu.
Here's the DDL:
<select name="Colours" onchange = "changeImage()">
<option value="White">White</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Yellow">Yellow</option>
<option value="Purple">Purple</option>
</select>
Here's the JS function I've written (switch statement is repeated for each of the options):
<script type="text/javascript">
function changeImage(){
var x = document.getElementById("Colours").value;
switch(x){
case "White":
document.Mainimg.src = images/white.jpg;
location.reload();
break;
case "Red":
document.Mainimg.src = images/red.jpg;
location.reload();
break;
And finally, if it's needed, the code for the image:
<div id="main_img">
<img id="Mainimg" name="Mainpic" src=images/white.jpg>
</div>
This doesn't work, nothing happens when I select a new option in the list. Do I have the complete wrong idea of how to do this or is it just a simple tweak?
Thanks for any help.
Remove the location.reload() : When you reload the page you lose your changes. The fact you change the src of the image is enough to have it loaded.
Use getElementById to fetch your image and put the URL between quotes :
document.getElementById('Mainimg').src = "images/white.jpg";
The missing quotes could have been discovered simply by using the console which shows compilation errors. Use the console.
Perhaps what you want to do is this: http://jsfiddle.net/jWbUv/
HTML:
<select name="Colours" onchange = "changeImage(this)">
<option value="">please select</option>
<option value="White">White</option>
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Yellow">Yellow</option>
<option value="Purple">Purple</option>
</select>
<div id="main_img">
</div>
JS:
function changeImage(src) {
var mainImg = document.getElementById('main_img');
mainImg.style.setProperty('background-image', 'url(\''+ src.value +'.png\')');
}
CSS:
#main_img {
width: 100px;
height: 100px;
background-size: contain;
background-repeat: no-repeat;
}
I'm using this jquery plugin to make my select dropdown boxes look nicer. http://code.google.com/p/select-box/
Here's a fiddle of it working:
http://jsfiddle.net/FQKax/1/
I want to have the two dropdowns to be different widths but I've tried wrapping them in divs, tried to hack the js to give them different ids, everything I can think of but no joy.
Also I'm ashamed to admit I can't seem to change the color of the text in the actual dropdown bit. I can change the backgound colour etc but buggered if I can change the color of the text... weird
There's an option that you can specify what to use as classname for the sbHolder object, but you don't want to change that since you would need to rewrite the CSS. It'd be nice if they let you set an additional class to apply, but they don't.
I would just put a wrapper around the select element and use CSS to override the default width http://jsfiddle.net/FQKax/8/
.wrapper-one .sbHolder{
width: 500px;
}
.wrapper-two .sbHolder {
width: 200px;
}
<div class="wrapper-one">
<select id="language">
<option value="javascript">Javascript</option>
<option value="objective-c">Objective C</option>
<option value="python">Python</option>
</select>
</div>
<br/><br/>
<div class="wrapper-two">
<select id="language2">
<option value="javascript">Javascript</option>
<option value="objective-c">Objective C</option>
<option value="python">Python</option>
</select>
</div>
This requires adding some markup, #cih's answer doesn't. It just requires using jQuery to mark each instance accordingly http://jsfiddle.net/FQKax/37/
$("#language").selectbox();
$("#language2").selectbox();
$(".sbHolder").each(function(index){
$(this).addClass('instance-' + index);
});
.instance-0.sbHolder{
width: 500px;
}
.instance-1.sbHolder {
width: 200px;
}
$(".sbHolder").first().addClass("first");
That will add a class you can target on you first checkbox, there better way to iterate through multiple selectors, check out this link..
Other than that Joe answers the rest of your question.
Try this
http://jsfiddle.net/FQKax/30/
<link href="http://select-box.googlecode.com/svn/tags/0.2/jquery.selectbox.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://select-box.googlecode.com/svn/tags/0.2/jquery.selectbox-0.2.min.js"></script>
<select id="language">
<option value="javascript">Javascript</option>
<option value="objective-c">Objective C</option>
<option value="python">Python</option>
</select>
<br/><br/>
<select id="language2">
<option value="javascript">Javascript</option>
<option value="objective-c">Objective C</option>
<option value="python">Python</option>
</select>
##### JQUERY #######
$(function () {
$("#language").selectbox();
$("#language2").selectbox();
$(".sbHolder").each(function(){
var $langDom = $(this);
if($langDom.prev().attr('id') == 'language'){
$langDom.addClass("language_1");
} else if($langDom.prev().attr('id') == 'language2') {
$langDom.addClass("language_2");
}
});
});
###### CSSS TO ADD #####
.language_1{
width: 1200px;
}
.language_2{
width: 200px;
}
For the text color, change .sbOptions a:link, .sbOptions a:visited {} and/or .sbOptions a:hover, .sbOptions a:focus, .sbOptions a.sbFocus {}.
For the widths, .sbOptions is your dropdown width, and .sbHolder {} is the width of the "currently selected" item.
Consider this:
<select name="month_selection">
<optgroup label="2012">
<option value="1">January</option>
</optgroup>
<optgroup label="2011">
<option value="1">January</option>
<option value="2">February</option>
The HTML above looks like #1 when open, and #2 when closed.
How can I get the closed version to look like #3?
The purpose is to also show the selected year without repeating it in the open options (so it looks cleaner).
My original (marked correct) answer is too old to be of use, so here is a more up-to-date answer that may be a helpful starting point. It has some weirdness around the select box width that would need resolving according to your UI structure. Hope it is helpful.
document.querySelector('select').addEventListener("change", function(e) {
var value = e.target.value
var option = e.target.querySelector("option[value='" + value + "']")
var group = option.parentElement
var display = document.querySelector("#value")
var text = option.text + " " + group.label
display.innerText = text
})
#wrapper {
position: relative;
}
#value {
position: absolute;
pointer-events: none;
width: 100%;
height: 100%;
display: flex;
align-items: center;
font-size: 0.8rem;
padding-left: 0.5em;
}
select {
color: #FFFFFF;
width: 100%;
}
select option {
color: black;
}
<html>
<div id="wrapper">
<div id="value">Select Date…</div>
<select>
<optgroup label="2012">
<option value="1">January</option>
<option value="2">February</option>
</optgroup>
<optgroup label="2013">
<option value="3">January</option>
<option value="4">February</option>
</optgroup>
</select>
</div>
</html>
Old Answer (2012)
Its good to see someone making efforts to keep a good clean UI. Kudos, more people should do this. However I'd advise against approaching to problem this way. You run a risk of trying to force an element to do something it wasn't designed to do. Even if you find a workaround, it might end up putting you into cross browser testing hell, or simply stop working on a new browser version.
I'd suggest replacing this with a JQuery or similar scriptable SELECT widget replacement such as http://filamentgroup.com/lab/jquery_ui_selectmenu_an_aria_accessible_plugin_for_styling_a_html_select/. This will give you all the flexibility you need to tweak the display through JavaScript.
This is a fairly simple way of doing it... Use change/input and when it is focused, reset the text to whatever is before the year.
Appears to work well in all browsers that I have tested.. The problem is that no matter what you do, you're always going to have to change the text value of the selected element, there is no way around that. Test yourself without deploying here - http://jsfiddle.net/CTwJy/
<select name="month_selection" id="month_selection">
<optgroup label="2012">
<option value="1">January</option>
</optgroup>
<optgroup label="2011">
<option value="1">January</option>
<option value="2">February</option>
</optgroup>
</select>
<script type="text/javascript">
function attach(ele, evt, cb) { ele.addEventListener ? ele.addEventListener(evt, cb) : ele.attachEvent('on' + evt, cb); }
function evSupported(ele, evt) { return ((('on'+evt) in ele) ? true : (function(ele, evt) { ele.setAttribute('on'+evt, 'return;'); return (typeof ele['on'+evt] == 'function'); })()); };
var selectBox = document.getElementById('month_selection');
attach(selectBox, (evSupported(selectBox, 'input') ? 'input' : 'change'), function() {
this.options[this.selectedIndex].innerText += ' ' + this.options[this.selectedIndex].parentNode.label;
this.blur();
});
attach(selectBox, 'focus', function() {
for (var i = 0; i < this.options.length; i++) {
this.options[i].innerText = this.options[i].innerText.split(' ')[0];
}
});
</script>
This isn't tested, so it may not work or may have bugs (for instance, it might permanently change the option's label), but perhaps it will give you some insight.
<script type="text/JavaScript">
function changeLabel()
{
var dropDown = document.getElementById("selMonth");
dropDown.options[dropDown.selectedIndex].label += " "+ dropDown.options[dropDown.selectedIndex].parentNode.label;
}
</script>
<select name="month_selection" id="selMonth" onchange="changeLabel()">
<optgroup label="2012">
<option value="1">January</option>
</optgroup>
<optgroup label="2011">
<option value="1">January</option>
<option value="2">February</option>