Function for counting characters/words not working - javascript

<!DOCTYPE HTML>
<html>
<head>
<title> Javascript - stuff </title>
<script type="text/javascript">
<!--
function GetCountsAll( Wordcount, Sentancecount, Clausecount, Charactercount )
{
var TextString = document.getElementById("Text").innerHTML;
var Wordcount = 0;
var Sentancecount = 0;
var Clausecount = 0;
var Charactercount = 0;
// For loop that runs through all characters incrementing the variable(s) value each iteration
for (i=0; i < TextString.length; i++);
if (TextString.charAt(i) == " " = true)
Wordcount++;
return Wordcount;
if (TextString.charAt(i) = "." = true)
Sentancecount++;
Clausecount++;
return Sentancecount;
if (TextString.charAt(i) = ";" = true)
Clausecount++;
return Clausecount;
}
-->
</script>
</head>
<body>
<div id="Text">
It is important to remember that XHTML is a markup language; it is not a programming language. The language only describes the placement and visual appearance of elements arranged on a page; it does not permit users to manipulate these elements to change their placement or appearance, or to perform any "processing" on the text or graphics to change their content in response to user needs. For many Web pages this lack of processing capability is not a great drawback; the pages are simply displays of static, unchanging, information for which no manipulation by the user is required. Still, there are cases where the ability to respond to user actions and the availability of processing methods can be a great asset. This is where JavaScript enters the picture.
</div>
<input type = "button" value = "Get Counts" class = "btnstyle" onclick = "GetCountsAll()"/>
<br/>
<span id= "Charactercount"> </span> Characters <br/>
<span id= "Wordcount"> </span> Words <br/>
<span id= "Sentancecount"> </span> Sentences <br/>
<span id= "ClauseCount"> </span> Clauses <br/>
</body>
</html>
I am a student and still learning JavaScript, so excuse any horrible mistakes. The script is meant to calculate the number of characters, words, sentences, and clauses in the passage. It's, plainly put, just not working. I have tried a multitude of things to get it to work for me and have gotten a plethora of different errors but no matter what I can NOT get this to work. Please help! (btw i know i misspelled sentence)

Remove the semicolon from for (i=0; i < TextString.length; i++);. This breaks out of the loop.
Put brackets {} around
Sentancecount++;
Clausecount++; so they are incremented each time the full stop is seen. Currently only Sentance is incremented each time. Clause is incremented at the end of the text.
I would also use brackets generally after ifs. It makes for readability and you can see what the code is doing if you can read it easily.
Next, you can only have want one return from the method. Have the first method call the secondary ones if that makes sense. Set it so you get some variables being given values, and then print them out.
hth

You could use the split method of the string. Like this:
WordCount = TextString.split(' ').length;
Sentancecount = TextString.split('.').length;
Clausecount = TextString.split(';').length;
Charactercount = TextString.length;
This way, you don't need the for loop anymore.

Well, you have several issues here.
First, you want your for loops to have braces around the code you want to execute on each iteration.
for (i=0; i < TextString.length; i++) {
if (TextString.charAt(i) == " " = true)
Wordcount++;
}
(I'm assuming WordCount is supposed to be outside the loop (but it's incorrect either way))
Next, you're not handling those return values.
The way return works is that you can set a variable to the result of the function.
For example:
function x() {
return 2;
}
var i = 1;
var q = i + x(); // Add the result of the function to i
alert(q); // This will display 3
So by calling return, you're sending that value back to where the function was called, but you're never using it.
Also, calling return immediately exits the function. You do not want this if you want to continue processing. I suggest that you create variables for each of the three values and store the results to that. Then after your processing in the script, you can the innerHTML of a div to the them.
Here's an example that may help you:
<html>
<head>
<title>Example Javascript</title>
<script type="text/javascript">
function myFunction()
{
var text = Array(8).join(parseInt('')) + ' Batman!';
var element = document.getElementById("result");
element.innerHTML = text;
}
</script>
</head>
<body>
The output from our function is: <div id="result"> </div>
<br />
<button type="button" onclick="myFunction()">Run</button>
</body>
</html>
I would like to note that there are some really simple ways to solve this, but this seems like homework or at least a learning experience which is why I'm setting you on the right path rather than just giving you a straight answer. You're close! My advice is to just keep at it!

Related

Is it possible to get a random sentence from a Google Sheet and showing it on my website when someone click a button?

I am at starting web dev, already using html/css.
For a little project, I had a look at JavaScript. (My goal is that when people click a button, the site will show a random sentence that will be taken from a google sheet cell.)
Could you tell me please if it is even possible? If so, please share some ideas that I will explore. If not, please give me some alternative ideas... Thanks so much.
Have a good day!
-LeganV9
This is possible using Google Apps Script!
I have a working demo here, with the source being here. I dare you to get the jackpot. :D
In order to make this, you can go to https://script.new. Now, in code.gs put this:
function doGet() {
return HtmlService.createTemplateFromFile("index").evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function getVals(){
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1IDbhQhaImcQB-4j-iByajwAkvxkutptcPMhMTxNrPtU/edit#gid=0");//Put your URL here
var sheet = ss.getSheetByName("Sheet1");//Put your sheet name here
var AMOUNT_OF_SENTENCES = sheet.getMaxRows().toString().replace(".0","");//You can replace this with a number eg 20
var range = sheet.getRange(1, 1,AMOUNT_OF_SENTENCES);
var values = range.getValues();
var newValues = [];
for(var i = 1; i<values.length;i++){
if(values[i][0] === "" || values[i][0] === " "){
}else{
newValues.push(values[i][0]);
}
}
return {valuesVar: newValues };
}
After that, create a new HTML file called "index" and put this in it:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>
The results are: <span id = "results">Loading...</span>
</h1>
<button id = "yourIdHere">Click me!!</button>
<script>
var yourDataList;
function onSuccess(data) {
yourDataList= data.valuesVar;
}
google.script.run.withSuccessHandler(onSuccess).getVals();
var myBtn = document.querySelector("#yourIdHere"); //Declare button, replace yourIdHere with your ID
var randomNum = 0; //Decclre random number
function getRandom() { //Declare your function
randomNum = parseInt(Math.random() * yourDataList.length); //Get random number between 0 and the length of your datalist
return yourDataList[randomNum]; //Return your value
}
myBtn.addEventListener("click", function() { //Bind a listener to the button
document.querySelector("#results").innerText = getRandom(); //Do whatever you want to with the random value
});
document.querySelector("#results").innerText = getRandom();//Change from loading...
</script>
</body>
</html>
Welcome to the world of web development! Hope your project is a success.
It should definitely be possible, since Google Sheets offers an API which has read/write functionality (https://developers.google.com/sheets/api).
You could even later extend this so people can submit their own sentences, given that writing to a Google Sheet is also possible with this API.
However, since you're starting out, consider treating this as an iterative process. You don't have to publish your first version, but just to prevent overwhelming yourself, you might want to set small milestones along the way - each adding more functionality. For example:
Create an array of random sentences (you could, for example, start with using this to keep it simple: https://github.com/JamesFT/Database-Quotes-JSON).
Select and log a random sentence to the console (console.log()) each time the script is executed.
Transfer the random sentence to render in HTML and allow a new sentence to be generated each time a button is pressed.
Move your sentences into a Google Sheet and begin exploring the API.
This way, you achieve something in a much shorter space of time, while working towards your end goal. It's a good way to keep motivated and make things more manageable.
Best of luck!

How to take the value of a variable to the paragraph tag?

I am having a problem to send the code to my <p> tag where am I going wrong?
<html>
<body>
<p id="100"> </p>
<script>
var dictionary
var lower
function start() {
var dictionary = "house";
lower = dictionary.toString().toLowerCase();
}
document.getElementById("100").innerHTML == document.getElementById([lower]).value
start()
</script>
</body>
</html>
What your script does is:
Try to get element with id "100" (btw. starting ids with a number is bad practice although it might work in some browsers — see What are valid values for the id attribute in HTML?). It might fail to detect the element, because of bad naming.
Expecting the element would have been found, you don’t assign the new innerHTML (which would work with a =), but make a comparison with a ==.
Then you try to find an element by [lower]. First, getElementById expects a string and second lower is undefined at this moment. It hasn’t been set yet. It will be set in the next line, where you execute start(). Also notice that only <p> does not have a value. In this case better go with innerText. If you just want the paragraph to show the value of lower, just assign lower like: document.getElementById("100").innerText = lower;
toString() is not needed if the argument is always a string. Then it would just be
var dictionary = "HouSe";
document.getElementById("a100").innerText = dictionary.toLowerCase();
A working example could be:
function toLowerCaseString(value) {
return value.toString().toLowerCase();
}
var dictionary = "HouSe";
document.getElementById("a100").innerText=toLowerCaseString(dictionary);
<html>
<body>
<p id="a100"></p>
</body>
</html>
remarks are in the comment in code snippet.
<html>
<body>
<p id="A100"> </p>
<script>
var dictionary,lower;
function start(){dictionary="house";
lower=dictionary.toString().toLowerCase();
//you need to return something for the function output to be consumed somewhere else
return lower;
}
//you use start output to render innerhtml
// you dont do another document.get because lower is not a dom element its is Js object and we have used start return to make is consumable
// == is comparative = is used as setter we are setting not comparing as code would suggest
document.getElementById("A100").innerHTML=start();
</script>
</body>
</html>
Local scope example as suggested by Mathi;
<html>
<body>
<p id="A100"> </p>
<script>
function start(){
let dictionary, lower;
dictionary="house";
lower=dictionary.toString().toLowerCase();
return lower;
}
document.getElementById("A100").innerHTML=start();
</script>
</body>
</html>

Custom object lab for my javascript class not running properly

I'm working on a lab for my Javascript class and it is a lab dedicated to custom objects and constructor functions. object. I'm making a custom object some musical artists I like. Creating a list of my favorites that I can repeatedly access. I made a constructor function(Called musicalArtist) that creates the musical artists. Passed the arguments through And then stored the custom object in an array. I then created another function called showInfo(). On the first
line, I entered the following code:
var info = “ ”
This creates an empty string that I can add information to as I run through the
objects. Then I created a for loop that has a counting variable named count set to 0. And inside the forloop I added details about the objects to the info variable.
When the user clicks the button it's supposed to run the showInfo() function but it does not? Here's my code:
<!DOCTYPE html>
<html lang="en">
<head>
<title> Custom Objects Lab</title>
<script>
function musicalArtist(name, song, description){
this.name = name;
this.song = song;
this.description = description;
}
var t= new musicalArtist("Tyler the Creator", "All of them", "He's
beautiful I might cry");
var s= new musicalArtist("Slipknot", "Wait and Bleed", "Literally so
awesome");
var a= new musicalArtist("Ayesha Erotica", "Literal Legend", "She is
such an icon");
var myArtists = [t];
var myAritsts= [s];
var myAritsts = [a];
function showInfo() {
var info = ""
for (var count = 0; count < 3; count++) {
info += "Name:" + myAritsts[count].name + "\n";
info += "Best Song:" + myAritsts[count].song + "\n";
info += "Descrition:" + myAritsts[count].description +
"\n";
}
alert(info);
}
</script>
</head>
<body>
<button onclick="showInfo()">A</button>
</body>
</html>
Your code is very close to working. While #stroeda's suggestion to use event listeners is more commonly used these days, that is not what is stopping your code from working.
Some notes to lead you in the right direction:
1) It is convention when defining a constructor to begin your function name with a capital letter. So, instead of function musicalArtist use function MusicalArtist. This does not change the functionality, but will be expected if others are looking at your code.
2) Each time you write var myArtists = [something] you are overwriting the previous myArtists array. What you want is an array with three artists in it.
3) If you are trying to iterate over an entire array, you would be better off using the length property of the array, rather than hardcoding the assumed length of 3. That way, if the length changes, your code will be able to handle it.
4) Be sure to check your spelling. A single typo can break your entire program. You have a typo in there that will break your code. If you write your code in an editor like VS Code and use a linter it will be easier to spot typos.
Good luck with the class!
Try to use event binding when you are loading your javascript and add the following code on the bottom of you JS:
document.getElementById("button").addEventListener("click", showInfo);
Change your button's HTML to:
<button id="button">A</button>
An error occures in your console.log because the code is incorrect but now it does load the click event

Using mathjax in an updating sequence in javascript

I have four dynamic variables in my program,
xzero, xone, xtwo, xthree
That represent the coefficients of a cubic function. I want to show the actual equation in the HTML, in the following format:
xthree*x^3+xtwo*x^2+xone*x+xzero=f(x)
but it needs to be able to update with the variables, so I had originally thought that I would do a
document.getElementById("demo").innerHTML = (new equation);
But it seems to me that either mathJax doesn't work in javascript, or that I'm not doing it right. The only alternative solution that I could think of is to make four individual div tags per variable, and update them all, but this seems unnecessarily clunky. Could I get some pointers either way as to how I would fix this?
MathJax automagically renders the document when it is loaded, but not later. Try explicitly requesting re-render:
document.getElementById("demo").innerHTML = "...";
MathJax.Hub.Queue(["Typeset", MathJax.Hub, 'demo']);
EDIT: After some thinking, I figured you could ask for the render in one element, keep it hidden, then copy the finished markup into another, to prevent flicker:
var mathDiv = document.getElementById('math');
var displayDiv = document.getElementById('display');
MathJax.Hub.Queue(["Typeset",MathJax.Hub,"math"]);
MathJax.Hub.Queue(function() {
var math = MathJax.Hub.getAllJax("MathDiv")[0];
var i = 1;
setInterval(function() {
MathJax.Hub.Queue(["Text", math, "\\int_0^{" + i + "} x dx"]);
MathJax.Hub.Queue(function() {
displayDiv.innerHTML = mathDiv.innerHTML;
});
i++;
}, 1000);
});
#math {
display: none
}
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<div id="math">$$$$</div>
<div id="display"></div>

Replace text in a website

I'm looking to replace text in a webpage (any webpage I want to run it on) using JavaScript. I'm not an expert in JavaScript, so I am sort of lost. If I can help it I would like to avoid jQuery.
Through Google, I've found this stackoverflow question. But when I inject document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi'); into a webpage it sort of messes the page up. It seems to make the page revert to basic text and formatting.
Also, I'm wondering if the regex code from here, could be used. Again, I really am not sure how to use it. What it would do is replace only webpage text - not links or filenames.
I'm using Google Chrome incase that matters.
You could perform your repleacements on all the just the text nodes in the DOM:
function replaceTextOnPage(from, to){
getAllTextNodes().forEach(function(node){
node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
});
function getAllTextNodes(){
var result = [];
(function scanSubTree(node){
if(node.childNodes.length)
for(var i = 0; i < node.childNodes.length; i++)
scanSubTree(node.childNodes[i]);
else if(node.nodeType == Node.TEXT_NODE)
result.push(node);
})(document);
return result;
}
function quote(str){
return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
}
Quote function borrowed from this answer.
Usage:
replaceTextOnPage('hello', 'hi');
Note that you will need to SHIM forEach in older browsers or replace that code with a loop like so:
var nodes = getAllTextNodes();
for(var i = 0; i < nodes.length; i++){
nodes[i].nodeValue = nodes[i].nodeValue.replace(new RegExp(quote(from), 'g'), to);
}
Recently, I had to exercise a similar problem, and I came up with something similar to this:
<!DOCTYPE html>
<html>
<head>
<title>HTML JS REPLACE</title>
<script type="text/javascript">
function convert(elem) {
var content = document.getElementById(elem).innerHTML; // get HTML content for the given element
var pattern = new RegExp(/hello/gi);
content = content.replace(pattern,'hi');
document.getElementById(elem).innerHTML = content; // put the replace content back
}
</script>
</head>
<body>
<div id="content">
Some text that includes both hello and hi. And a hello.
</div>
<script type="text/javascript">
window.onload = convert('content');
</script>
</body>
</html>
The result will be that you will get a page saying this:
Some text that includes both hi and hi. And a hi.
while the original source still says:
Some text that includes both hello and hi. And a hello.
The tricky bits are really just a few - first, you want the window.onload trigger to be included at the bottom of body, so the DOM loads fully before running any JS on it.
Second, you must have a top-level block element that you assign a unique ID which you can reference from JS.
Third, the convert function uses a regular expression, which executes a global case-insensitive replace of the string "hello" by changing it to "hi".
Your specific application may require to instead capture all of the occurences and then parse them in a loop, which may (or may not) cause some performance issues. Be careful :)

Categories