Custom object lab for my javascript class not running properly - javascript

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

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!

javascript how to insert new elements at different locations in page

I'm writing a chrome extension that will add helper text instructions/reminders to specific location in the "new order" form we use at work. I'm really new to coding (basically using this project as a way to learn). I've created something that works - but I'm convinced there's a more elegant solution that I just haven't been able to figure out.
var helpText = "this is the message"
var customAlert = makeAlert(helpText) //create html container for msg
function makerAlert(helpText){...} //createElem, add class/style, append children
I'm okay with that bit (above). But should i be storing information on each message in objects instead? why would/wouldn't i? what information would go in it?
function alertPlacer(customAlert){
var par = document.getElementsByClassName("class-name")[i];
var sib = par.childNodes[j];
par.insertBefore(customAlert, sib);
};
really struggling with this bit (above). I have actually made alertPlacer() functions for each message because i can't figure out how to create a function that will take different class name & index parameters. should i be breaking this up more? if i stored these bits of info in an object, would that be useful?
relevant info:
because the target locations are within a form, almost nothing has an "id" attribute. so i have to use getElementsByClassName & an index.
for each message, I know the target parent className & index and the child node index to "insert before".
i would like to stick with javascript-only solution.
functions can take multiple arguments:
function alertPlacer(customAlert,className,parIndex,childIndex){
var par = document.getElementsByClassName(className)[parIndex]; var sib = par.childNodes[childIndex];
par.insertBefore(customAlert, sib);
};
And you call your function like
alertPlacer(yourAlert,"class-name",6,9);

Problems with onclick / calculating a sum

Let me start by saying, that while I have some programming experiencing (some basic C from a college class and I once wrote a FORTRAN programm in college for a professor), I am utterly new to JS and beginning to get a bit frustrated.
For some reason, even after reading tutorials and watching several YouTube videos on objects, I seem unable to wrap my head around it. I understand the fundamentals and have no problems doing very basic stuff, like writing a loop that prints out increments on a HTML site, but every time I try something practical, I am completely at a loss.
Here is my current problem: I have created this HTML site that generates a shopping list. Basically, when I click on one of the buttons next to an item name, it adds that item to the list in the middle of my screen. Thanks to Google I found a piece of JavaScript code which, through try and error, I managed to tweak for this purpose:
<!-- click this button to add the item-->
<button onclick="myFunction('ITEM1', 100)" class="sidebarbuttons" >ITEM1 </button>
/* Create a List one line at a time- */
<script>
function myFunction( x, y ) {
var node = document.createElement("LI" );
var textnode = document.createTextNode(x);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
}
</script>
So far, so good. Now I want to get the net price for all the items. Which means, When I click the button, I want a function to add the price of that item to a variable and then display that variable in a field with
document.getElementById("result").innerHTML = total_sum;
Here's my question: how, oh my god, how do I do this? I thought I could add the following:
function myfunction(x,y){
var sum = 0;
var sum+=y;
}
document.getElementById("result").innerHTML = 'sum';
Obviously, this doesn't work at all. Can you please give me some hints what I have to do to make this work?
First of all,
please consider to study JavaScript better, because it's a falsy easy programming language and it's very dangerous to copy&paste without knowing the language. It's quite normal to read a lot, watch a lot and don't know where to start, and it's the main reason because people hates JavaScript: because we don't know well JavaScript. So consider to read the book series "You Don't Know" by Kyle Simpson.
About your question. You can add a variable to storage the sum of your items and when you click to an item, you can add to it:
var total_sum = 0;
function myFunction( x, y ) {
var node = document.createElement("LI" );
var textnode = document.createTextNode(x);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
showResults(y);
}
function showResults(price){
total_sum += parseFloat(price)
document.getElementById("result").innerHTML = total_sum;
}
JSBIN
Let me know ;)
So you are on the right track. Picking up where you left off in your last code block, there are few things you will need to change.
//declare the variable outside of the function... otherwise it will only be available to you within that function.
var totalSum = 0;
// then within your function you will be able to successfully add to the global totalSum variable
function calculateSum(x){
totalSum += x;
// and lastly... set the innerHTML within the function... which should equal the variable totalSum
document.getElementById("result").innerHTML = totalSum;
}
Hope this helps.

Function for counting characters/words not working

<!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!

Password Strength Meter

I'm trying to create my own JS Password Strength Meter.
It was working before but i didn't like how it worked so I tried using
{score +=10;}
Instead of just:
score++
This is my code:
http://jsfiddle.net/RSq4L/
Best Regards,
Shawn,
Hope someone can help
Multiple issues:
Your passwordStrength() function was not defined in the global scope in the jsFiddle so it wasn't getting called. This is probably an artifact of how you set up the jsFiddle, perhaps not an issue in your real code.
The method of getting the appropriate ratingMsg will not work because you don't have array values for every possible score so many scores will generate an "undefined" ratingMsg.
Your CSS classes are also sparse so there are many score values that they will not match for either and no appropriate CSS class/style will be in effect. If you want a specific class for each rating value, then perhaps you should put the classname in the ratings array so it can be fetched from there along with the ratingsMsg.
For the first issue, in your jsFiddle, you also have to make sure the password processing function is defined in the global scope. The way your jsFiddle is set up, it is not (it's in the onload handler). You can fix this in the jsFiddle by just setting the first drop-down in the upper left to "no wrap (head)".
For the second issue, you are using:
ratingMsg[score]
but, your array is a sparse array not guaranteed to have an entry for most possible scores. You simply can't do it that way because many elements you access will have undefined values which won't give you a meaningful message. For example, if score was 15, you would be accessing ratingMsg[15], but there is no value in that space in the array so you won't get a meaningful rating message.
The solution is to find a different way to select the right message. The simplest way would just be an if/else if/else if statement that would check which range the score is in and set the appropriate msg. There are more elegant table driven ways, but all will involve searching through a data structure to find which two values the current score is between and using that msg.
If you look at this jsFiddle http://jsfiddle.net/jfriend00/dA7XC/, you'll see that your code is getting called, but it only hits values in the array sometimes.
And, here's a rewritten algorithm that finds the appropriate msg no matter what the score show in this fiddle: http://jsfiddle.net/jfriend00/jYcBT/.
It uses a data structure like this:
var ratingMsg = [
0, "Unclassified",
10, "Weak",
20, "Fair",
50, "Better",
60, "Medium",
70, "Good",
90, "Strong"
];
and a for loop like this to get the appropraite ratingMsg:
for (var i = ratingMsg.length - 2 ; i >= 0; i-=2) {
if (score >= ratingMsg[i]) {
msg = ratingMsg[i+1];
break;
}
}
Here you go: http://jsfiddle.net/RSq4L/11/
The first problem is that in your fiddle you have the onLoad option set, so your passwordStrength function is not actually being declared in the global scope. It is being declared inside of the onLoad block that jsFiddle wraps your code with. This causes the page to error out when the keypress handler tries to invoke the function.
You can fix this problem in several different ways:
By explicitly declaring the function as global as per my example above.
By choosing one of jsFiddle's "no wrap" options instead of onLoad.
By dynamically binding your event-handler instead of setting it through the element's onkeydown attribute in the markup.
The second problem is how you are keying your score messages. You have:
var ratingMsg = new Array(0);
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
...and you lookup the message by doing ratingMsg[score]. This will only work if the score exactly matches one of your indices. And based upon your math this will not always be the case.
I would suggest doing something like:
ratingMsg = {};
ratingMsg[0] = "Unclassified";
ratingMsg[10] = "Weak";
ratingMsg[30] = "Fair";
ratingMsg[50] = "Better";
ratingMsg[60] = "Medium";
ratingMsg[70] = "Good";
ratingMsg[90] = "Strong";
function closestRating(score) {
var bestKey = 0;
var bestMatch = 100;
for (var key in ratingMsg) {
if (key <= score && score - key < bestMatch) {
bestMatch = score - key;
bestKey = key;
}
}
return ratingMsg[bestKey];
}
On an unrelated note, are you sure you want to be using onkeydown? I think onkeyup would work better.
Your fiddler script had several errors. Here's the corrected one: new script.
You were missing a semicolon here: document.getElementById("passwordDescription").innerHTML = "" + ratingMsg[score] + ""
You forgot to escape '^' on your regular expression
I just wrote this for it:
Jquery Plugin for password strength forcing

Categories