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

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.

Related

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

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

Using the id for if condition

What is the correct way of addressing the id of an element in an if statement condition?
if($('id').val() == Reset)
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
Thanks,
Neil P.
Since I can't see your HTML I'm going to post a simple example:
<div id="myID"></div>
if($("div").attr("id") == "myID")
{
//do stuff
}
if($('someSelector').attr('id') == 'Reset')
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
if ( $('div').attr('id') == 'Reset' ) {
// do something
}
If you're trying to check the value of the ID property then you can get it using the attr method.
For example, if you were looping through all of the elements with the class foo and wanted to check for the id bar you could do this in your loops:
...
var id = item.attr("id");
if(id == 'bar')
{
}
Here's an example where all divs on the page are selected and each one has it's ID checked in turn:
var divs = $('div');
divs.each(function(index, value) {
var id = $(value).attr('id');
if(id == 'foo')
{
// Do foo work
}
else if(id == 'bar')
{
// Do bar work
}
Working example: http://jsfiddle.net/gZHMD/1/
Using a short form (ternary/conditional operator) instead of if
// element could be any html element but inputs have val and div, spans and suchlike don't have val
var Submit_Status = $('element').attr('id') == 'Reset' ? $("#Reset").val() : $("#Nb_var97").val();
Also, if you have multiple elements, then you have to select specific one, an example here.

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 select all class except the clicked element in JQuery?

I have a website developed on Drupal. I use a module called collapsiblock (it is basicly a JQuery plugin) to achieve accordion like effect. It is working fine with me (although it is in Beta). But I want to modify it so that when the user clicks on one item of the accordion the other items will collapsed.
In its current stats, it is working in a way that when the user click on one item, it will check if the item is already collapsed or expanded and it will make the item the opposite. That means if the user clicks on one item it will expand and if he/she clicks on another item it will also expand, but it will not collapse the previously clicked item.
You can see the code below. I know where should I add the code to collapse and how to collapse and expand. My question is: How do I select all the items that have the class '.collapsiblock' except the one that the user has clicked??
Note: the item that has the class '.collapsiblockCollapsed' get collapsed and if this class is removed from the item it get expanded.
// $Id: collapsiblock.js,v 1.6 2010/08/18 19:17:37 gagarine Exp $
Drupal.Collapsiblock = Drupal.Collapsiblock || {};
Drupal.behaviors.collapsiblock = function (context) {
var cookieData = Drupal.Collapsiblock.getCookieData();
var slidetype = Drupal.settings.collapsiblock.slide_type;
var defaultState = Drupal.settings.collapsiblock.default_state;
var slidespeed = parseInt(Drupal.settings.collapsiblock.slide_speed);
$('div.block:not(.collapsiblock-processed)', context).addClass('collapsiblock-processed').each(function () {
var id = this.id;
var titleElt = $(':header:first', this).not($('.content :header',this));
if (titleElt.size()) {
titleElt = titleElt[0];
// Status values: 1 = not collapsible, 2 = collapsible and expanded, 3 = collapsible and collapsed, 4 = always collapsed
var stat = Drupal.settings.collapsiblock.blocks[this.id] ? Drupal.settings.collapsiblock.blocks[this.id] : defaultState;
if (stat == 1) {
return;
}
titleElt.target = $(this).find('div.content');
$(titleElt)
.addClass('collapsiblock')
.click(function () {
var st = Drupal.Collapsiblock.getCookieData();
if ($(this).is('.collapsiblockCollapsed')) {
$(this).removeClass('collapsiblockCollapsed');
if (slidetype == 1) {
$(this.target).slideDown(slidespeed);
}
else {
$(this.target).animate({height:'show', opacity:'show'}, slidespeed);
}
// Don't save cookie data if the block is always collapsed.
if (stat != 4) {
st[id] = 1;
}
}
else {
$(this).addClass('collapsiblockCollapsed');
if (slidetype == 1) {
$(this.target).slideUp(slidespeed);
}
else {
$(this.target).animate({height:'hide', opacity:'hide'}, slidespeed);
}
// Don't save cookie data if the block is always collapsed.
if (stat != 4) {
st[id] = 0;
}
}
// Stringify the object in JSON format for saving in the cookie.
var cookieString = '{ ';
var cookieParts = [];
$.each(st, function (id, setting) {
cookieParts[cookieParts.length] = ' "' + id + '": ' + setting;
});
cookieString += cookieParts.join(', ') + ' }';
$.cookie('collapsiblock', cookieString, {path: Drupal.settings.basePath});
});
// Leave active blocks uncollapsed. If the block is expanded, do nothing.
if (stat == 4 || (cookieData[id] == 0 || (stat == 3 && cookieData[id] == undefined)) && !$(this).find('a.active').size()) {
$(titleElt).addClass('collapsiblockCollapsed');
$(titleElt.target).hide();
}
}
});
};
Drupal.Collapsiblock.getCookieData = function () {
var cookieString = $.cookie('collapsiblock');
return cookieString ? Drupal.parseJson(cookieString) : {};
};
UPDATE:
Problem has been solved by adding the following code:
$('.collapsiblock').not(this).each(function(){
$(this).addClass('collapsiblockCollapsed');
$(this.target).animate({height:'hide', opacity:'hide'}, slidespeed);
});
just above the following line:
$(this).removeClass('collapsiblockCollapsed');
Use the not selector.
Example:
$('.collapsiblock').click(function(){
$('.collapsiblock').not(this).each(function(){
$(this).slideUp();
});
$(this).slideDown();
})
Try this,This is a better way because if you use each function it will load and in the future when you have more than a thousand div it will take a long time to slide up and slide down.
Example:
$('.collapsiblock').click(function(){
$('.collapsiblock').not(this).slideUp();
$(this).slideDown();
});
You could keep track of which element has already been clicked with your own jquery click handler and jquery's data(...) function. Then filter iterating your .collapsiblock items with jquery's filter (...) function to include the items you need.

Categories

Resources