js code to replace checkbox and closures - javascript

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.

Related

Is there anything that I am missing?

I created a checkbox and apply these attributes
let box = document.createElement('input');
box.setAttribute("type","checkbox");
box.setAttribute("id","box");
box.setAttribute("onclick","checkBox(this)");
This is the function
function checkBox(para2){
let condition = box.checked;
if (condition === true) {
para2.parentNode.style.opacity = '0.5'
para2.parentNode.style.textDecoration = "line-through"
}
if (condition === false) {
para2.parentNode.style.opacity = "1";
para2.parentNode.style.textDecoration = "none";
}
}
When I click on first checkbox, style works. But when I click on other children it doesn't work.
In your checkBox function,
let condition = box.checked;
This line specifically checks whether the checkbox "box" is checked. Since you are having multiple checkboxes, I believe you may have box2, box3, etc.
As a solution, you can introduce a "name" attribute to your checkboxes and use a query selector to identify which ones are checked.
let condition = document.querySelectorAll('input[name="color"]');
condition.forEach((cb) => {
if (cb.checked === true) {
// your code
} else {
// your code
}
});
Note: there might be many other possible ways to do this. This is the one that came to my mind right now

dojo/cbtree uncheck all checkboxes and check selected checkbox

I want to make the checkbox work more or less like a radio button in this instance. This is what I have so far. I would like to be able to do this in the treeCheckboxClicked() function so that it would just uncheck all the remaining checkboxs then check the one that was selected.
buildTocTree: function (cp1) {
var self = this;
var toc = new TOC({
checkboxes: false,
enableDelete: true,
deleteRecursive: true,
showRoot: false,
checkBoxes: false,
}, self._viewId + '_tocTree');
toc.on("checkBoxClick", dojo.hitch(this, "treeCheckboxClicked"));
},
treeCheckboxClicked: function (e) {
if (e.checked) {
if (e.subLayers || e.name === 'GISLayer')
this.selectedLayerValue('');
else if (e.layerInfos)
this.selectedLayerValue('');
else
this.selectedLayerValue(e.name);
if (this.selectedLayerValue() != '')
this._selectedGISSourceLayer = e;
else
this._selectedGISSourceLayer = '';
}
}
Without knowing the internal details of the TOC widget, especially its DOM, it's difficult to know how to query all checkboxes within its template. Assuming your treeCheckboxClicked is already getting called, and e.target is the checkbox element itself, the following code should get you close to your desired functionality:
if (e.checked) {
query('checkbox', self.domNode).forEach(function (checkbox) {
checkbox.checked = checkbox != e.target;
});
//...
}
Note: This assumes the dojo/query module has been loaded.
Are you using agsjs.TOC? They have a handler included to do this for you. In the examplesat http://gmaps-utility-gis.googlecode.com/svn/tags/agsjs/latest/examples/toc.html they toggle the function off and on with a button, but you can make it default on and include the following snippet in your tree declaration. (replace DynaLayer 1 with your layer)
toc.on('toc-node-checked', function(evt){
// when check on one layer, turn off everything else on the public safety service.
if (evt.checked && evt.rootLayer && evt.serviceLayer && evt.rootLayer == dynaLayer1){
evt.rootLayer.setVisibleLayers([evt.serviceLayer.id])
}

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

Checkbox is still showing true when unchecked jQuery

Ok, so I'm currently having an issue with the $.prop('checked') functionality. When unchecking some of my boxes, and using this function to read the checkboxes, all of them are still showing up as true when some of them should be showing up as unchecked. The part of the function that checks this is below, but some background: I'm using a table with input values in each td element and due to the way it's written, I'm having to gather all the info / validate / and check by using a td.each() function.
$("td", ele).each(function(idx){
var before = $('.e_content', this),
b_name = $('input:last[type!="hidden"], textarea:last, checkbox:last, select:last', this).attr('name'),
b_val = $('input[name="'+b_name+'"], select:last, textarea[name="'+b_name+'"]', this).val(),
b_chx = $('input:checkbox[name="'+b_name+'"]', this).prop('checked'),
after = function(){
before.hide();
$(ele).css("background", color);
$('td.edit', ele).show();
$('td.save', ele).hide();
$('span', this)
// WORKING ON TAKING THE VALUE OF THE .e_content FORM AND REPLACING THE SPAN WITH IT
.html(function(){
console.log(b_name+' : '+b_chx);
if(b_val != undefined && b_val != ''){
if(b_name == 'StageType'){
if(b_val == 1){ return 'Voice'; }
if(b_val == 2){ return 'Text'; }
if(b_val == 3){ return 'Email'; }
}
else if(b_name == 'qtrhour') {
return $('select', before).find(':selected').text();
}
else if(b_chx == true) { return '&check;'; }
else if(b_chx == false) { return '&cross;'; }
else {
if(before.find('input:last').prop('type') != 'checkbox')
return b_val.replace(/\n\r?/g, '<br />');
}
}
})
.show();
};
$(this).html(after);
});
The problem is with this line:
b_chx = $('input:checkbox[name="'+b_name+'"]', this).prop('checked'),
It's coming up always as true even when the checkbox has been unchecked before the save button is hit. This function fires on the .save click event. Hopefully this is enough to determine what might be going wrong.
You can try the following,
$('input:checkbox[name="'+b_name+'"]', this).is(':checked');
To avoid issues regarding to checking or unchecking checkboxes, I normally use jQuery.attr()
$(...).attr('checked')
$(...).attr('checked','checked')
$(...).removeAttr('checked')
Also sometimes I check or uncheck them binding or triggering a .click() function.

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