Javascript / JQuery - Sorting by Multiple Classes - javascript

having a bit of trouble here, any help would be greatly appreciated...
I am trying to hide and show a bunch of list items based on several classes assigned to them.
In my JS Fiddle Example I have several items with classes relating to their description.
I have managed to hide and show these, but complex selections are not possible...
example: If I wanted to only see fabrics that are "premium", "blue" and "linen".
Something like this (that works lol) is what I am after...
$('.sel_range').click(function() {
range = document.getElementById("range").value;
if ($('.fabric_option').hasClass(range)) {
$('.' + range).fadeIn('fast', function() {
!$('.fabric_option').hasClass(range).fadeOut("fast");
});
}
});

Something like this should work
var selects = $('#range, #fabric, #colour');
selects.on('change', function() {
var el = selects.map(function(i, item) {
return item.value.indexOf('all_') === 0 ? '' : '.' + item.value;
}).get().filter(function(x) {
return x.length;
}).join('');
$('#fabric_options li').show().not(s?s:'*').hide();
});
FIDDLE
It starts with showing all the list items, then joins the values together to create a clas selector, leaving out the class if all_something is selected etc. and then hides everything that doesn't match, and if nothing is selected excludes everything.

I think it can be solved like this:
var range, fabric, colour;
var updateShown = function() {
$('li').show()
if (range) {
$('li:not(.' + range + ')').hide();
}
if (fabric) {
$('li:not(.' + fabric + ')').hide();
}
if (colour) {
$('li:not(.' + colour + ')').hide();
}
}
// Range
$('#range').change(function() {
range = $(this).val();
updateShown();
});
// Fabric
$('#fabric').change(function() {
fabric = $(this).val();
updateShown();
});
// Colour
$('#colour').change(function() {
colour = $(this).val();
updateShown();
});
With value="" of each select first option
<select id="range">
<option class="sel_range" value="">All Ranges</option>
<option class="sel_range" value="luxury">Luxury</option>
<option class="sel_range" value="premium">Premium</option>
<option class="sel_range" value="base">Base</option>
</select>
<select id="fabric">
<option class="sel_fabric" value="">All Fabrics</option>
<option class="sel_fabric" value="leather">Leather</option>
<option class="sel_fabric" value="linen">Linen</option>
<option class="sel_fabric" value="cotton">Cotton</option>
</select>
<select id="colour">
<option class="sel_colour" value="">All Colours</option>
<option class="sel_colour" value="red">Red</option>
<option class="sel_colour" value="blue">Blue</option>
<option class="sel_colour" value="green">Green</option>
</select>
jsFiddle demo

what about this?
$('#range').on('change',function () {
range = $("#range").val();
$('li').each(function(){
if(!$(this).hasClass(range)){
$(this).hide();
}else{
$(this).show();
}
});
});
// just for range, rest in fiddle
http://jsfiddle.net/J3EZX/6/

If you're using jQuery, just string them together with a . and no space, e.g.:
$(".linen.red.base").text("Help! I'm being replaced!");

Related

Display items of two drop down based on each other

I have two drop downs with exactly the same values.
I want the drop down 2 to display the values based on the selection of items of drop down 1.
So the selected index of drop down 2 will be equal to or more than the selected index of drop down 1.
document.getElementById("SELECTB").selectedIndex >= document.getElementById("SELECTA").selectedIndex
So if B is selected in Drop down 1 then selectable options in drop down 2 will be B,C and D. (A will be not selectable item)
http://jsfiddle.net/xxyhm78t/1/
Solution working with pure Javascript:
var select1 = document.getElementById("SELECTA");
var select2 = document.getElementById("SELECTB");
select1.onchange = function () {
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
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);
}
}
Fiddle
Reference: This is an adjusted solution from javascript Change the Dropdown values based on other dropdown
Update: Like asked in the comment - to disable the options instead of removing them:
var select1 = document.getElementById("SELECTA");
var select2 = document.getElementById("SELECTB");
select1.onchange = function () {
while (select2.firstChild) {
select2.removeChild(select2.firstChild);
}
for (var i = 0; i < select1.options.length; i++) {
var o = document.createElement("option");
o.value = select1.options[i].value;
o.text = select1.options[i].text;
(i <= select1.selectedIndex)
? o.disabled = true
: o.disabled = false ;
select2.appendChild(o);
}
}
Adjusted Fiddle
Update 2: Like asked in the comment if it's possible to adjust this to use class names instead of ids - yes, by using getElementsByClassName(). I've adjusted in this Fiddle both selects to have class="SELECTA" and class="SELECTB" instead of the previously used id. The according adjustment for the Javascript is only the declaration of the variables:
var select1 = document.getElementsByClassName("SELECTA")[0];
var select2 = document.getElementsByClassName("SELECTB")[0];
As you already know, an id is a unique attribute, therefore it's possible to get a single element using getElementById(). getElementsByClassName() returns a collection of HTML elements instead, even if there's only a single element having the class. So it's - in this example - necessary to address the 1st element of this collection. As counting starts by 0, the first (and only) element having the class "SELECTA" is getElementsByClassName("SELECTA")[0].
Reference: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementsByClassName#Syntax
You can do this using selectedIndex with the following piece of code:
$("#SELECTA").change(function() {
var selIndex = this.selectedIndex;
$("#SELECTB").find("option").each(function(k,v) {
$(this).attr("disabled", selIndex > k);
});
});
Depending on what it is you are after, you may need to reset #SELECTB if one of the disabled values is selected.
I think this is what you are looking for:
$("select").on("change", function (e) {
var sel = this.selectedIndex;
$("#SELECTB option").each(function (i, e) {
$(this).prop("disabled", sel > i);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="SELECTA">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
And this can be even more general:
$("select").on("change", function (e) {
var sel = this.selectedIndex;
var nextSelect = $(this).parent().find("select").not(this);
$(nextSelect).children().each(function (i, e) {
$(this).prop("disabled", sel > i);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="SELECTA">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
<select id="SELECTB">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>

Remove last selected element from the multiple select if user select more than 3 option using jquery

I need to select only 3 options from the multiple select. If user selects more than 3 options than the last selected element should be replaced by the new one clicked.
I have a example as follows:
<select multiple id='testbox'>
<option value='1'>First Option</option>
<option value='2'>Second Option</option>
<option value='3'>Third Option</option>
<option value='4'>Fourth Option</option>
<option value='5'>Fifth Option</option>
<option value='6'>Sixth Option</option>
<option value='7'>Seventh Option</option>
<option value='8'>Eighth Option</option>
<option value='9'>Ninth Option</option>
<option value='10'>Tenth Option</option>
</select>
When user selects
First option
Second option
Third option
Now he reaches max selection limit 3 .If he click on the another option like Tenth Option I need to remove Third option and get selected Tenth option
For that i tried this but no idea how I can achieve my goal
<script type="text/javascript">
google.load("jquery", "1");
$(document).ready(function() {
//alert("1111");
var last_valid_selection = null;
$('#testbox').change(function(event) {
if ($(this).val().length > 2) {
alert('You can only choose 2!');
$(this).val(last_valid_selection);
} else {
last_valid_selection = $(this).val();
latest_value = $("option:selected:last",this).val()
alert(latest_value);
}
});
});
</script>
Please suggest some idea or solution.
This works quite nicely:
var lastSelected;
$("#testbox").change(function() {
var countSelected = $(this).find("option:selected").length;
if (countSelected > 3) {
$(this).find("option[value='" + lastSelected + "']").removeAttr("selected");
}
});
$("#testbox option").click(function() {
lastSelected = this.value;
});
I had to set a global variable lastSelected as well as an options click event to capture the actual last option clicked (this.value in the change event was giving me the top selected option, not the actual last option).
Demo: http://jsfiddle.net/JAysB/1/
Well, I don't like jQuery, so I've developed the same (fiddle), but in pure, vanilla, easy-to-read JavaScript:
document.getElementById('testbox').selopt=new Array();
document.getElementById('testbox').onchange=function(){
for(i=0; i<this.childNodes.length; i++)
if(this.childNodes[i].tagName!='OPTION')
continue;
else{
if(this.childNodes[i].selected &&
this.selopt.indexOf(this.childNodes[i])<0)
this.selopt.push(this.childNodes[i]);
}
if(this.selopt.length==4)
this.selopt.splice(2,1)[0].selected=false;
}
P. S. No global variables! :P
var lastOpt;
$('#testbox option').click(function () {
lastOpt = $(this).index();
});
$('#testbox').change(function () {
if ($('option:selected', this).length > 3) {
$(' option:eq(' + lastOpt + ')', this).removeAttr('selected');
}
});
JSFIDDLE

drop options in dropdown box

I am using 24 dropdowns. I want to select a driver for a position. But when i select a driver for the first position it should be removed from the other dropdowns so i can't use a driver two times. The dropdown is:
<select name="rijderQual1">
<option value="1">S. Vettel</option>
<option value="2">M. Webber</option>
<option value="3">J. Button</option>
<option value="4">L. Hamilton</option>
<option value="5">F. Alonso</option>
<option value="6">F. Massa</option>
<option value="7">M. Schumacher</option>
<option value="8">N. Rosberg</option>
<option value="9">K. Raikkonen</option>
<option value="10">R. Grosjean</option>
<option value="11">R. 11</option>
<option value="12">R. 12</option>
<option value="14">K. Kobayashi</option>
<option value="15">S. Perez</option>
<option value="16">R. 16</option>
<option value="17">R. 17</option>
<option value="18">P. Maldonado</option>
<option value="19">R. 19</option>
<option value="20">H. Kovalainen</option>
<option value="21">J. Trulli</option>
<option value="22">P. de</option>
<option value="23">R. 23</option>
<option value="24">T. Glock</option>
<option value="25">C. Pic</option>
</select>
The names are rijderQual1 to rijderQual24. So when i select S Vettel for example in rijderQual1 it should be removed from the 23 other dropdowns.
Is there a way to do this? I think it should be done with JS or jQuery?
You can iterate thru all options everytime some selected value is changed and hide the options that are selected somewhere else:
$('select').change(function() {
var selectedValues = $('select').map(function() { return this.value; }).get();
$('option').show();
$.each($('option'), function(i, item) {
if($(this).val() != 0 && $.inArray($(this).val(), selectedValues) > -1 )
{
$(this).hide();
}
});
});​
DEMO
Try populating your dropdown box through an array, and on each item selected delete that item from that array. both JS and JQuery would work.
I still believe another approach would be wiser, for example colour-coding all dropdowns that have the same value selected. Or unselect the option from the first dropdown if you select it in another. That way you wouldn't deprive users from doing what they want, but warn them if they try to do something that's not allowed. Better for UX. Something a little more like this.
// Store text labels for options
$("option")
.each(function() {
$(this).data("label", $(this).text());
});
$('select').change(function() {
// Get selected values
var selectedValues = $('select').map(function() { return this.value; }).get();
// Reset conflicting dropdowns
currentVal = $(this).val();
$(this).siblings("select")
.each(function() {
if ($(this).val() == currentVal) $(this).val(0);
});
// Mark selected options as unavailable
$("option")
.each(function() {
if( $(this).val() != 0 && $.inArray($(this).val(), selectedValues) > -1 && !$(this).is(":selected"))
$(this).text("(" + $(this).data("label") + ")");
else
$(this).text($(this).data("label"));
});
});​
DEMO: http://jsfiddle.net/NAWNP/
Still, according to your requirements this would iterate through the options, disabling those that are in use by other dropdowns. This way you can still see your options, even though you can't make them.
$('select').change(function() {
var selectedValues = []
$("option:selected").each(function() { selectedValues.push($(this).val()) });
$("option")
.removeAttr("disabled")
.each(function() {
if( $(this).val() != 0 && $.inArray($(this).val(), selectedValues) > -1 && !$(this).is(":selected"))
{
$(this).attr("disabled", "true");
}
});
});​
DEMO: http://jsfiddle.net/ntxmh/2/
Working demo http://jsfiddle.net/zyGH7/
another http://jsfiddle.net/fLTxj/
Much concise version. This is the source: jQuery remove options except current (Very well written)
Hope it fits the cause! B-)
Code
$('document').ready(function() {
$(".hulk").change(function() {
var val = this.options[this.selectedIndex].value;
$('select').not(this).children('option').filter(function() {
return this.value === val;
}).remove();
});
});​

Change dropdown selected text without changing the option text

I have an indented dropdownlist, where I have some root options and their children, like below:
Food
Market
Restaurants
Grossery
Clothes
Home
TV
If I select Market, for example, the text in the dropdownlist still indented. Then I did a jQuery function to remove the spaces before the text. It looks like this:
$(function () {
$("select").change(function () {
var str = jQuery.trim($("select option:selected").text());
$("select option:selected").text(str);
})
});
It works. But, if I try to select other option after selected Market, for example, The list looks like this:
Food
Market
Restaurants
Grossery
Clothes
Home
TV
Market lost its indentation. I would like a way to remove the spaces but only in the selected text shown in the dropdown, but not in the option.
What should I do?
Bit late to the party here...
First of all I've amended your HTML to include a class on each option element to indicate the level to which it should be indented.
<select class="select">
<option value="1" class="level-0">Item 1</option>
<option value="2" class="level-1">Item 1.1</option>
<option value="3" class="level-2">Item 1.1.1</option>
<option value="4" class="level-1">Item 1.2</option>
</select>
I have also written the jQuery to add the required indentation on load, using a string of non-breaking spaces. While this is hardly an elegant solution, it's the only one that will work across all browsers - as you've obviously discovered, OPTION elements are a land CSS forgot. It also includes the logic for the change event to remove/add the padding to the selected items.
While it's not the prettiest code, and I'm sure there are a lot of performance improvements which could be made (hey, it's late here and this was a brain dump as I was intrigued by the question), it works.
var levelClassPrefix = "level-";
var indentationString = " ";
$(".select").each(function() {
padOptions(this);
});
function padOptions(elem) {
$("OPTION", elem).each(function() {
var level = $(this).attr("class").replace(levelClassPrefix, "");
var currentText = $(this).html();
var regex = new RegExp(indentationString , "g");
$(this).html(padText(currentText.replace(regex, ""), level))
});
}
function padText(value, level) {
var output = "";
for (var i = 1; i <= level; i++) {
output = output + indentationString;
}
return output + value;
}
$(".select").change(function() {
padOptions(this);
var selectedOption = $("option:selected", this);
var currentText = selectedOption .html();
var regex = new RegExp(indentationString , "g");
selectedOption.text(currentText.replace(regex, ""));
});
Here is a fiddle to prove the theory
Why not style the indivudual options instead?
Something along these lines:
HTML:
<select>
<option>Food</option>
<option class='sub'>Market</option>
<option class='sub'>Restaurants</option>
<option class='sub'>Grossery</option>
<option>Clothes</option>
<option>Home</option>
<option class='sub'>TV</option>
</select>
CSS:
option.sub { text-indent: 2em; }
Why trim the string? I would add a css class similar to this
select .level0 {}
select.level1 {
text-indent: -1.5em; /* you have to calculate your indentation value */
}
select.level2 {
text-indent: -3em; /* you have to calculate your indentation value */
}
Forge html accordingly
<select>
<option class='level0'>Food</option>
<option class='level1'>Market</option>
<option class='level1'>Restaurants</option>
<option class='level1'>Grossery</option>
<option class='level0'>Clothes</option>
<option class='level0'>Home</option>
<option class='level1'>TV</option>
</select>
and apply the class accordingly. Maybe, I don't know jquery, you have to
$(function () {
$("select").change(function () {
var theclass = $("select option:selected").class();
$("select option:selected").set(class, theClass); // <-- is this jquery??
})
});

How to get the value of a multiple option dropdown?

Say I have this dropdown:
<select name="color" multiple="multiple">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
So basically more than 1 color can be selected. What I'd like is that if a user selects red, and then clicks green, i'd like a function to be called each time which pops up a message box saying the color which was most recently clicked.
I've tried this:
<option value="red" onclick="alert('red');">Red</option>
<option value="green" onclick="alert('green');">Green</option>
<option value="blue" onclick="alert('blue');">Blue</option>
This works in firefox and chrome, but not in IE.
Any ideas?
$("select[name='color']").change(function() {
// multipleValues will be an array
var multipleValues = $(this).val() || [];
// Alert the list of values
alert(multipleValues[multipleValues.length - 1]);
});
Here's another examples: http://api.jquery.com/val/
The following code should do what I think you're after. Each time an item is selected, it compares the current list of selections against the previous list, and works out which items have changed:
<html>
<head>
<script type="text/javascript">
function getselected(selectobject) {
var results = {};
for (var i=0; i<selectobject.options.length; i++) {
var option = selectobject.options[i];
var value = option.value;
results[value] = option.selected;
}
return results;
}
var currentselect = {};
function change () {
var selectobject = document.getElementById("colorchooser");
var newselect = getselected(selectobject);
for (var k in newselect) {
if (currentselect[k] != newselect[k]) {
if (newselect[k]) {
alert("Option " + k + " selected");
} else {
alert("Option " + k + " deselected");
}
}
}
currentselect = newselect;
}
</script>
</head>
<body>
<select id="colorchooser"
name="color"
multiple="multiple"
onchange='javascript:change();'
>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</select>
</body>
</html>
It should work just as well in Internet Explorer as Firefox et al.
Since you using jQuery,I suggest you to take a look at this superb plugins. This plugins will transform a multiple select dropdown into a checkbox list, so user can select multiple values with easy.
To get the values, I suggest you use fieldValue methods from jQuery form plugins. It's a robust way to get value from any type of form element. Beside, you can use this plugins to submit your form via AJAX easily.
This will alert only the last (most recent) selected value. Calling $(this).val() using the select's change handler will return an array of all your selected values:
$(document).ready(function() {
$("select[name=color] option").click(function() {
alert($(this).val());
});
});
I am not sure what you exactly want. This will always alert the last selected color:
$(function(){
var selected = Array();
$('select[name=color] option').click(function() {
if($(this).is(':selected')) {
selected.push($(this).val());
}
else {
for(var i = 0; i < selected.length;i++) {
if(selected[i] == $(this).val()) {
selected = selected.splice(i,1);
}
}
}
alert(selected[selected.length -1])
});
});
The array is used to maintain the history of selected colors.
For the last clicked color, it is simpler:
$(function(){
$('select[name=color] option').click(function() {
alert($(this).val());
});
});
This is so complicated to accomplish that I used a simpler option of listing the items with a checkbox next to them and a select/unselect all button. That works much better and is also supported by IE. Thanks to everyone for their answers.

Categories