Making a dropdown find() faster - javascript

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();
}
});

Related

minified javascript codes, I don't understand, can anyone explain it

I'm trying to improve myself by working on codes. I can understand its normal state without any problems. In the sample code below, jquery, value reading, value assignment and if-else queries are nested. I could not get the code in a meaningful readable way. Can anyone write the code below in a simple expanded readable format?
$('.input-required input, .input-required select, .input-required textarea').on('focusin keyup', function () {
var inputSpan = $(this).parent().find('span').text();
$(this).val() != inputSpan && '' != $(this).val() && $(this).parent().find('span').addClass('input-style-1-active').removeClass('input-style-1-inactive'),
'' === $(this).val() && $(this).parent().find('span').removeClass('input-style-1-inactive input-style-1-active')
});
$('.input-required input, .input-required select, .input-required textarea').on('focusout', function () {
$(this).parent().find('span').text();
'' === $(this).val() && $(this).parent().find('span').removeClass('input-style-1-inactive input-style-1-active'),
$(this).parent().find('span').addClass('input-style-1-inactive')
});
The extended version of the first code block is correct as below?
$('.input-required input, .input-required select, .input-required textarea').on('focusin keyup', function () {
var inputSpan = $(this).parent().find('span').text();
if(($(this).val() != inputSpan) && ('' != $(this).val())){
$(this).parent().find('span').addClass('input-style-1-active').removeClass('input-style-1-inactive');
}else{
$(this).parent().find('span').removeClass('input-style-1-inactive input-style-1-active');
}
});
Whoever wrote that did not write it with maintenance in mind. Is it generated code by some tool?
I would think it could be condensed to
$(':input.input-required').on('input focusout', function (e) {
let $inputSpan = $(this).parent().find('span'),
text = $inputSpan.text(),
val = $(this).val();
if (val && val != text) {
$inputSpan
.addClass('input-style-1-active')
.removeClass('input-style-1-inactive')
}
else {
$inputSpan
.removeClass('input-style-1-active')
.addClass('input-style-1-inactive')
}
});
Which may be even more readable with toggleClass

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

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;
}
});
}
});

Jquery once two options have been selected from select drop down list run code

I have 2 select drop down menus. I want to to add a class once a option has been selected from both menus.
$('#size').change(function(){
if ($(this).val() > 0 ) {
$('#pizza').addClass('pizzaImage');
}
});
$('#crust').change(function(){
if ($(this).val() > 0 ) {
$('#pizza').addClass('pizzaImage');
}
});
This is my code so far, it works when I select an option from one. Basically I want to put these together I just don't know the syntax to do so. I also tried this but no results.
var size = $('#size')
var crust = $('#crust')
function image () {
if ((crust).val > 0 && (size).val > 0) {
$('#pizza').addClass('pizzaImage');
}
}
var $selects = $('#size, #crust');
$selects.change(function(){
var bothSelected = this.value && $selects.not(this).val();
$("#pizza").toggleClass("pizzaImage", bothSelected);
});
I would start by adding a common class between the two, to make it easier to bind the function to both select elements at the same time. Maybe something like pizzaOptions. Then, you could do something like this:
$(".pizzaOptions").on("change", function(){
var sizeSelected = $("#size").val() !== "";
var crustSelected = $("#crust").val() !== "";
if(sizeSelected && crustSelected){
$('#pizza').addClass('pizzaImage');
}
});

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.

How to store <TR> id value in array, when I toggle?

I am toggling 'tr.subCategory1'and its siblings .RegText. at the same time I am trying to store its ids in the array like this list_Visible_Ids[$(this).attr('id')] = $(this).css('display') != 'none' ? 1 : null; (When I collapsed I need store 'null' in array at its id place, If I expand I need store I need store 1 at its id place). But everytime alert($(this).css('display')) showing block. How can I handle this?. So When I collapsed or expanded it is storing 1 only.
$(document).ready(function() {
$('tr[#class^=RegText]').hide().children('td');
list_Visible_Ids = [];
var idsString, idsArray;
idsString = $('#myVisibleRows').val();
idsArray = idsString.split(',');
$.each(idsArray, function() {
if (this != "" || this != null) {
$('#' + this).siblings('.RegText').toggle();
list_Visible_Ids[this] = 1;
}
});
$('tr.subCategory1')
.css("cursor", "pointer")
.attr("title", "Click to expand/collapse")
.click(function() {
$(this).siblings('.RegText').toggle();
$(this).siblings('.VolumeRegText').toggle();
//alert($(this).css('display'))
list_Visible_Ids[$(this).attr('id')] = $(this).css('display') != 'none' ? 1 : null;
});
$('#form1').submit(function() {
idsString = '';
for (var index in list_Visible_Ids) {
idsString += (idsString != '' ? ',' : '') + index;
}
$('#myVisibleRows').val(idsString);
form1.submit();
});
});
You aren't toggling the tr itself, only its siblings (with class .RegText and .VolumeRegText). You therefore have to check if these are visible when you are storing the state in the array. For this you can use .is(":hidden") on one of the siblings. The click function would then look like this
$('tr.subCategory1')
.css("cursor", "pointer")
.attr("title", "Click to expand/collapse")
.click(function() {
$(this).siblings('.RegText').toggle();
var isHidden = $(this).siblings('.VolumeRegText').toggle().is(':hidden');
list_Visible_Ids[$(this).attr('id')] = !isHidden ? 1 : null;
});
There is also a lot to comment on the rest of the code. In
$('tr[#class^=RegText]').hide().children('td');
skip the .children('td'), as you aren't using this selection.
list_Visible_Ids = []; should be declared using var.
Looping through idsArray, you are checking this != "" || this != null), which should be using && instead of ||.
$.each(idsArray, function() {
if (this != "" && this != null) {
$('#' + this).siblings('.RegText').toggle();
list_Visible_Ids[this] = 1;
}
});
There's also really no point in using the $.each() function instead of a regular JavaScript for-loop
It also seems you are using an old version of jQuery, since using the # in selectors was deprecated in version 1.3.

Categories

Resources