jQuery Multi-Select Listbox where 'None' Option Deselects All Others - javascript

Fiddle here: https://jsfiddle.net/q0o11c5e/17/
I have a Multi-Select Listbox with 'None' with the following requirements:
Selecting 'None' included anywhere in the selection => only 'None'
is selected (anything else is turned off)
Deselecting any other item
with Ctrl+click, if nothing else is selected, will automatically
select 'None'.
This is implemented with jQuery's Change function. My issues:
1) First of all, for #2 (Full Ctrl+click deselection): the flow doesn't come into the $( "#listbox" ).change(function() at all. You can see that because if you select 'A' and then deselect it with Ctrl+click, the Alert at the top of the function isn't displayed.
2) For #1, if the selection includes 'None' (value '') anywhere, I create a blank array, push '' onto it, and set the Listbox Val to it (and break immediately), but that doesn't work.
$( "#listbox" ).change(function() {
alert('SelArray: ' + $('#listbox').val() + ' Length: ' + $('#listbox').val().length);
// If no selection, automatically select 'None'
if ($('#listbox').val().length == 0) {
alert('Nothing selected');
}
else
{
// If new selection includes empty ('None'), deselect any other active selections
$.each($('#listbox').val(), function (index, value) {
if (value == '') {
alert('None selected, clearing anything else..');
var noneOnly = {};
noneOnly.push('');
$('#listbox').val(noneOnly);
return false;
}
});
}
});

If I get the intention correctly, something like the below?
$( "#listbox" ).change(function() {
var arr= $(this).val();
if (arr == null || arr.length === 0 || (arr.length > 1 && arr[0] === ''))
$(this).val(['']);
});
This simply sets the selection whenever no value is selected or when multiple values are selected including 'none'
Fiddle

$("#listbox").on("input change", function() {
if($(this).find("option[value='']:selected").length!=0 || $(this).find("option:selected").length==0) {
$(this).find("option").attr("selected", false);
$(this).find("option[value='']").attr("selected", true);
return false;
}
});
hi, check my above piece of code, this is my try https://jsfiddle.net/q0o11c5e/22/

(Posted on behalf of the question author).
This is solved now, final fiddle here: https://jsfiddle.net/q0o11c5e/23/
JS code:
$( "#listbox" ).change(function() {
var arr= $(this).val();
if (arr == null || arr.length === 0 || (arr.length > 1 && arr[0] === '')) {
$(this).val(['']);
}
else
{
// If new selection includes empty ('None'), deselect any other active selections
$.each(arr, function (index, value) {
if (value == '') {
var noneOnly = [];
noneOnly.push('');
$('#listbox').val(noneOnly);
return false;
}
});
}
});

Related

Button is being disabled due to hidden select elements

I have a form with three select options:
Fit
Colour
Size
By default, the 'Fit' dropdown and 'Colour' dropdown are active with a default value selected (e.g. Regular Fit and Blue Colour).
There are three different 'Size' dropdowns, but only one is visible at any time depending on what is selected from the 'Fit' dropdown.
The Button is disabled if an option value="none".
Problem
The Button only becomes active if all three 'Size' dropdowns are altered so that their value is not "none" (this is done by selecting an initial size for Regular, and then selecting Petite and Long from the 'Fit' dropdown). Ideally, I only want the button to take into account the 'Size' dropdown that is active.
Update
Working jsFiddle solution provided by #nagappan below, big thanks.
https://jsfiddle.net/dodgers76/c0dvdwbz/
var currentSelectedVals = {'selector-fit':'','selector-color':'','selector-sizes':''};
var disableComboVals = [
{'selector-fit':'','selector-color':'','selector-sizes':'none'},
{'selector-fit':'petite','selector-color':'','selector-sizes':'10'},
{'selector-fit':'petite','selector-color':'','selector-sizes':'20'},
{'selector-fit':'petite','selector-color':'','selector-sizes':'22'},
{'selector-fit':'petite','selector-color':'','selector-sizes':'24'},
{'selector-fit':'long','selector-color':'','selector-sizes':'22'},
{'selector-fit':'long','selector-color':'','selector-sizes':'24'}
];
function checkDisableCombo() {
return $.grep(disableComboVals, function(vals){
cnt = 0;
$.each(vals, function(key,val) {
console.log('comparing key val '+key+val);
if (val === '' || val === currentSelectedVals[key]) {
console.log('>>matched values');
cnt = cnt + 1;
}
});
if (cnt===3) {
return true;
}
return false;
});
};
$(function(){
var sizeVal = 'none';
$("select.selector-fit").on("change", function(){
//remove active
$("select.selector-sizes.active").removeClass("active");
//check if select class exists. If it does then show it
var subList = $("select.selector-sizes."+$(this).val());
if (subList.length){
//class exists. Show it by adding active class to it
subList.addClass("active");
subList.val(sizeVal);
}
});
$('.selector-sizes').on('change', function() {
sizeVal = $(this).val();
});
});
$(function() {
$('.selector').on('change', function() {
var $sels = $('option.selector-sizes:selected[value="none"]');
var isSizeSelector = jQuery.inArray( "selector-sizes",this.classList);
currentSelectedVals[this.classList[1]] = this.value;
console.log(currentSelectedVals);
var result = checkDisableCombo();
console.log(result);
if ( result.length > 0) {
console.log('disabled false');
$("#Testing").attr("disabled", true);
} else {
$("#Testing").attr("disabled", false);
}
}).change();
});
If we want to disable the button by combination of the drop down selected values. We can have a global variable to track the current selected values from three drop downs. Only we can have array of disbale combos. So whenever user select a value we cross check with disable combos and if it matches we can disable the button. Validate the combo can be done as below. Updated the jsfiddle link. JS FIDDLE UPDATED
function checkDisableCombo() {
return $.grep(disableComboVals, function(vals){
cnt = 0;
$.each(vals, function(key,val) {
console.log('comparing key val '+key+val);
if (val === '' || val === currentSelectedVals[key]) {
console.log('>>matched values');
cnt = cnt + 1;
}
});
if (cnt===3) {
return true;
}
return false;
});

Jquery Chosen get the Id of un-selected value in dropdown

I have manage to get id of selected option for the Chosen plugin. Here is the jsfiddle Demo.
Now I am not sure how to get the Id of unselected option. I am using this code to get the id of selected option.
var SelectedIds = $(this).find('option:selected').map(function() {
if ($(this).attr('value') == params.selected)
return $(this).prop('id')
}).get();
alert(SelectedIds);
When an option is deselected, you get the change event, but the params object has a deselected property that you can use just like you're using the selected.
I made a jsfiddle for you to demonstrate: http://jsfiddle.net/1eut1c3d/
$("#chosen").chosen().on('change', function(evt, params) {
if (params.selected !== undefined) {
var selectedID = $(this).find('option:selected').map(function() {
if ($(this).attr('value') == params.selected)
return $(this).prop('id')
}).get();
alert("Selected: " + selectedID);
}
if (params.deselected !== undefined) {
var deselectedID = $(this).find('option').not(':selected').map(function() {
if ($(this).attr('value') == params.deselected)
return $(this).prop('id')
}).get();
alert("Deselected: " + deselectedID);
}
});

Making a dropdown find() faster

I have a dropdown box and an input that is used to autofilter the dropdown.I need to make a dropdown filtering faster. I've added a textbox before the dropdown menu and an event to filter the dropdown:The code snippet is:
td.prepend(' <span class="ms-metadata"><br/>(type some chars to filter )</span><br/>');
.....
td.prepend($('<input/>', {id: 'DPFilter',
onkeyup: 'filterDP(this)'
}));
and on the function filterDP(element) :
....
var value = $(element).val();
$( dropdown).find("option").each(function() {
var optionValue = $(this).val();
$(dropdown).find('option[value="' + optionValue + '"]').map(function () {return $(this).parent('span').length === 0 ? this : null;})
.wrap('<span>')
$(this).map(function () { return $(this).parent('span').length === 0 ? this : null;}).wrap('<span>').hide();
...
if ((value == "") || ($(this).text().search(value) > -1) ){
$(dropdown).find('option[value="'+optionValue+'"]').show();
}
The only place I can think of, is the $(dropdown).find('option[value="'+optionValue+'"]').show(); , instead of finding it, to use an index, but I don't know how.
Also, I use the find() twice (in a code not shown), will a variable making faster?
Thank you
You can both simplify and speed this up by using filter:
var value = $(element).val();
$(dropdown).filter(function() {
if ($(this).text().indexOf(value) != -1) {
$(this).show();
}
});

jQuery problems with function

What i'm trying to do here is if the selection is equal to value 10 the click function to be available only if selection is equal to 10. But when i change to other ex. category with different value the radio click function is still available. ?
I have 6 radio boxes with value 1,2,3,4,5,6 so what i want to do if value == 4 to slidedown another div while i'm in category with value 10.(selection).
How can i fix this problem ? Here is my sample code.
$('#category').on('change', function () {
var selection = $(this).val();
$('#slidedown'+selection).slideDown(200);
if(selection == '10'){
$("input:radio[name='checkbox']").click(function() {
var radio = $(this).val();
if(radio == '4' && selection == '10') {
$('#slidedown'+selection).slideUp();
} else {
$('#slidedown'+selection).slideDown();
}
});
});
Thanks, any help will be appreciated.
EDIT : I want to slideUp the currect div which is slided down by the category value if radio box with value 4 is checked.
You should have another selection var inside the click callback:
$('#category').on('change', function () {
var selection = $(this).val();
$('#slidedown'+selection).slideDown(200);
});
$("input:radio[name='checkbox']").click(function() {
var selection = $('#category').val(); //This does the trick
var radio = $(this).val();
if(radio == '4' && selection == '10') {
$('#slidedown_another').slideUp();
} else {
$('#slidedown_another').slideDown();
}
});
Also, callbacks must be separated for not binding a new listener each time
Hope this helps. Cheers
Use the disabled property to enable and disable the radio buttons.
$('#category').change(function() {
var selection = $(this).val();
$('#slidedown'+selection).slideDown(200);
$('input:radio[name=checkbox]').prop('disabled', selection != '10');
});
$("input:radio[name='checkbox']").click(function() {
var radio = $(this).val();
if(radio == '4') {
$('#slidedown_another').slideUp();
} else {
$('#slidedown_another').slideDown();
}
});
Your code is adding a handler when the select has the correct value, but it never removes the handler when the select changes to a different value. Also, every time they select 10 it was adding another handler, so the handler would then run multiple times.

js code to replace checkbox and closures

The following javascript (prototype 1.6) code hides all checkboxes on the page and inserts a div element with some css style and a click event to act as a fake-checkbox. It also looks out for a label next (or previous) the checkbox, to also trigger the same event.
When I click the div (fake_el) itself, everything works as expected, but when I try the same with the label, it only works one time. after that, the el isn't gonna change - as if it (the el) would be a value-parameter.
Any ideas here?
$$('input[type=checkbox]').each(function(el) {
if (el.visible()) {
var fake_el = new Element('div', { className:'checkbox checkbox_' + el.checked });
var label = (el.next() != null && el.next().tagName === 'LABEL' && el.next().readAttribute('for') === el.id) ? el.next() : undefined;
label = (el.previous() != null && el.previous().tagName === 'LABEL' && el.previous().readAttribute('for') === el.id) ? el.previous() : label;
var action = function(el) {
el.checked = (el.checked) ? false : true;
fake_el.className = 'checkbox checkbox_' + el.checked;
}
fake_el.observe('click', function() { action(el); });
if (label != null) { label.observe('click', function() { c.log(el); action(el); c.log(el); }); }
el.insert({ after:fake_el }).hide();
}
});
I changed a couple items and created a jsFiddle for this. First and foremost, c.log had to be changed to console.log for it to work for me :). After that, the only thing I changed was how the divs were added, since it wasn't working for me with insert. I set up some test data and away I went...
EDIT: Perhaps you don't have a non-label tag between two checkboxes and it is getting confused? Notice I have a br between label and the next checkbox, maybe you need to do something like that.

Categories

Resources