Javascript inserting weird newLine character - javascript

I have an array named verses that contains strings created from an ajax response. The array is created like this:
verses.push(splitStr[i].replace('\n',''));
Later I create some <span> elements and append the values from the array. However the last element from array always has a strange behavior because it contains a hidden new line character in ASCII it has the code 10 (checked that in the console). Now when I print in the console log the last element from the array a get this result: "string". Then I create the span element that contains this string and later when I retrieve back the value from span I get:
"string
"
That's because when creating the span it always inserts this strange new line character. So in the source code the span looks like:
<span class="answer" onclick="checkAnswer(this)">potopului
</span>
You can see that the closing tag is on the next line.
In the console I used some break points and I got this value extracted from span: "string↵"
Now, has anyone any idea why when creating this span javascript inserts a new line character and why does it happen only with the last element from array?
The code used to create the span elements:
for (var i = 0; i < 3; i++) {
if (i!=phtml) {
tags.push("<span class='answer' onclick='checkAnswer(this)'>"+generateRandom(pos)+'</span>');
//generate a string from the array different from the one with position pos
}else{
tags.push("<span class='answer' onclick='checkAnswer(this)'>"+verses[pos].replace('\n','')+'</span>');
}
}
var output='';
for (var i = 0; i < tags.length; i++) {
output = output + tags[i];
}
document.getElementsByClassName('v-options')[0].innerHTML = output;
The checkAnswer() function:
function checkAnswer(e){
var text = e.innerHTML;
var input = document.getElementsByClassName('hidden-word')[pos];
if (text == verses[pos]) {
input.value = verses[pos];
input.setAttribute('disabled','');
}
console.log(":"+text.substring(0, text.length-1) + ":"+verses[pos]+":");
}

Sometimes line breaks are printed in different styles. Commonly it is a combination of two special characters \n and \r so you just need to check all possible types of newline combinations or their lost broken parts. Try to change your RegExp to match them all :
splitStr[i].replace(/\n\r|\n|\r/g, '')

Related

Javascript simple word counter

I am trying to make a simple word counter for a textarea element in Javascript. So far I have tried many methods but everyone fails in something. I searched the web but I only found solutions that use functions or JS commands and syntax that I still don't know. The goal is to count the words in a textarea that contains a maximum of 140 characters. The text can also be on more than one line so I have to consider the new line symbol.
Till now I wrote this:
for (let i = 0; i < text.length; i++) {
if (text[i]==' ' && (text[i-1]!==' ' && text[i-1]!=='\n')) {
wc++;
}
else if(text[i]=='\n' && text[i-1]!==' '){
wc++;
}
}
It kind of works but it counts only if after the word I press SPACE. Is there any way to start counting from when the user types just one letter?
EDIT:
I have already tried the .split(" ") method but it doesn't work with the ENTER/RETURN key. My goal is to start counting as soon as the user types a letter.
You can use split along with a regex for whitespace
let words = text.split(/\W/);
wc = words.length;
split breaks your string into an array, it creates a new entry to the array everytime it finds the expression you pass to it.
The regex /\W/ gets whitespaces (' ' and '\n')
So this way it would create an array with every word separated, and then you just need to check the length of the array
Added replace all multiple spaces with single space. Also added check if entered a new line.
document.getElementById("inputField").addEventListener("input", function(e) {
// Get the input text value
var text = this.value;
//replace all multiple spaces with single space
text = text.replace(/\s\s+/g, " ");
// Initialize the word counter
var wc = 0;
// Loop through the text
// and count spaces in it
for (let i = 0; i < text.length; i++) {
if (text[i]==' ' && (text[i-1]!==' ' && text[i-1]!=='\n')) {
wc++;
}
else if(text[i]=='\n' && text[i-1]!==' '){
wc++;
}
}
// Display it as output
document.getElementById("show").innerHTML = wc;
})
<textarea id="inputField" rows=10 cols="60">
</textarea>
<br><br>
<p> Word Count:
<span id="show">0</span>
</p>

Create a text area and analyze button

I am working on my college homework. I am having a lot of difficulty with it and getting stuck. My class mates are not helping me and the instructor hasn't responded. I am hoping I might get some help/understanding here. The current assignment I am working on and it is due today is:
Create a page containing a textarea and an “analyze” button. The results area will display the frequency of words of x characters. For example, the text “one two three” contains 2 3-character words and 1 5-character word. An improvement to the original design would be to strip out any extraneous characters that may skew the count.
I am just starting it now, so I will add the code here as I update. I know I won't have a problem with the HTML part, the JavaScript will be my problem. From what I get, I will need to have a function that counts the words and the characters in each word. But it needs to exclude spaces and characters like: ,.';/. I have not run across this code before, so any input on how I should frame the javascript will be helpful. Also it seems he wants me to list how many words have the same characters? am I reading this right?
My code thus far:
<!DOCTYPE html>
<html>
<body>
<textarea id="txtarea">
</textarea>
<input type="button" id="analyze" value="Analyze" onclick="myFunction()" />
<p id="demo"></p>
<p id="wcnt"></p>
<script>
function myFunction() {
var str = document.getElementById("txtarea").value;
var res = str.split(/[\s\/\.;,\-0-9]/);
var n = str.length;
document.getElementById("demo").innerHTML = "There are " + n + " characters in the text area.";
for (var i = 0; i < res.length; i++) {
s = document.getElementById("txtarea").value;
s = s.replace(/(^\s*)|(\s*$)/gi, "");
s = s.replace(/[ ]{2,}/gi, " ");
s = s.replace(/\n /, "\n");
document.getElementById("wcnt").innerHTML = "There are " + s.split(' ').length + " words in the text area.";
}
}
</script>
</body>
</html>
Now I need to figure out how to make it count the characters of each word then output how many words have x amount of characters. Such as 5 words have 4 characters and so on. Any suggestions?
var textarea = document.getElementById("textarea"),
result = {}; // object Literal to hold "word":NumberOfOccurrences
function analyzeFrequency() {
// Match/extract words (accounting for apostrophes)
var words = textarea.value.match(/[\w']+/g); // Array of words
// Loop words Array
for(var i=0; i<words.length; i++) {
var word = words[i];
// Increment if exists OR assign value of 1
result[word] = ++result[word] || 1;
}
console.log( result );
}
analyzeFrequency(); // TODO: Do this on some button click
<textarea id="textarea">
I am working on my college-homework.
Homework I am having a lot of difficulty with it and getting stuck.
My class mates are not helping me and the instructor hasn't responded.
I am hoping I might get some help/understanding here.
</textarea>
Notice how Homework and homework (lowercase) are registered as two different words, I'll leave it to you to fix that - if necessary and implement the analyzeFrequency() trigger on some button click.
Most likely you will have to use JavaScript's split function with regex to define all the characters you do not want to include. Then loop through the resulting array and count the characters in each word.
var words = document.getElementById("words");
var analyze = document.getElementById("analyze");
analyze.addEventListener("click", function(e) {
var str = words.value;
var res = str.split(/[\s\/\.;,\-0-9]/);
for(var i = 0; i < res.length; i++) {
alert(res[i].length);
}
});
<textarea id="words">This is a test of this word counter thing.</textarea>
<br/>
<button id="analyze">
Analyze
</button>
Your instructor does NOT want you to list how may words have the same characters but rather the same number of characters. The basic algorithm:
Assign the value of the text area to a variable.
Convert that string value into an array. In javascript this could be accomplished with the String split method using a regular expression containing a character class.
Iterate over that array examining each element for its length. For each element, increment a counting object's property whose property name is the length of the element.
Iterate over the counting object's property list. Output to the result area each property name and its value.

Split a string of HTML into an array by particular tags

Given this HTML as a string "html", how can I split it into an array where each header <h marks the start of an element?
Begin with this:
<h1>A</h1>
<h2>B</h2>
<p>Foobar</p>
<h3>C</h3>
Result:
["<h1>A</h1>", "<h2>B</h2><p>Foobar</p>", "<h3>C</h3>"]
What I've tried:
I wanted to use Array.split() with a regex, but the result splits each <h into its own element. I need to figure out how to capture from the start of one <h until the next <h. Then include the first one but exclude the second one.
var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>';
var foo = html.split(/(<h)/);
Edit: Regex is not a requirement in anyway, it's just the only solution that I thought would work for generally splitting HTML strings in this way.
In your example you can use:
/
<h // Match literal <h
(.) // Match any character and save in a group
> // Match literal <
.*? // Match any character zero or more times, non greedy
<\/h // Match literal </h
\1 // Match what previous grouped in (.)
> // Match literal >
/g
var str = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>'
str.match(/<h(.)>.*?<\/h\1>/g); // ["<h1>A</h1>", "<h2>B</h2>", "<h3>C</h3>"]
But please don't parse HTML with regexp, read RegEx match open tags except XHTML self-contained tags
From the comments to the question, this seems to be the task:
I'm taking dynamic markdown that I'm scraping from GitHub. Then I want to render it to HTML, but wrap every title element in a ReactJS <WayPoint> component.
The following is a completely library-agnostic, DOM-API based solution.
function waypointify(html) {
var div = document.createElement("div"), nodes;
// parse HTML and convert into an array (instead of NodeList)
div.innerHTML = html;
nodes = [].slice.call(div.childNodes);
// add <waypoint> elements and distribute nodes by headings
div.innerHTML = "";
nodes.forEach(function (node) {
if (!div.lastChild || /^h[1-6]$/i.test(node.nodeName)) {
div.appendChild( document.createElement("waypoint") );
}
div.lastChild.appendChild(node);
});
return div.innerHTML;
}
Doing the same in a modern library with less lines of code is absolutely possible, see it as a challenge.
This is what it produces with your sample input:
<waypoint><h1>A</h1></waypoint>
<waypoint><h2>B</h2><p>Foobar</p></waypoint>
<waypoint><h3>C</h3></waypoint>
I'm sure someone could reduce the for loop to put the angle brackets back in but this is how I'd do it.
var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>';
//split on ><
var arr = html.split(/></g);
//split removes the >< so we need to determine where to put them back in.
for(var i = 0; i < arr.length; i++){
if(arr[i].substring(0, 1) != '<'){
arr[i] = '<' + arr[i];
}
if(arr[i].slice(-1) != '>'){
arr[i] = arr[i] + '>';
}
}
Additionally, we could actually remove the first and last bracket, do the split and then replace the angle brackets to the whole thing.
var html = '<h1>A</h1><h2>B</h2><p>Foobar</p><h3>C</h3>';
//remove first and last characters
html = html.substring(1, html.length-1);
//do the split on ><
var arr = html.split(/></g);
//add the brackets back in
for(var i = 0; i < arr.length; i++){
arr[i] = '<' + arr[i] + '>';
}
Oh, of course this will fail with elements that have no content.
Hi I used this function to convert html String Dom in array
static getArrayTagsHtmlString(str){
let htmlSplit = str.split(">")
let arrayElements = []
let nodeElement =""
htmlSplit.forEach((element)=>{
if (element.includes("<")) {
nodeElement = element+">"
}else{
nodeElement = element
}
arrayElements.push(nodeElement)
})
return arrayElements
}
Happy code

Checking innerHTML values if empty or not for Array of Object

I am trying to check if below condition holds true:
var elemArray = document.getElementsByClassName('customers');
for(var i = 0; i < elemArray.length; i++){
elemArray[i].id = i;
var elem = document.getElementById(elemArray[i].id);
var text = elem.innerHTML;
text = text.toString();
alert(text);
if(text=="<br>"){
alert('bingo');
elem.style.visibility="hidden";
}
}
In the 1st alert I can see values as
1. <br>ABC
2. <br>XYZ
and for empty values I get:
1. <br>
2. <br>
so I am trying to compare it but "bingo" is not showing. What is it that I am missing?
Looks like you have either special characters or spaces in the content. Remember == compares exact strings. i.e. '<br>' and '<br> ' are different.
Here is a working jsfiddle for and it prints bingo just fine.
http://jsfiddle.net/1nxzxjdd/
Some answers mention using indexOf or contains method which might not be useful to OPs question because it looks like OP is interested in finding out values containing only <br>

Regular expression subgroups inside groups and the way to reference them

I'm trying to parse a document structure like this:
Headline
c=myClass1 myClass2 myClass3
Some text plus a number3gr
More text plus another number2cm
More text plus another number2.2m
I have a regular expression that is capturing the important parts into groups:
/(.*)[\r\n]c=(.*)[\r\n]*([a-zA-Z\s]*)(\d*\.?\d*)(\w*)[\r\n]/g
Later I'm using the groups to build a html-string:
'<xmp><!--begin recipe--\><h2>$1</h2><div class="$2"><div class="serves">Serves: <input type="text" class="servesinput" value="2" size="3"></div><span class="oldMulti">2</span></br><table class="ingredients"><tr><th>Amount:</th><th>Ingredient:</th></tr><tr><td class="amount $5 ">$4</td><td>$3</td></tr></div></xmp>'
This is where I am stuck: after the empty line, there can be any number of lines like these:
Some text plus a number3gr
Is there a way to re-use this part of my reg exp as many times as necessary (as many times as there are those type of rows):
([a-zA-Z\s]*)(\d*\.?\d*)(\w*)[\r\n]
Maybe I can make use of subgroups? But then I have no idea how to repeat the results inside the html-string.
For information on capturing a repeated group: http://www.regular-expressions.info/captureall.html
For a more efficient way, I'd try parsing the file line by line manually, since regular expressions can be quite inefficient.
Once you have the text (see here for example:)
How can you read a file line by line in JavaScript?
I would split into lines (an array) per the example and iterate through them in a for loop.
var headline = "";
var classes = [];
var lineList = [];
var line;
var count = 0;
headline = lines[0];
classes = lines[1].split(" ");
classes[0] = classes[0].substring(2); // cut off "c=" in first token
for (line in lines) {
if (count > 2) {
// line is after the blank line
// do something
}
count += 1;
}

Categories

Resources