Validation for checkboxes - javascript

Hello
I have a JS function which says
for(var i = 0; i < document.calDailyBlock.selFilCheckBox.length; i++)
{
if(document.calDailyBlock.selFilCheckBox[i].checked)
{
filteredInitId += document.calDailyBlock.selFilCheckBox[i].value + ",";
alert(filteredInitId);
isProjCheck = true;
}
}
document.calDailyBlock.filteredComId.value = filteredInitId;
When there are no checkboxes on the page and I try to click on Filter button which calls this function, I receive an error "document.calDailyBlock.selFilCheckBox.length' is null or not an object"
Is there any simple thing which I can add in this function ?
Also can anyone help me how to check if there is only one checkbox on one page ?
Thanks in advance

I think you are relying on a fairly obscure (non-official) feature of some browsers which lets you get an element from the document as if it were an attribute. In other words, you are going:
document.calDailyBlock
This is searching the document for a variable calDailyBlock. Instead, you should use the standardised getElementById:
document.getElementById("calDailyBlock")
And use the same approach for getting selFilCheckBox.
This will return null if calDailyBlock or selFilCheckBox are not found. Before you go calling length on them (which gives that error), you should check to see if you got back null, and then (I suppose) fail silently (don't do anything).

to avoid the error use an if:
if(document.calDailyBlock.selFilCheckBox) {
for(var i = 0; i < document.calDailyBlock.selFilCheckBox.length; i++)
{ … }
}

Related

Declaring a for loop function in javascript

I have a for loop that searches for a value in an array in my javascript code in couchDb. I want to make it into a function. This should be fairly simple but I am having trouble with it. This is the for loop(Which works perfectly fine):
if (newDoc.destination && newDoc.destination.length > 0) {
for (var i = 0; i < newDoc.destination.length; i++) {
if (newDoc.destination[i].address) return;
}
}
throw({forbidden: 'doc.address is required'});
And this is the way I wrapped it into a function:
function arrayReq(field, message) {
message = message || "Array must have a " + field;
if (newDoc.destination && newDoc.destination.length > 0) {
for (var i = 0; i < newDoc.destination.length; i++) {
if (newDoc.destination[i].field) return;
}
}
throw({forbidden: message});
}
I would think that the return in the function should stop the function from going any further but it still throws the error. Can someone tell me what I am doing wrong? Btw if i change field into address it works fine. Can I not make the address into a changeable variable?
I think the problem is that you are trying to use field as both a string variable, and a property of your object inside the destination[] array.
In your code, if the destination[i] object does not have a property called field (not the string value populated in the field parameter, but an actual property named "field") it will never evaluate to true and break out of the function.
To access a property of an object by using the string representation in javascript, you use the indexer syntax.
Try changing it from array.destination[i].field to array.destination[i][field]

JavaScript throws TypeError saying that my variable is undefined

I don't have much experience in JavaScript, so far I have this:
function loop() {
var authorDivs = document.getElementById('ctl00_MainContent_MCPObjectInfo_dvCreatorView').getElementsByTagName("div");
for (var i = 0; i < authorDivs.length; i++) {
var divOfDiv = authorDivs[i].getElementsByTagName("div");
if (typeof divOfDiv.item(i) === 'undefined' || divOfDiv.item(i) === null) {
console.log("This is undefined or null");
}
else {
var realDivs = divOfDiv.item(i);
realDivs.item(i).textContent = "please work plz";
}
}
}
I get the following error from the console in FireFox: TypeError: realDivs is undefined on this line: realDivs.item(i).innerHTML = "please work plz";
Essentially what I have (in my mind) is a loop that goes through authorDivs and gets all of the divs within those divs and saves them in divOfDiv. I then check to see if the divs in divOfDiv are undefined or null, if they are not then those divs get saved in a variable realDivs which I then use to edit the innerHTML. That's what I'd ideally like to see happen, what is causing the error? What am I doing wrong?
Note: I do not have access to jQuery but only JavaScript.
Edit: I've added the changes suggested below and its fixed that -- thanks! But I'm now getting the following error: TypeError: realDivs.item is not a function
What is causing that? And on another note how do I know when I'm dealing with an array and when I'm dealing with an HTMLCollection? Do you just assume? I've never used a loosely typed language before so its new to me.
Well, you'll need to move that code inside the conditional block that is supposed to prevent it! Also, || "null" is not going to work as you expect, you'll need to check for || divOfDiv.item(i) === null explicitly.
So try
for (var i = 0; i < authorDivs.length; i++) {
var divOfDiv = authorDivs[i].getElementsByTagName("div");
if (divOfDiv.item(i) == null) {
console.log("This is undefined or null");
} else {
var realDivs = divOfDiv.item(i)
realDivs.item(i).innerHTML = "please work plz";
console.log(divOfDiv.item(i));
}
}
However, that still doesn't really work for two reasons:
The i index you use to access the i-th divOfDiv comes from the iteration over authorDivs - hardly what you want. Instead, use a second loop over all divOfDivs.
Your realDivs variable does hold a single <div>, which does not have an .item method. You'd just directly access its .innerHTML property.
So you should use
var authorDivs = document.getElementById('authorView').getElementsByTagName("div");
for (var i=0; i<authorDivs.length; i++) {
var divsOfDiv = authorDivs.item(i).getElementsByTagName("div");
for (var j=0; j<divsOfDiv.length; j++) {
var realDiv = divsOfDiv.item(j);
realDiv.innerHTML = "please work plz";
console.log(realDiv);
}
}
it will happen in case when your if (typeof divOfDiv.item(i) === 'undefined' || 'null') returns true. Then you never initialize realDivs (what would happen if condition was falsy). Later you try to call item function on that unitialized object
There are two problems in the code.
comparing DOM object with 'undefined' and null. If div tag is not available in authorDivs[i], it will return empty DOM array. So, comparision of empty DOM array with undefined and null is not good approach. We can use array length property for doing validation.
divOfDiv = authorDivs[i].getElementsByTagName("div");
if(divOfDiv.length > 0) { console statement}
As item(i) is already return single DOM element, item(i) of "realDivs" variable is not proper approach. In addition to this, innerHTML method needs to be used after validating whether realDivs contains DOM element. Please update the code as below.
var realDivs = divOfDiv.item(i);
realDivs ? (realDivs.innerHTML = "please work plz"): null;
Note : item(i) will return null if DOM is not available.

How do I recurse DOM nodes to an arbitrary depth in Javascript?

I am really having trouble getting my head around crossbrowser recursion in the DOM. I want to get only the text content of a node, but not any HTML tags or other information. Through trial and error, I found that the textContent and innerText attributes don't hold across all browsers, so I have to use the data attribute.
Now the function I have so far is this:
getTextContentXBrowser: function(nodeIn) {
// Currently goes down two levels. Need to abstract further to handle arbitrary number of levels
var tempString = '';
for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
if (nodeIn.childNodes[i].firstChild !== null) {
tempString += nodeIn.childNodes[i].firstChild.data;
} else {
if (nodeIn.childNodes[i].data && nodeIn.childNodes[i].data !== '\n') {
tempString += nodeIn.childNodes[i].data;
}
}
}
return tempString;
},
It's written in object notation, but otherwise it's a pretty standard unremarkable function. It goes down two levels, which is almost good enough for what I want to do, but I want to "set it and forget it" if possible.
I've been at it for four hours and I haven't been able to abstract this to an arbitrary number of levels. Is recursion even my best choice here? Am I missing a better option? How would I convert the above function to recurse?
Thanks for any help!
Update: I rewrote it per dsfq's model, but for some reason, it goes one level down and is unable to go back up afterwards. I realized that my problem previously was that I wasn't concatenating in the second if clause, but this seems to have stopped me short of the goal. Here is my updated function:
getTextContentXBrowser: function(nodeIn) {
var tempString = '';
for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
if (nodeIn.childNodes[i].data) {
tempString += nodeIn.childNodes[i].data;
} else if (nodeIn.childNodes[i].firstChild) {
tempString += this.getTextContentXBrowser(nodeIn.childNodes[i]);
}
}
return tempString.replace(/ /g,'').replace(/\n/g,'');
},
Anyone see what I'm missing?
Have you considered doing this with jQuery?
getTextContentXBrowser: function(nodeIn) {
return $(nodeIn).text();
}
As simple as that!
It can be really simple function calling itself to to replace nodes with its contents. For example:
function flatten(node) {
for (var c = node.childNodes, i = c.length; i--;) {
if (c[i].nodeType == 1) {
c[i].parentNode.replaceChild(document.createTextNode(flatten(c[i]).innerHTML), c[i]);
}
}
}
Looks like in your case you getTextContentXBrowser is a method of some object, so you will need to call it from inside itself properly (in my example I just use function).
Demo: http://jsfiddle.net/7tyYA/
Note that this function replaces nodes with a text in place. If you want a function that just returns a text without modifying actual node right away consider this example with another version of the script:
Demo 2: http://jsfiddle.net/7tyYA/1/

Get all files for all .uploadedFiles

Im looking for a javascript/jquery (doesn't matter which way) to collect all the files i've uploaded.
I have the following code, where .afbeelding is the class for a couple of file input fields
var geuploadeAfbeeldingen = $('.afbeeldingen').files;
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
}
This somehow doesnt seem to work. When i try document.getElementsByClassName it also doesn't work. The funny thing however is, that document.getElementById seem to work on one input field
Any ideas?
This should do what you want
var files = [],
geuploadeAfbeeldingen = $('.afbeeldingen').each(function(){
for (var i = 0; i < this.files.length; i++){
files.push(this.files[i]);
}
});
You end up with an array (files) that holds each file you have selected through the input elements..
Demo at http://jsfiddle.net/gaby/GJW7Y/1/
If you only want the filenames then change
files.push(this.files[i]);
with
files.push(this.files[i].name);
Try this way :
var geuploadeAfbeeldingen = $('.afbeeldingen');
for (var i = 0; i < geuploadeAfbeeldingen.length; i++) {
alert(geuploadeAfbeeldingen[i].files[0].name);
}
This may help you.
Edit :
$('.afbeeldingen').files is not work and document.getElementById().files is worked because first one return JQuery object( array of objects) and second one return DOM object.The jQuery object (created by the $ method) is a wrapper around a DOM element or a set of DOM elements. The normal properties and methods are not available with JQuery object.
You need to loop through each input element and return the files property.
Something like this is probably the shortest way, using map to iterate through an array:
var geuploadeAfbeeldingen = $('.afbeeldingen').map(function(k, v) { return v.files[0]; }).get();

Javascript array in loop

I am trying to loop through all elements in an xml file with the name "playerhash" with javascript.
for(var i = 0; i < 4; i++) {
alert(i);
if(getCookie('riskinfo') == xmldoc.getElementsByTagName("playerhash"[i].childNodes[0].nodeValue) {
player = xmldoc.getElementsByTagName("playerhash")[i].getAttribute('color');
break;
}
}
When I try to run the js it gives me Line 3: Uncaught TypeError: Cannot read property 'nodeValue' of undefined With the alert() function I figured out that the error is occurring when i = 0 and I know that there are at least four playerhash elements.
How can I loop through all of the elements without the error?
As deceze said, you have errors in the code. You should write your code in much smaller steps so that it is easier to debug. Also, check each step before proceeding so that if it fails unexpectedly, it will not throw errors at the user. Condition expresssions should not do assignment as that makes debugging more difficult, use them just for testing conditions:
// Should have already checked that xmldoc is a valid document
var riskinfo = getCookie('riskinfo');
var playerhash = xmldoc.getElementsByTagName("playerhash");
var max = 4; // or playerhash.length
var node, player;
for(var i = 0; i < max; i++) {
node = playerhash[i];
if (node && node.nodeValue == riskinfo) {
player = node.getAttribute('color');
i = max; // break out of for loop
}
}
.getElementsByTagName("playerhash"[i].childNodes[0].nodeValue)
You're missing a ) in there. Should be something along the lines of this:
if (getCookie('riskinfo') == xmldoc.getElementsByTagName("playerhash")[i].childNodes[0].nodeValue) {
Of course, repeating xmldoc.getElementsByTagName("playerhash") in every loop is rather expensive, you should do this once before the loop and save the result in a variable.
You should probably also check whether the ith element actually exists and whether it actually has any child nodes before trying to access that child node.

Categories

Resources