Storing for loop result to push into HTML - javascript

EDIT: Solved. After the helpful people here helped me solve this I realised this issue was to do with my getElementsByClassName selector. Sorry if the title is misleading. The original question is below.
I am getting the expected results from this function's for loop, but I can't get them to print to the HTML.
Could anybody help point out what I'm missing? A point in the right direction would do, I can do some legwork myself.
Any advice is much appreciated.
HTML:
<input type="text" name="searchString" class="searchString">
<span class="longestWordInput"></span>
<span class="longestWordCountInput"></span>
<button class="generate">Generate</button>
JavaScript:
function longestWordFunc() {
var stringSplit = document.querySelector(".searchString").value.split(" ");
let longestWordCount = 0;
let longestWord = "";
for(var i = 0; i < stringSplit.length; i++) {
if(stringSplit[i].length > longestWordCount) {
longestWordCount = stringSplit[i].length;
longestWord = stringSplit[i]
}
}
//Logging expected result
console.log(longestWordCount)
console.log(longestWord)
//Print to HTML not working
document.getElementsByClassName("longestWordInput").innerHTML = longestWord;
document.getElementsByClassName("longestWordCountInput").innerHTML = longestWordCount;
};
document.querySelector(".generate").addEventListener("click", longestWordFunc);

The problem is that getElementsByClassName() returns a NodeList (an array-like structure containing all elements with the specified class name) instead of a single element.
You can access your single span element like this
document.getElementsByClassName("longestWordInput")[0].innerHTML = longestWord;
or you could use querySelector() instead
document.querySelector(".longestWordInput").innerHTML = longestWord;

Hi I believe you need to use getElementsByClassName like the below
document.getElementsByClassName("longestWordInput")[0].innerHTML = longestWord;
document.getElementsByClassName("longestWordCountInput")[0].innerHTML = longestWordCount;

Related

Newbie> How can I search and array for a promted word<

I am trying to learn JS and found this "test" but cant figure it out.
I have an array and I need to search through if there are words that start with "syn". I tried few options but nothing worked for me. This I think is the closest Ive got but it still returns empty array. I just needs to be from the start of the word(not in the middle). Can someone please help me?
const data = [
'Synáček',
'Alois, synové a bratři',
'Autosynchro',
'Sy-noid',
'Brak a synopie',
'Brambory',
'Syntetika'
];
let vyraz = prompt('Výraz', null);
var hledat = [];
for (var i = 0; i < data.lenght; i++) {
if (data.lowerCase[i].includes == vyraz.lowerCase) {
hledat.push(data[i])
}
};
console.log(hledat);
You have some errors in your code. This is how it should be:
for (var i = 0; i < data.length; i++) {
if (data[i].toLowerCase().startsWith(vyraz.toLowerCase())){
hledat.push(data[i])
}
};
console.log(hledat);
Note that you had a typo in data.length. Also the method to transform to lower case is toLowerCase instead of lowerCase and you forgot the parenthesis after the function calls. includes is a method not a property so using it like someString.includes == something is not correct. Also in data.lowerCase[i] the array index must come after the array like in data[i].toLowerCase().
You could use .filter() method with a regex.
const data = [
'Synáček',
'Alois, synové a bratři',
'Autosynchro',
'Sy-noid',
'Brak a synopie',
'Brambory',
'Syntetika'
];
const result = data.filter(item => item.toLowerCase().match(/^syn|\ssyn/));
console.log(result);

getElementsByClassName isn't returning all elements

I'm creating a button that I should highlight certain words within a specified class, but I am having issues with it returning all elements within the class. It will only work if I specify an index, so I'm assuming there may be something wrong with the existing "for loop". Any help is appreciated!
This will work, but only "highlights" the first element in the class, of course:
var bodyText = document.getElementsByClassName('test')[0].innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test')[0].innerHTML = bodyText;
return true;
This will not work at all:
var bodyText = document.getElementsByClassName('test').innerHTML;
for (var i = 0; i < searchArray.length; i++) {
bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag,
highlightEndTag);}
document.getElementsByClassName('test').innerHTML = bodyText;
return true;
If you want to replace multiple words in multiple elements, you need two loops:
const testElements = document.getElementsByClassName('test');
for (const element of testElements) {
for (const search of searchArray) {
element.innerHTML = doHighlight(element.innerHTML, search, highlightStartTag, highlightEndTag);
}
}
As you can see getElementsByClassName is pluralized (Elements). Indeed a same class can be assigned to multiple HTML elements. You won't find any way to ommit the [0] and you shouldn't anyway as it might mean you're getting data from the wrong node. If you need data from a specific element that you can ensure is unique then you need to give it an id and use getElementById instead.
You cannot access innerHTML in something which returns an htmlcollection
document.getElementsByClassName('test').innerHTML
Because it's written in plain english: getElementsByClassName. plural.
"Elements".
with an "s" at the end...
meaning it's a (sort of) Array (an htmlcollection)

getElementById(...) returns null unexpectedly

EDITED: I pretty much checked dozens of articles here on this issue, but I simply can't find the problem in my code: The line (commented below) returns null, although I expect it to return the particular element I created and added above.
element2 = document.createElement("button");
element2.innerHTML = "-";
element2.text = rowCounter;
element2.style.backgroundColor = 'white';
element2.id = "kuerzer"+rowCounter; //rowCounter is an iterator variable
ell2.appendChild(element2);
console.log(document.getElementById(element2.id)); //returns null
However, I am now trying to find this element in another function like this:
function structureGantData(){
var gantData = [[]];
for(i=0; i<document.getElementById("myTable").rows.length; i++){
console.log("schleife");
gantData[i][0] = document.getElementById("kuerzer",(i+1)).text; //ISSUE
Could anyone help me? :-)
Thanks alot!
Fabian
You have not added the created element to the DOM, so it cannot be found there.
You may use say Node.appendChild (or any other similar) method to append it somewhere first.
I believe you meant to call document.getElementById("kuerzer" + (i + 1)) rather than document.getElementById("kuerzer", i + 1) in structureGantData.

Combining getElementsByTagName and getElementsByClassName

I'm trying to combine getElementsByTagName and getElementsByClassName to narrow a search down and count the resulting nodes, but the second search always results in a length of 0, and I've no idea why.
<!DOCTYPE html>
<html>
<head></head>
<body>
<p>Stuff</p>
<p class="content">Stuff2</p>
<p>Stuff</p>
<p class="content">Stuff2</p>
<script type="text/javascript">
pElements = document.getElementsByTagName("p");
console.log(pElements);
for(i = 0; i < pElements.length; i++) {
console.log(pElements[i].getElementsByClassName("content").length);
}
//console.log(document.querySelectorAll('p.content').length);
</script>
</body>
</html>
I know I can use querySelectorAll for this like the line I have commented out, but I'd like to understand why the first solution isn't working, and what I can do to fix it.
Thanks!
The problem with the first example is that:
pElements[i].getElementsByClassName("content")
searches for children of the p element. But since it is actually on the same element, they are not found.
W3C reference:
"The getElementsByClassName() method returns a collection of an element's child elements with the specified class name"
EDIT: To find if a p element has the content class, instead of getElementsByClassName(), you could use
pElements[i].classList.contains("content")
which will return true if the element has the class. Reference
EDIT2: A more backwards-compatible way would be to get the className property, split it on spaces and iterate the array to see if the class is there.
var names = pElements[i].className.split(" ");
var found = false;
for(var i = 0; i < names.length; i++){
if(names[i] === "content"){
found = true;
break;
}
}
if(found){
//Your code here
}
You can NOT combine getElementsByTagName and getElementsByClassName. Because as mentioned by #juunas, pElements now consists of the result consisting of an array of all the <p> elements.
And when you apply the getElementsByClassName to this result-set, using pElements[i].getElementsByClassName("content"), it searches in the child elements of pElements.
Suggestive Result :
Use the getAttribute() function to check the class of each element in pElements, like,
pElements = document.getElementsByTagName("p");
console.log(pElements);
for(var i = 0, j = 0; i < pElements.length; i++) {
if (pElements[i].getAttribute("class") === "content") {
j++;
}
}
console.log("Length of the resulting nodes: ", j);
It's because your p-elements dont have any elements with the class "content". The p-elements itself have this class, so you cant find it and 0 is correct.
Change
<p class="content">Stuff2</p>
To
<p><span class="content">Stuff2</span></p>
And you will get 1 as the result.

Javascript search for tag and get it's innerHTML

It's probably something really simple, but I'm just learning.
There's a page with 3 blockquote tags on it, and I'd need to get the innerHTML of the one containing a certain string. I don't know how to search/match a string and get the innerHTML of the tag containing the matched result.
Any help would be appreciated!
var searchString = 'The stuff in innerHTML';
var elements = document.getElementsByTagName('blockquote')
for (var i = 0; i < elements.length; i++) {
if (elements[i].innerHTML.indexOf(searchString) !== -1) {
alert('Match');
break;
}
}
:)
Btw there would be a much nicer method if you'd be using Prorotype JS (which is much better than jQuery btw):
var el = $$('blockquote').find(function(el) {
return el.innerHTML.indexOf('The string you are looking for.') !== -1;
});
You could of course also use regular expressions to find the string, which might be more useful (use el.match() for that).
If you need to search through every <blockquote> on the page, try this:
function findBlockquoteContainingHtml(matchString) {
var blockquoteElements = document.getElementsByTagName('BLOCKQUOTE');
var i;
for (i = 0; i < blockquoteElements.length; i++) {
if (blockquoteElements[i].innerHTML.indexOf(matchString) >= 0) {
return blockquoteElements[i].innerHTML;
}
}
return null;
}
Assign an id to the blockquote elements then you can get the innerHTML like this:
HTML:
<blockquote id="bq1">Foo</blockquote>
JS:
var quote1 = document.getElementById('bq1').innerHTML;
Be careful using innerHTML to search for text within a tag, as that may also search for text in attributes or tags as well.
You can find all blockquote elements using:
var elems = document.getElementsByTagName("blockquote")
You can then look through their innerHTML, but I would recommend instead looking through their textContent/innerText (sadly, this is not standardized across browser, it seems):
for (i in elems) {
var text = elems[i].textContent || elems[i].innerText;
if (text.match(/foo/)) {
alert(elems[i].innerHTML);
}
}

Categories

Resources