Make javascript reference variable a value variable? - javascript

I have a javascript function that goes something like this:
function doSomething(me) {
var isMeChecked = me.checked;
for (i=0;i<=10;i++) {
me.checked = !isMeChecked;
alert (me.checked);
}
}
I assumed that isMeChecked would remain constant after the first load, but it apparently is a reference variable to me.checked, and so it changes with every iteration.
How do I force isMeChecked to get set to the value of me.checked when it's first loaded, and not the reference of me.checked?
Alright, to make this more clear, I am editing this post to show actual code in use that is exhibiting the undesirable behavior:
Here are the javascript functions:
function CheckAll(me, gridViewId) {
var isMeChecked = (me.checked)?true:false;
alert('CheckAllFired_1');
Parent = document.getElementById(gridViewId);
for (i = 0; i < Parent.rows.length; i++) {
alert('CheckAllFired_2_' + i.toString());
var tr = Parent.rows[i];
var td = tr.childNodes[0];
var item = td.firstChild;
if (item.id != me.id && item.type == "checkbox") {
alert('CheckAllFired_3_' + i.toString() + '_' + me.checked + '_' + isMeChecked);
item.checked = !isMeChecked;
item.click();
}
}
}
function CheckSelectAll(me, checkBoxHeaderId, gridViewId) {
alert('CheckSelectAllFired_1');
if (!me.checked) {
alert('CheckSelectAllFired_2');
document.getElementById(checkBoxHeaderId).checked = false;
return;
}
else {
alert('CheckSelectAllFired_3');
document.getElementById(checkBoxHeaderId).checked = true;
Parent = document.getElementById(gridViewId);
for (i = 0; i < Parent.rows.length; i++) {
alert('CheckSelectAllFired_4_' + i.toString());
var tr = Parent.rows[i];
var td = tr.childNodes[0];
var item = td.firstChild;
if (item.type == "checkbox") {
alert('CheckSelectAllFired_5_' + i.toString());
if (!item.checked) {
alert('CheckSelectAllFired_6_' + i.toString());
document.getElementById(checkBoxHeaderId).checked = false;
return;
}
}
}
return;
}
}
I have an asp.net gridview. The first column is a column of checkboxes, with a checkbox in the header as well that toggles "Select/Deselect All" of the other checkboxes in the column.
The checkbox in the header has it's onclick event set to onclick="CheckAll(this, 'myGridViewClientID')"
All of the remaining checkboxes in the grid, have their onlick event set to onclick="CheckSelectAll(this, 'headerCheckBoxID', 'myGridViewClientID'"
Both the headerCheckBoxID and myGridViewClientID are set in the codebehind when the gridview is rendering.
The idea is that when the checkbox in the header is checked, it will set all the other checkboxes to the opposite checked status, and then fire their click event to simulate a click, and also fire their onclick actions (which involve things like changing the color of their row, setting the datakey of the row into a SelectedValues array if it is checked, etc).
However, I also wanted the child checkboxes to have the following behavior:
1) If any of them get unchecked, uncheck the "select all" checkbox.
2) If all of them get checked, check the "select all" checkbox.
Now, because the click event of the child checkboxes has the opportunity to change the checked status of the headercheckbox, when the loop returns back to the "checkall" event, the state of the headercheckbox is different than when it first started, and so it ends up only checking the first child checkbox when trying to do a select all.
Using alerts, I was able to see that when the checked state of the headercheckbox is changed in the CheckSelectAll function, that value is also changed for the "isMeChecked" value in the CheckAll function which is spawning the CheckSelectAll functions.
That looks an awful lot like a reference variable then. I don't know how to stop it from doing that.

Think about it. assume x.checked = true. run doSomething(x).
When the function starts, me.checked is true. Now look at your for loop:
Pass 1: me.checked is true. so isMeChecked is true. so you set me.checked to false.
Pass 2: me.checked is false. isMeChecked is still true, because you don't change it inside the loop. so me.checked is again set to false.
Pass 3: see pass 2.
...
When the function exits, isMeChecked is true, and me.checked is false. All you have done is set me.checked to false 10 times.
This is not a matter of isMeChecked being a reference (because it's not), but just an error in your logic if you were expecting different results.

Unless I'm crazy, there's no such thing as a reference to a boolean in javascript. They're always passed by value. Can you paste complete example code that we can run without filling in any blanks?

Your loop is just broken -- Read the comments
// doSomething({checked:true});
function doSomething(me) {
// isMeChecked = true;
var isMeChecked = me.checked;
for (i=0;i<=10;i++) {
// me.checked = false ... always...
me.checked = !isMeChecked;
alert (me.checked);
}
}

You could do var isMeChecked = me.checked?true:false;
Also, me.checked != isMeChecked is not the same as me.checked = !isMeChecked, which is probably what you intended.

Related

Find whether all checkbox are checked within a parent div

I am trying to get the state of two input checkboxes within a div element. I need to set a flag variable to true only if both the checkboxes are checked. If any of the input checkbox is unchecked , then it should be set to false.
I tried this using for loop using the below code
var oParNode = oNode.ParentNode;
if (null != oParNode) {
for (var i = 0; i < oNode.ParentNode.Nodes.length; i++) {
if (oNode.ParentNode.Nodes[i].Checked) {
checked = true;
}
else {
checked = false;
}
}
}
In this code , Nodes[i] returns the input element. When I check the first checkbox first and the second one next this loop works fine but when I check the second one first , the checked variable is set to true based on the second checkbox value which is executed at last.
Expected: I need to return "checked" to be true only if both checkboxes are checked .
Can some one suggest me on this.
You can use Array#some() method, to check if there's an unchecked one:
var checked = oNode.ParentNode.Nodes.some(check => !check.checked)
Seems for second node it is overriding the value. If you know there are two checkboxes you can directly check it like this.
if (oNode.ParentNode.Nodes[0].Checked && oNode.ParentNode.Nodes[1].Checked) {
checked = true;
} else {
checked = false;
}
Instead of finding all checked, find unchecked instead since this is what you are looking for.
var checked = true;
for (var i = 0; i < oNode.ParentNode.Nodes.length; i++) {
if (!oNode.ParentNode.Nodes[i].Checked) {
checked = false;
break;
}
}
You need to break your loop in case any of checkbox is not checked
var oParNode = oNode.ParentNode;
if (null != oParNode) {
for (var i = 0; i < oNode.ParentNode.Nodes.length; i++) {
if (oNode.ParentNode.Nodes[i].Checked) {
checked = true;
} else {
checked = false;
break;
}
}
}
You can simply every method of array instead of loop
let checkedAll = oNode.ParentNode.Nodes.every(element => element.checked )

Javascript Enabled input type when checkbox checked and disable when checkbox unchecked

my javascript is here:
function enable(id) {
var i = (document.getElementById('haha').checked);
if(i= true) {
document.getElementById("nama_"+id).disabled= false;
document.getElementById("ket_"+id).disabled= false;
}else{
document.getElementById("nama_"+id).disabled= true;
document.getElementById("ket_"+id).disabled= true;
}
}
when i checked checkbox, the textbox will enabled, but when i unchecked, that textbox still enable, i want to this textbox go disabled after i unchecked. how can i fix this problem?
= is assignment (setting the value of a variable), so if (i = true) sets i to true and then branches into the if block. To do a comparison, normally you'd use == or ===, but with booleans, that's never necessary; just check the value directly:
if (i) {
// Enable it
} else {
// Disable it
}
In this case, though, you can just use i directly:
document.getElementById("nama_"+id).disabled = !i;
document.getElementById("ket_"+id).disabled = !i;
There's also no need for the () around your check of checked.
I'd probably do this:
function enable(id) {
var disabled = !document.getElementById('haha').checked;
document.getElementById("nama_"+id).disabled = disabled;
document.getElementById("ket_"+id).disabled = disabled;
}
There, I'm getting the value of the checkbox and inverting it, then using that as the disabled flag on the other inputs. I'd do it like that because it's nice and easy to debug, I can see the disabled value easily in the debugger when I'm stepping through code.
Some folks really, really like to do things in one expression. (I think that's very overrated.) They might do this:
function enable(id) {
document.getElementById("nama_"+id).disabled =
document.getElementById("ket_"+id).disabled =
!document.getElementById('haha').checked;
}
...since the result of an assignment is the value that was assigned.
function chkBox(obj) {
console.log(obj);
$(obj).parents("tr").find("input[type='number']").prop('disabled', !$(obj).is(":checked"));
$(obj).parents("tr").find("input[type='hidden']").prop('disabled', !$(obj).is(":checked"));
}
call the function and pass this.
onclick="chkBox(this)"

HTML 5 toggling the contenteditable attribute with javascript

enter code hereI am trying to make something editable online with a function like this
function toggle_editable (div, cssclass) {
var classToEdit = document.getElementsByClassName(cssclass)
for (i = 0;classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
}
if (classToEdit[i].contentEditable == true) {
classToEdit[i].contentEditable = false ;
}
}
}
classToEdit is a collection of HTML elements with the same class name or whatever document.getElementsByClassName(cssclass) returns
when going through the debugger it jumps over the line
classToEdit[i].contentEditable == true
as well as over the line
classToEdit[i].contentEditable == true
and does not execute the code in the braces following the if statements
this works however - meaning it sets the contenteditable property without hesitation
classToEdit.contenteditable = true;
as well as this
classToEdit.contenteditable = false;
(well obviously)
also this seemed to have no effect
classToEdit.contenteditable = !classToEdit.contenteditable
ideas anyone?
ps why is the loop
You've created an infinite loop here:
for (i = 0;classToEdit.length; i++) {
Should be:
for (var i = 0; i < classToEdit.length; i++) {
But, if you say classToEdit.contenteditable = true "works", you've to define "not working/is working" since the snippet doesn't definitely do what you expect it to do, if classToEdit is a HTMLCollection.
It looks like you'd want to toggle contentEditable values, you can do it like this:
for (var i = 0; i < classToEdit.length; i++) {
if (classToEdit[i].contentEditable == false) {
classToEdit[i].contentEditable = true ;
} else { // Notice else here, no need for another check
classToEdit[i].contentEditable = false;
}
}
Or simply without ifs in the loop:
classToEdit[i].contentEditable = !classToEdit[i].contentEditable;
Your current code will switch the value back to it's original in a case the value was false.
HTMLElement.contentEditable returns a string and not a boolean.
Hence, what you want to identify the state of your editable field is:
// Incorrect
classToEdit[i].contentEditable == true
// Coorect
classToEdit[i].contentEditable === 'true'
What's even better if you want to know the state of your fields is to use HTMLElement.isContentEditable
which returns a boolean:
classToEdit[i].contentEditable = !element.isContentEditable
Another way to refactor the above:
function toggleContentEdit() {
var editableFields = document.getElementsByClassName('editable');
[].forEach.call(editableFields, function(field){
var isEditable = field.isContentEditable;
field.setAttribute('contenteditable', !isEditable);
});
};
JSFiddle: http://jsfiddle.net/6qz3aotv/

What does unescape() function returns?

I have to use unescape() function in an if-else statement. In my website I have two pages, one with a form that the user fills and the second page have to get the information from the filled form by unescape function. I need the if-else statement because in the form I put two radio buttons that each one adds different text areas with different ids' and names so I want to check in the second page what text fields are are filled. (all the fields created by clicking on a radio button which starts a javascript function so in the next page I must check if the field was created and not just to check if it is an unfilled text field).
It is a little bit hard for me to explain so just check the code. In the code you will see params["placeName"] and so on, so placeName for example like all the others is a text field name from the previous page.
So the question is - what does unescape function returns if the component name I insert as a paramater does exist in the previous page?
<script type="text/javascript">
function getParams() {
var idx = document.URL.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = document.URL.substring(idx + 1, document.URL.length).split('&');
for (var i = 0; i < pairs.length; i++) {
nameVal = pairs[i].split('=');
params[nameVal[0]] = nameVal[1];
}
}
return params;
}
params = getParams();
//from here it is what I want to do (I don't know if this condition in the if statement is correct, this is what I ask)
// if (unescape(params["placeName"]) == false) {
// }
// else {
var place = unescape(params["placeName"]);
var country = unescape(params["country"]);
var city = unescape(params["city"]);
var address = unescape(params["address"]);
var type = unescape(params["type"]);
var rate = unescape(params["rate"]);
// }
</script>
It can also work if I could check what radio button is checked
You are asking what will unescape(params["something"]) return if params["something"] is not present. The answer is undefined. So you need to check equivalence to "undefined". Meaning: if (unescape(params["placeName"]) == "undefined") (in this case params["placeName"] is not present (was not created).
The undecode function returns -as it's name indicated- a decoded string. If you enter a value that's not defined it will probably cause an error because of the indefinition. If what you want is to check whether the element was or not created or not you could use
if (params.placeName !== undefined) {
// It was created
}
instead.
Aditionally, if you want to check which radio button was checked use
if (document.getElementById('foo').checked) {
// Radio button with id 'foo' was checked
} else if (document.getElementById('bar').checked) {
// Radio button with id 'bar' was checked
} else if
...

how to check if a checkbox exists

The check box's exist for each row. the table is created by PHP and I need a way to check if the check box exists. when they are created they are given the ID of checkbox_(an incrementing number).
This is what I have so far, but it does not work on checking if the element exists.
var check = true;
var todelete = "";
var counter = 0;
//check if box exisits and record id and post
while(check)
{
if ($("#Checkbox_"+counter).length > 0)
{
todelete = todelete + $("#Checkbox_"+counter).value;
counter = counter + 1;
}
else
{
check = false;
}
}
I have also tried
if ($("Checkbox_"+counter))
if (document.getElementById("tbody").value == null)
Update:
Even with the # symbol or if i do it by javascripts element ID - when I debug the DOM, it hits the while, then the if, adds the value to todelete, adds 1 to the counter, then it goes back to the while, then hits the if
Then bounces back up to the while without even going into the if or the else???
this I do not understand, then it just bounces up and down between the two lines and crash's the browser?
Update2:
I needed to .tostring() the counter when adding it to the string for an element id. problem solved
You can use
if ($("#Checkbox_"+counter).length > 0)
I'm assuming that 'Checkbox_0' is an ID, so I've added the # symbol. If it's the name of the checkbox, you can use
if ($("input[name='Checkbox_"+counter+"']").length > 0);
[edit]Also, you should check to make sure you do / don't need the capital 'C'.
You can use for "checkbox exists in this case"
if ($("#Checkbox_"+counter).length > 0) {
//checkbox exists
}
if (($("#Checkbox_"+counter).length) > 0) {
...
//Or something more generalized
jQuery.fn.exists = function(){
return jQuery(this).length>0;
}
//then, if you have valid selector
if ($("#Checkbox_"+counter).exists()){
//do something here if our selected element exists
}
// if document.getElementById(name) do not exist
// document.getElementById(name).value generate already an error
if (document.getElementById(name) != null) {
// you code if checkbox exist
}

Categories