If for loop returns null javascript - javascript

I have a loop with inner if statements as follows
var html = "";
var i;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type == type)
{
html += '<p>hello world</p>';
}
}
I'd really like to be able to say if no results are returned from for loop, say "Sorry, no results were found" etc… I've tried the following… 
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type == type)
{
html += '<p>hello world</p>' +i;
}
}
But that just puts the object number next to the returned result…
Any help would be great as I'm sure this is very easy
Thanks

At the end check whether the html variable is actually filled, if not we didn't find any items and we can use the sorry message:
var html = '';
var i;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type === type)
{
html += '<p>hello world</p>';
}
}
if (html === '') { // or: "if (!html)" if you like that sort of thing
html = 'Sorry, no results were found'
}
Also notice that I changed the comparison from == to ===. That's because == tries to convert the type. While === does not. Use === to prevent strange errors, usually that's the one you want. For more info on it: Which equals operator (== vs ===) should be used in JavaScript comparisons?
Updated because of comment by #ASDFGerte

Similar to shotor's answer, but a slightly different approach would be as follows:
var html = "";
var i;
var found = false;
for (i = 0; i < products.length; i++)
{
if(products[i].attrs.product_type === type)
{
html += '<p>hello world</p>' +i;
found = true;
}
}
if (found === false)
{
//do stuff here.
}

var html = "";
var i;
var hasResult = false;
for ( i = 0; i < products.length; i++ )
{
if( products[i].attrs.product_type == type )
{
html += '<p>hello world</p>';
hasResult = true;
}
}
if( !hasResult ){
html = "No match";
}

Related

Is there a way to get the Complete String using a portion of it using JavaScript?

In a GridView, the name of the table is getting generated dynamically. but it will have the dynamic Name with GridView ID gets appended.
something Like "w123443dsfnsbd32dkkd_GridView1". so first part will always keep changing whenever we reloads the grid. so I would like to get the name of the Grid with "_GridView1", with this I would like to fetch the complete Grid Name. So Is there a way to look for this?
I tried this var table = document.getElementById("GridView1"); but didn't work.
Code:
var table = document.getElementById("wcwidget_df5339c463eedb_widget_gridView1");
if (table.rows.length > 0) {
for (var i = 0 ; i < table.rows.length; ++i) {
if (table.rows[i].cells[0].innerText == "Company1" || table.rows[i].cells[0].innerText == "Company2" ||
table.rows[i].cells[0].innerText == "Company5" )
{
for (var k = 1; k < table.rows[i].cells.length; ++k) {
table.rows[i].cells[k].style.fontWeight = "bold";
table.rows[i].cells[k].style.color = "black";
}
}
}
for (var i = 0 ; i < table.rows.length; ++i) {
if (table.rows[i].cells[0].innerText == "Risk" || table.rows[i].cells[0].innerText == "Medium Risk" || table.rows[i].cells[0].innerText == "High Risk" ) {
table.rows[i].cells[0].style.fontWeight = "bold";
table.rows[i].cells[0].style.color = "black";
}
}
}
try this:
document.querySelectorAll("[id*='GridView1']")
this will return an array.
On modern browsers see the #amit's answer.
If compatibility with older browsers is required:
var allElements = document.getElementsByTagName("*");
for (var i = 0, n = allElements.length; i < n; ++i) {
var element = allElements[i];
if (element.id.endsWith("_GridView1")) {
// do something with the found element
break;
}
}

JavaScript loop through to check duplicate value

I am having troubles trying to check if the date exists in the array.
for(var i = 0; i< crisislist.length; i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}
The sample data for the date is:
["01-02-2017", "22-03-2017", "22-03-2017", "07-08-2017"]
And the expected output for hazelabel, hazedata should be:
hazelabel: ["01-02-2017", "22-03-2017", "07-08-2017"]
hazedata: [1,2,1]
With the code above, when I check until the last element in the array and trying to make a comparison, it throw me an error message:
Uncaught TypeError: Cannot read property 'date' of undefined
I think this is because when I reach the last element of array, and I try to find crisislist[I+1].date, it could not found and thus the error message.
Any idea how to fix this? Thanks in advance!
You must access crisislist[i+1].date only when i doesn't point to the last element.
Also notice that to get the desired result, you need to move the hazedata.push inside the if block and put the initialisation of hazecounter in front of the loop.
var hazecounter = 1;
for (var i = 0; i< crisislist.length; i++) {
if (crisislist[i].category == 1) {
if (i == crisislist.length-1 || crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
hazedata.push(hazecounter);
hazeCounter = 1;
} else {
hazecounter++;
}
}
}
Your if statement is going to be a problem.
if(crisislist[i].date != crisislist[i+1].date) {
You are accessing crisislist[i+1] in a loop that goes to < crisislist.length. That means that if you have an array of size 4, your loop will go until i = 3, but you are accessing i+1 from the array (crisislist[4]), which will be undefined.
Try changing your for loop to go to crisis.length-1
You just need to check till second last :
for(var i = 0; i< (crisislist.length-1); i++){
hazecounter = 1;
if(crisislist[i].category == 1){
if(crisislist[i].date != crisislist[i+1].date) {
hazelabel.push(crisislist[i].date);
if (crisislist.length-2 == i)
{
hazelabel.push(crisislist[i+1].date);
}
}else{
hazecounter++;
}
hazedata.push(hazecounter);
}
}
Check that code. If you have any questions, add a comment :) In my solution dates dont have to be sorted.
</head>
<BODY>
<script>
function Something(date)
{
this.date = date;
this.category = 1;
}
var crisislist = [];
var hazelabel = [];
var hazedata = [];
crisislist[0] = new Something("01-02-2017");
crisislist[1] = new Something("22-03-2017");
crisislist[2] = new Something("22-03-2017");
crisislist[3] = new Something("07-08-2017");
for(var i = 0; i< crisislist.length; i++){
if(crisislist[i].category == 1)
{
if(!hazelabel[crisislist[i].date])
{
hazelabel[crisislist[i].date] = crisislist[i].date;
hazedata[crisislist[i].date] = 1;
}
else
{
hazedata[crisislist[i].date]++;
}
}
}
for(var key in hazelabel)
{
console.log(hazelabel[key]);
console.log(hazedata[key]);
}
</script>
</BODY>
</HTML>

Does not execute the code after a for within a function

Good! I have a problem and you do not run my code at the end of the loop, the above and what is inside the loop works fine, the problem is that after the loop is still not executing the code. Any idea why it can be?
This is my code:
var arrayp = new Array();
function botonAdelante(tabl, pasos)
{
var padreTabla = document.getElementById(tabl).rows;
var cont = 0;
for(var j = 0; j < padreTabla.length; j++)
{
var hijoTd = document.getElementById(pasos+ "-producto-" +j);
var childArray = hijoTd.children;
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}
}
alert("It is in this part of the code does not work");
}
Clarification: "continue" found at the end of long and if it will not work either.
The continue is confusing used like this, but I have a feeling your code is probably throwing an error because the cont might exceed the array length. Regardless of whether this fixes it or not I'd at least add a check to ensure that it doesn't throw an exception.
Please check for exceptions being thrown through web dev tools (F12 in Chrome).
for(var i = 0; i < childArray.length; i++)
{
var check = document.getElementById(pasos+ "-CheckBox-" +j);
if(check.type == 'checkbox' && check.checked==true && arrayp.length <= cont)
{
arrayp[cont] = check.value;
var algo = arrayp[cont];
alert(arrayp[cont]);
alert(arrayp);
cont++;
continue;
};
}

JavaScript - how to change elements of a string?

JS newbie here. I want to write a basic program that changes each element in a string based on a condition. If the letter is uppercase we swap it to lowercase, if the letter is already lowercase we swap it to uppercase. Why is this not working? Thanks!
function SwapCase(str){
for (var i = 0; i < str.length; i++) {
if (str.charAt(i)===str.charAt(i).toUpperCase()) {
str.charAt(i).toLowerCase();
} else{}
str.charAt(i).toUpperCase();
}
return str;
}
SwapCase("gEORGE");
Currently you do not write back your changes. You could, for example, do something like this:
function SwapCase(str){
var result = '';
for (var i = 0; i < str.length; i++) {
if (str.charAt(i)===str.charAt(i).toUpperCase()) {
result += str.charAt(i).toLowerCase();
} else{
result += str.charAt(i).toUpperCase();
}
}
return result;
}
function SwapCase(str){
var sReturn = "";
for (var i = 0; i < str.length; i++) {
if (str.charAt(i)===str.charAt(i).toUpperCase()) {
sReturn += str.charAt(i).toLowerCase();
} else{
sReturn += str.charAt(i).toUpperCase();
}
}
return sReturn;
}
Doing the same thing with String Prototyping and some shorthand notation.
String.prototype.swapCase = function(){
var returnString = '';
for (var i = 0; i < this.length; i++) {
returnString += (this[i]===this[i].toUpperCase())
? this[i].toLowerCase()
: this[i].toUpperCase();
}
return returnString;
};
console.log("Hallo".swapCase());

getElementsByClassName IE resolution issue

I am having issues figuring out how to resolve the getElementsByClassName issue in IE. How would I best implement the robert nyman (can't post the link to it since my rep is only 1) resolution into my code? Or would a jquery resolution be better? my code is
function showDesc(name) {
var e = document.getElementById(name);
//Get a list of elements that have a class name of service selected
var list = document.getElementsByClassName("description show");
//Loop through those items
for (var i = 0; i < list.length; ++i) {
//Reset all class names to description
list[i].className = "description";
}
if (e.className == "description"){
//Set the css class for the clicked element
e.className += " show";
}
else{
if (e.className == "description show"){
return;
}
}}
and I am using it on this page dev.msmnet.com/services/practice-management to show/hide the description for each service (works in Chrome and FF). Any tips would be greatly appreciated.
I was curious to see what a jQuery version of your function would look like, so I came up with this:
function showDesc(name) {
var e = $("#" + name);
$(".description.show").removeClass("show");
if(e.attr("class") == "description") {
e.addClass("show");
} else if(e.hasClass("description") && e.hasClass("show")) {
return;
}
}
This should support multiple classes.
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
if ((' ' + elements[i].className + ' ').indexOf(findClass) > -1) {
matching.push(elements[i]);
}
}
return matching;
}
You can pass in a parent too, to make its searching the DOM a bit faster.
If you want getElementsByClassName('a c') to match HTML <div class="a b c" /> then try changing it like so...
var elementClasses = elements[i].className.split(/\s+/),
matchClasses = findClass.split(/\s+/), // Do this out of the loop :)
found = 0;
for (var j = 0, elementClassesLength = elementClasses.length; j < elementClassesLength; j++) {
if (matchClasses.indexOf(elementClasses[j]) > -1) {
found++;
}
}
if (found == matchClasses.length) {
// Push onto matching array
}
If you want this function to only be available if it doesn't already exist, wrap its definition with
if (typeof document.getElementsByClassName != 'function') { }
Even easier jQuery solution:
$('.service').click( function() {
var id = "#" + $(this).attr('id') + 'rt';
$('.description').not(id).hide();
$( id ).show();
}
Why bother with a show class if you are using jQuery?
Heres one I put together, reliable and possibly the fastest. Should work in any situation.
function $class(className) {
var children = document.getElementsByTagName('*') || document.all;
var i = children.length, e = [];
while (i--) {
var classNames = children[i].className.split(' ');
var j = classNames.length;
while (j--) {
if (classNames[j] == className) {
e.push(children[i]);
break;
}
}
}
return e;
}
I used to implement HTMLElement.getElementByClassName(), but at least Firefox and Chrome, only find the half of the elements when those elements are a lot, instead I use something like (actually it is a larger function):
getElmByClass(clm, parent){
// clm: Array of classes
if(typeof clm == "string"){ clm = [clm] }
var i, m = [], bcl, re, rm;
if (document.evaluate) { // Non MSIE browsers
v = "";
for(i=0; i < clm.length; i++){
v += "[contains(concat(' ', #"+clc+", ' '), ' " + base[i] + " ')]";
}
c = document.evaluate("./"+"/"+"*" + v, parent, null, 5, null);
while ((node = c.iterateNext())) {
m.push(node);
}
}else{ // MSIE which doesn't understand XPATH
v = elm.getElementsByTagName('*');
bcl = "";
for(i=0; i < clm.length; i++){
bcl += (i)? "|":"";
bcl += "\\b"+clm[i]+"\\b";
}
re = new RegExp(bcl, "gi");
for(i = 0; i < v.length; i++){
if(v.className){
rm = v[i].className.match(bcl);
if(rm && rm.length){ // sometimes .match returns an empty array so you cannot use just 'if(rm)'
m.push(v[i])
}
}
}
}
return m;
}
I think there would be a faster way to iterate without XPATH, because RegExp are slow (perhaps a function with .indexOf, it shuld be tested), but it is working well
You can replace getElementsByClassName() with the following:
function getbyclass(n){
var elements = document.getElementsByTagName("*");
var result = [];
for(z=0;z<elements.length;z++){
if(elements[z].getAttribute("class") == n){
result.push(elements[z]);
}
}
return result;
}
Then you can use it like this:
getbyclass("description") // Instead of document.getElementsByClassName("description")

Categories