JavaScript - Lecture 5 - CS50's Web Programming with Python and JavaScript 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] you okay welcome back everyone to web programming with Python and JavaScript and today we turn our attention to the second of the main programming languages that would be looking under this class in particular JavaScript and to get an understanding for why it is that JavaScript is actually helpful let's go back and revisit this diagram of what communication over the Internet will generally look like oftentimes we'll have a user otherwise known as the client using their computer on their web browser whether that's Chrome or Safari or some other web browser that sends an HTTP request a web request to some sort of web server that server then processes that request and then returns some sort of response that comes back to the client thus far all of the code that we've written the Python web application code running in a Django web application for example has all been code that runs on some sort of server code that is listening for requests doing some computation in order to process that request and then generating some sort of response usually in the form of an HTML template that we then send back to the client what JavaScript is going to enable us to do is to begin to write client-side code javascript is going to allow us to write code that actually runs and inside of the users web browser on the client and this can be useful for a number of reasons one if there's computation that we want to do but we don't need to go out and reach out to a server in order to do so we can do the computation potentially faster just by running the code exclusively on the client and in addition to that we can begin to make our web pages a whole lot more interactive javascript is going to give us the ability to directly manipulate the Dom where again the Dom is the document object model that tree like hierarchy that represents the web page that the user happens to be looking at so javascript will enable us to write code that directly manipulates the content on the web page and we'll see how that can be quite powerful very soon so how do we then use JavaScript inside of a web page in order to add some code add some programming logic to a web page well so far we've already seen HTML the language we use to describe the structure of a web page where a HTML page just describes the structure of a page and in terms of nested tags we had those head tags at the top of the page the body tags that describe the structure of the page and then additional tags that could be nested within those and in order to add JavaScript to a web page if it's as simple as include some script tags that are often located inside of the HTML page itself when we use these script tags we're telling the browser that anything in between these script tags should be interpreted in this case as JavaScript code that the web browser is then going to execute so our very first program for example might just look like a line of code inside of the script tags something like this where alert for example is the name of a function a function that's going to produce an alert and then just as with functions in Python functions in JavaScript can take arguments so in between these parentheses we have an argument something like a string hello world the text that we would like to display to the user so let's go ahead and give this a try and see how we can actually use this code to write JavaScript that is going to run inside of the user's web browser I'll go ahead and create a new file that will call hello HTML and inside of it I'll include the same basic HTML structure that we've already seen before where I have a head section that has a title and then a body that maybe just says hello for example and so now what I'd like to do is add a little bit of JavaScript to this web page so in the head section of my web page I'm gonna go ahead and add a script tag we're in between these script tags now I can write JavaScript code code that is going to be written in JavaScript that will run inside of the web browser when the user actually opens up this page and for now I'll just say alert and then hello world it turns out in JavaScript you can use either single quotation marks or double quotation marks in order to represent strings and I'll generally use single quotation marks here just by convention so here I'm running a function called alert that's going to display an alert something like hello world to the user and that's going to be inside of the script tags of this HTML page so now if I want to actually open the page up I can open hello dot HTML or you could just visit it inside of your web browser whether it's Chrome or something else and now at the top of the page what you'll notice is that I get a little bit of an alert some interaction where it says this page says hello world and gives me an option to like press a button for example like Hello I'd like the OK button that'll say all right dismiss the alert now and this is our very first example of JavaScript we have a function called alert built into JavaScript for our web browser and our web browser knows that when we call the alert function the browser should display an alert message that looks a little something like that and if i click the ok' button to dismiss the alert then we go ahead and get back the original page that i had from the beginning and so now we can begin to imagine that using this ability to programmatically display alerts that we can add additional features to our applications as well and one big area where javascript can be quite powerful is with isn't driven programming and what event-driven programming is all about is thinking about things that happen on the web in terms of events that happen what are some examples of events events are things like the user clicks on a button or the user selects something from a drop-down list or the user Scrolls through a list or submits a form anything the user does and can generally be thought of as an event and what we can do with javascript is add event listeners or event handlers things that say when an event happens go ahead and run this particular block of code or this function for example and using that we can begin to allow our JavaScript code to respond to how the user is actually interacting with our web page to say when the user clicks on a button I would like to run this particular JavaScript function for example so let's go ahead and give that a try I'll go ahead and now instead of just saying alert hello world let me put this alert inside of a function and to create a function in JavaScript you just use the keyword function followed by the name of the function I'll call the function hello for example and then in parenthesis any inputs that function takes this hello function is not going to take any input so I'll just use an empty set of parentheses and then inside of curly braces I include any of the code that I want to run in this function and so what I've done here now is create a function called hello and then inside of the curly braces have defined the body of the function what code should run when I run the hello function and what the hello function should do is it should display an alert that in this case says a hello world so now what I'd like to do is get this function to run when something happens on the page for example when a user clicks on a button so to do that the first thing I'll need to do is actually create a button so add a button that just says like click here for example so now if i refresh this page i now see that i have hello and I also have this button that says click here but when I click here like nothing happens I'm clicking the click here button but it's not changing anything because I haven't yet said what should happen when the user does click on this button and so one way we could do this is by adding an attribute to this HTML element called unclick what this is going to do is it's going to add an on click handler to this button it's going to say what should happen when the user clicks on this button and I'm going to set the onclick attribute equal to running the function hello and in order to run a function in JavaScript just as you ran a function with Python you use the name of the function followed by a set of parentheses to say go ahead and actually run this function using this parenthesis calls the function another word for running the function and the fact that there's nothing in between the parentheses means we're not providing anything as input to the hello function though if the hello function did take inputs we could certainly add that in between the parentheses so now I've tied the two pieces of this page together I have a button that says click here and I've added an onclick handler that says that when you click on the button you should run the hello function and then up above I've defined the hello function to say what should the hello function do well when the function is called we're going to display an alert that in this case says hello world so now we should be able to refresh the page we still see the same thing at least initially where it just says hello and a button that tells me to click here but now if I go ahead and click the button that says click here well then I get the alert that says this page says hello world I can press ok and this event handler is always going to work I click the button again and I get the alert a second time because every time I click the button it's going to call the hello function again and when I click the hello when the hello function runs and it is going to display this particular alert so this now appears to give us a fair amount of power and much as in other programming languages languages like Python or other languages you might have worked with JavaScript has all these same types of language features so far we've seen datatypes things like a string but we also have other data types that we'll take a look at soon too we've seen functions some functions that are built into JavaScript like the alert function and other functions that we can write for ourselves functions like hello but we also have the ability to include things like variables inside of our program as well so what might that look like well I'll go ahead and create a new file it will call counter HTML and counter is going to have some of the similar code to hello so I'll just go ahead and copy it for now but I'll clear out the script section change the title from hello to counter and now inside I'll get rid of the button or actually I'll keep the button but instead of saying click here the button is going to say count I'd like to create a program that just counts for me from zero to one two two three four so on and so forth and now in order to do that in order to have some way of counting repeatedly zero one two three four five I'm going to need a have some sort of variable inside of my program something that is keeping track of data like the number that I'm currently have counted to so in order to do that in JavaScript I can say something like let counter equal zero this is the way in JavaScript that I define a new variable I first say let counter meaning let there be a new variable called counter and I'm going to initially set the value of counter equal to the number zero and now when I click on the button instead of running the hello function I'm going to go ahead and run the count function which doesn't exist yet but I'll now write it I'll define a function called count and what the count function is going to do is it is going to first increment the value of counter and a number of ways I could do that one is my saying counter equals counter plus one to say go ahead and reset the value of counter to whatever it counter is plus one and there are a couple of shorthand notations for this I could equivalently say counter plus equals one to say add one to the counter or in the case of adding one javascript much like languages like c if you've seen them before and support notation like this counter plus plus which just means take the value of counter and increment it add 1 to it so I'll add 1 to the value of counter and then I'll just display an alert that has whatever the current value of counter happens to be and so I've incremented the value of counter and then displayed an alert that shows me what's contained inside of counter and so now if I go ahead and not go to hello dot HTML but to counter dot HTML instead I now see that I still see a button that says count and if I click on that button I get an alert that this time says one we've incrementing the value of counter from zero to one the alert now says 1 and I can press ok if I press count again the count now goes to 2 I press ok press count again it goes to 3 and every time I click count it is going to increment the value of the variable counter inside of my JavaScript webpage and then it's going to display an alert that is going to contain the value of that variable so using alerts now we're able to manipulate that we can inside a functions manipulate the values of variables and then display alerts that show the contents of those variable ism but ultimately when users are interacting with the page it's going to be fairly annoying if the only way that we have to interact with the user is via displaying these alerts the equivalent of like printing something out except instead of printing it to a terminal we're printing it via an alert that appears on the screen what would be more interesting and more powerful and much more useful in the context of a webpage is if we could programmatically update the website change something about the webpage the user is actually seeing changing the content that happens to be on the page and turns out Java Script is going to enable us to do that as well because Java Script allows us to manipulate the Dom the document object model that represents all of the elements that happen to be on that page so to do that let's go ahead and return to hello HTML this again was this paté web page that just said hello and gave me a button where if I clicked on that button it would display an alert that said hello world now what I'd like to do is instead of having the hello function display an alert I'd like to have it manipulate something on the page and what might I want me to manipulate well inside the body of the page I here have this heading this heading that just says hello for example which is inside of an h1 element and what I might like to do is actually change that element how can I do that well it turns out that in JavaScript we have access to a function called document dot query selector and what document query selector is going to do is it is going to give us the ability to look through an HTML page and extract an element out of that page so that we can manipulate that HTML element using JavaScript code and so if I want to select like an h1 element I can say document query selector and then as the argument the input to document our query selector I'll go ahead and say each one meaning go through the page find me an h1 element and query selector is only going to return one element so if they're multiple it's going to return the first thing it finds but here we only have one h1 element so it's ok I'm gonna say look through this document try and find in h1 element and when you do I'd like to manipulate it and the way I'd like to manipulate it is by saying dot innerhtml equals of let's say goodbye for example so alright what's going on here well right now initially when we first load the page we have an h1 a big heading at the top that just says hello and now when this hello function is called which is called when this button is clicked on because it has an on-click attribute that is equal to hello calling the hello function what the hello function is going to do is it's going to say document query selector h1 find me the h1 element that will return this element right here a JavaScript representation of this HTML element that is just an h1 whose HTML inside of it says hello and if I want to change that HTML I can do that by modifying the inner HTML property of the JavaScript elephant in order to update a property of anything in JavaScript will generally use this dot notation we're dot accesses of property of some particular object and so I have this element this h1 and saying dot inner HTML means take that element and access its inner HTML property some property of that object and I would like to update its inner HTML to just in this case be the word goodbye followed by an exclamation point for example so now what we'll see is that when we run this page when we open this page up as by opening up hello HTML I still see an h1 that says hello I still see a button that says click here but now when I actually click on the button click here you'll see that hello changes to goodbye we've run JavaScript code that finds an h1 element on the page and manipulates it changing it to something else than it was originally now every time I click here nothing else happens because every time I click here it's going to find the same h1 and it's going to update its HTML changing it from hello to goodbye so maybe what I'd really like then is the ability to toggle back and forth to toggle back and forth between hello and goodbye rather than just change it from one thing to something else every time I click the button I'd like it to alternate back and forth and there are a number of ways you can imagine doing this but one way is by taking advantage of conditions so much in the same way that a language like Python has conditions ifs and LS and else's JavaScript too has if and else if and else that allow us to describe conditions such that we can only run certain blocks of code when a particular boolean expression is true for example so what would that look like well let's go ahead and say inside of this hello function I can ask a question if document query selector H ones inner HTML is equal to hello well then go ahead and set it to goodbye and else then go ahead and update the inner HTML this h1 element go ahead and set it to hello instead so what is this hello function doing it's now a little bit more sophisticated it now has a condition where I say if the keyword if followed by in parentheses the condition that I want to check for the thing I want to see is this true or not and what I'm checking for is is let me run document out query selector h1 which again looks through the page finds me the h1 tag and get to that element for me if I look at that inner HTML if it is equal to hello then I want to do something and this triple equals sign is JavaScript's way of checking for strict equality checking to make sure the two values are equal and also that their types are the same thing that if this is a string this must also be a string it turns out in JavaScript is also a weaker way to check for equality that just uses two equal signs and that is going to check the values are the same but it's going to allow for a bit of differences in type the two things might have different types but so long as they're basically the same value the double equal sign might generally come to be true usually if you can you'll want to use this triple equal sign the strict equality to make sure that not only are the types the same but the values are the same too and the triple equal sign will check both of those things so if I go ahead and find the h1 element and its inner HTML is the word hello well then go ahead and find the h1 element and update its inner HTML setting it equal to goodbye for example and else go ahead and find that same h1 element updated inner HTML set it equal to hello and again just as in functions where we use these curly braces to enclose the body of the function all of the lines of code that are inside of the function JavaScript does the same thing to that inside of a condition when we want to express that this is inside the body of an if condition I can use curly braces to say this line of code in that line of code that's inside of the if expression or that's inside of the else expression for example so let's go ahead and try this now I can go ahead and open hello dot HTML refresh it it currently says hello with a button that says click here and now when I click here hello changes to goodbye and when I click here again goodbye changes back to hello and every time I click the button it's going to alternate between hello and goodbye because we either get caught in the if expression or we get caught in the else expression now there are a couple of places where you might look at this and notice that maybe this isn't as efficient as this code could potentially be and recall that every time we run document query selector to say go ahead and try and find a particular HTML element for me it's going to look through that page trying to find the h1 element and it turns out that right now we have three separate calls to query selector even though only two of them will ever run on any given instance of the function but we document a query selector then we call it again inside of the if expression we can probably improve the design of this page by factoring that out by just looking for the h1 element once and then manipulating it and checking it using that element that we have found and to do that we can store an element inside of a variable in the same way that a variable can store a number like a counter or a string like hello world it can also store other values like an HTML element that we get back from document dog query selector so I could say something like let heading we're heading is just the name of a variable the equal to document query selector h1 for instance find the h1 element save it inside of a variable called heading and now rather than document query selector each one all the time I can just say if the headings inner HTML is hello then set the headings inner HTML to good bye otherwise I set the headings inner HTML to hello so I've improved the efficiency of the program but also reduce the number of characters of code that I've had to write my lines are now much shorter a little bit easier to read this we would consider to be an improvement in design and it turns out there's one other improvement we can make here too that we can define a variable like let something equal something else but it turns out that JavaScript gives us a couple of ways to define a variable and if we're going to be creating a variable whose value is never going to change we're never going to reassign the variable name to something else then instead of let we can enforce that it's never going to change by calling it a Const variable so Const heading equals document query selector h1 means I am going to create a variable called heading setting it equal to the result of document query selector h1 and never again will I change what heading is equal to I will never have another line of code that says heading equals something else because it is constant and JavaScript will then enforce that this variable should not change and if ever I do try to change it javascript will give me an error and this can just be helpful to prevent against possible unintended behavior that if you know you have a variable it is never going to change it's often good designed to label it as a constable so that you and other people looking at your code know that that is never going to have a value that gets changed later on so this then will behave the same way where it says hello but I can toggle it back and forth changing it to goodbye and then changing it back to hello again and so now using this ability this ability to manipulate the dawn we can go back to our counter program and actually improve upon it that right now the counter program I count and it displays an alert that says 1 I count and it displays an alert that says 2 I can probably do a little bit better than that by instead of displaying an alert actually manipulating the Dom in some way that I would like to have this h1 this big heading at the top instead of starting up by saying hello let's have it start out by saying 0 for example just some initial value for the counter and now when I increment the value of counter rather than display an alert that just tells me the value of the counter in an alert I'm going to instead say document query selector h1 . innerhtml equals counter where i'm saying find the h1 element updated innerhtml set it equal to whatever the value of the variable counter happens to be such that now if i refresh this page the value of this h1 initially is 0 that's the initial value but every time I click count we're going to update the contents of that h1 element and this time setting it to 1 2 3 4 and so forth every time I click the count button it's going to increment the value of the variable as well as manipulate the Dom actually making changes in order to produce the effect that I want to see on this actual page and we can begin to add additional logic to this as well maybe I do occasionally want an alert but I don't want an alert every single time I could add a condition I could say something like if I only want to display an alert every time I count to a multiple of 10 like 10 and 20 and 30 and 40 and 50 and so forth I could add a condition that says that if counter mod 10 and mod just gets me remainder when you divide by 10 so if you take the counter divide it by 10 if the remainder is 0 when I divide by 10 well that means counter is a multiple of 10 and so I can now display an alert where I can display annele that says like I want to say something like the counter is now 10 or the counter is now 20 and in order to do that what I really want to do is have some way of plugging in a variable into a string inside of JavaScript and in Python the way we would have done this is by you appending f4 prepending F in front of the string to create a formatted string and then I would have said something like the count is now and then I'd use curly braces to say go ahead and print out the value of counter so this f4 formatted string followed by this string would have been the way in python that we would have done this turns out javascript does the same thing just with slightly different syntax it doesn't use F instead instead of using the regular quotation marks whether the single or double quotation marks JavaScript uses these backticks which are usually located above the tab key on a standard u.s. keyboard and this is going to create what JavaScript calls a template literal where I can then substitute the value of a variable somewhere inside of this template and then in order to actually do the substitution while Python uses double curly braces to say plug in the value of counter right here javascript does something similar it also uses double curly braces but there needs to be a dollar sign in front of it the dollar sign and then the dollar double curly braces we can go ahead and plug in the value of a variable there so this then is a template literal where every time we get to a multiple of ten we're going to display an alert that says the count is now and then this dollar sign curly brace means actually plug in whatever the value of counter happens to be right there so now if I go ahead and refresh counter it starts at zero I can count 3 4 5 6 7 8 9 but when I get to 10 then I get an alert that says the count is now 10 and then I see the result update on the page and so that template literal can allow us to combine variables and strings in order to generate new strings that are able to represent data inside of them as well so now what improvements can we begin to make it what changes can we make to this to improve upon the design of it well one thing especially as our programs get a little bit more sophisticated a little bit more complicated is that we often don't want to be intermingling our JavaScript code with the contents of our HTML the down here we have button on click equals count this name of this function and especially as our page starts to get more complicated it's going to start to get a little bit annoying if we're constantly having to maintain a little bit of JavaScript code like making a call to a function inside of our HTML we'll see a little bit later there are other paradigms that actually encourage this type of thing but right now it can start to get a little poorly designed if we'd really like to separate all of our JavaScript related code from all of the HTML the general structure of our page and so there are ways we can begin to do that as well I can add an event listener inside of JavaScript to that I can say something like document dot query selector button and then I can say dot on click equals count so what's going on here and I can do this instead of this on click equals count what I'm now saying is document query selector button find me the button on the page and turns out there's only one button here so it's fine though if there were more I might have to be a little bit more specific but once I get that button then I'm going to access it's on click property and I'm going to set it equal to count and what does count count is the name of a function count is itself a function and so what I'm here saying is I would like to set the value of the onclick property of the button equal to count the count is the function that should run when the button is clicked on and notice that I am not actually calling the function it's not count and then parentheses which were being run the count function and then get its return value and use that as the value for onclick I'm just setting on click equal literally to the count function itself without actually calling the function and what this is going to do is it is going to say when the button is clicked on then and only then should you actually run this count function and we're not going to run the count function until that button actually gets clicked on and so in JavaScript functions can be treated as values of their own just as you can set a variable equal to a string just as even set a variable equal to an integer just as you can set a variable equal to like an HTML element like the result of document query selector you can also set a variable equal to a function something like count and passed that around as a value just as you could with any other value and this is a paradigm we generally call functional programming where we have functions as values of their own things that we can reassign things that we can manipulate just as we could have any other value so now I can try and run this program by going ahead and refreshing the page I'll refresh it at zero I press count and alright nothing seems to be happening it's still zero I want it to be counting but it doesn't seem to be working so why not any time you run into problems in JavaScript where you're not getting the behavior you want often it can be helpful to look at the JavaScript console where the JavaScript console is the equivalent of like the terminal window and when you're running your Django application in Python that would display any error messages the JavaScript console will display any of the JavaScript logging information and error messages as well in chrome I can get to it if I first go ahead and go to inspect and then just open up the console tab here and all right we seem to have some sort of error here it's an uncaught type error that says we cannot set property on click of no encounter dot HTML line 18 so that will generally tell you where the error is coming from it's coming from counter HTML on line 18 and the problem seems to be but I'm trying to access the on click property of no and no is JavaScript way of expressing like nothing some object that doesn't exist so somehow I'm trying to set the onclick property of no well let's see what's going on on line 18 and see if we can figure out what's happening there well alright here is line 18 where I say document dot query selector button setting it's on click property equal to count and now what seems to be the problem here well the error message was that I was trying to modify the onclick property of no well here then is the onclick property so why would this document query selector button be returning or giving me an output of no well it turns out the document dot query selector will return null if it's not able to find something if I try and find a button but it's not able to find a button well this seems a little bit strange because there's a button down here 24 that I'd like for my JavaScript code to be able to find when it runs query selector and tries to find the button as it turns out this is a bit of the quirk of the way the browser is going to work but if the browser is running our code from top to bottom just reading it from line one on and on then it's going to get to line 18 where I said document query selector button onclick equals count and it's going to try and find a button on line 18 but the button doesn't show up in my HTML page until much further down in the page so at this point when we get to this line of JavaScript javascript is looking for the button but the Dom the body of the page hasn't finished loading yet the content of the Dom has not yet loaded and as a result we're not able to find this button so how do we solve this problem how do we get it so we actually are able to like ask for the button and actually get the button well it turns out there are a couple of strategies we could use one would be take the script tag and go ahead and just move it to the bottom section of the body so that after we've already defined the button that says count then we have the script tag that then says alright go ahead and now find the button and now we'll be able to find it it turns out another way and perhaps a more common way is to instead add yet another event listener and we're gonna add an event listener not to the button but to the entire document where document is a variable built into this JavaScript that we have access to on the web page that just refers to this entire web document where I've used document query selector already to look through the whole web document trying to find a button or trying to find an h1 tag for example but I can also add an event listener to the document itself and in order to do that I can say document dot add event listener and when I call add event listener and I can do this on any HTML element not just the document but I could run this function on a button or on an h1 element or any other HTML element add event listener will generally take two arguments where the first is what event I want to listen for the event could be something like click when I click on the document it could be something like when I scroll through a page for example but with the event I'm going to listen for is a particularly special event called Dom content loaded and the Dom content loaded event is an event that is going to be hired or triggered when the Dom the document object model the structure of the page is done loading when all of the elements on the page are done loading the Dom content has been loaded and then if I attach an event listener to it you know run whatever code I want to run that should only run after the Dom is fully loaded after all of the content on the page has then been loaded and the second argument to an event listener is what function should run once the event actually happens when the Dom content loaded does happen so I could pass in the name of a function if I had the name of a function that I wanted to pass in but alternatively JavaScript allows me to just directly write a function here in the argument to add event listener I can just say function and then a set of parentheses to mean the function doesn't take any input and then in curly braces I can include the body of the function right here as the second argument to add event listener and this is a little bit of tricky syntax to wrap your mind around if you've never seen it before but the big-picture way to think of it is add event listener takes two arguments one is the event the second is the function so here first is the event Dom content loaded and the second argument is a function and I declare the function same as before just using function I haven't given the function a name because strictly speaking it doesn't need a name I'm never going to refer to this function by name so it is what we might call an anonymous function a function that has no name but I'm still passing it into the add event listener function as an argument because I want to run the code inside of the function once the Dom is done loading and so inside of curly braces then is the content of that function the content of what code should run when the Dom is done loading and then at the end I again used just this end parenthesis where that end parenthesis lines up with this parenthesis here this is enclosing all of the arguments to add event listener where the first one is Dom content loaded and the second one is this entire function that might span multiple lines so you'll see syntax like this quite a bit in JavaScript but now what I want to do is adding the event listener to the button I can go ahead and just for place and put it here and it turns out that if I wanted to instead of saying dot on click equals count you could used the same syntax of add eventlistener I could say at eventlistener click and then count to mean when the click event happens go ahead and run the count function but you can equivalently shorthand this and just say dot on click equals count and that would work just as well so now what we're saying here is that wait until the Dom has done loaded wait until all the content on the page is loaded and then go ahead and run this function and what the function is going to do is it's going to add the event handler to this button and that'll work because now we'll be able to find the button because now all of the content of the Dom has loaded so now if I go back Refresh counter dot HTML you'll notice that the JavaScript error goes away I don't seem to have that error anymore and now if I press count were able to see the count increment just as before as well and so this then is an improvement upon what I've had before where now I'm able to separate out my JavaScript code from all of the rest of my code as well but much as in the case of CSS where we were able to take CSS that was originally located in the head of our page and move it into a separate file you can do the same thing with JavaScript too and this can be helpful if you have multiple people working on different files you want one person working on the HTML and someone else working on the JavaScript it can be helpful if you expect that one of these things is going to change more frequently than the other so you might not need to load the other one as often so there can be value in separating our HTML code from our JavaScript even more and by moving our JavaScript into a separate file and so in order to do that I can create a new file that I'll just call counter j/s which will contain all of the JavaScript for my counter HTML file so in order to do that what I can say is let's go ahead and copy all of this JavaScript code go ahead and cut it out of this page and I'll paste it into counter j/s remove some of that indentation so now I have a file called counter das that just contains all of the JavaScript I want to run on my counter dot HTML page and now rather than include actual JavaScript in between these script tags what I can say is script SRC SRC first equals a counter Jas for example if I go ahead and reference counter Jas and use that JavaScript in the head of the page here and that then is going to work exactly in the same way I still am able to count as high as I'd like I still get an alert every time the count reaches a multiple of ten but my HTML is now a little bit simpler it's just the body it's just the h1 in the button and then all of my javascript is now located in a separate file that allows me to do that allows me to keep my HTML code and my JavaScript code separate from each other and that can be value for valuable for a couple of reasons among them if I have common JavaScript code that's in use by multiple different HTML pages multiple HTML pages can all include the same JavaScript source rather than needing to repeat myself use the same JavaScript across multiple different pages I can just use the same JavaScript across all of them and that'll be helpful too as we begin to take a look later at some JavaScript libraries which are JavaScript written by other people we can just include other people's JavaScript in our own webpages just by adding a script tag at the top of our page that specifies a particular source you may have already interacted with bootstrap that has its own JavaScript code and you can include bootstraps JavaScript just by including a script tag at the top of our HTML page in order to say go ahead and include all of that javascript in our page as well so what else can we do now now that we have the ability to like get at elements of the Dom and actually manipulate their contents well one thing we can do is begin to make our pages a little bit more interactive actually respond to what users are doing on the page whether the user is typing something in or maybe filling out a form for example so let's go ahead and try an example of that where the user might be filling out a form and we would like for our code to somehow respond to what it is that they type I'll go ahead and go back into hello dot HTML and now inside of the body of the page I've said hello at the top I'm here instead of a button I'm going to have a form this HTML form will look like the HTML forms we've seen before a have an input field that'll add the auto focus attribute to to mean like automatically focus this input field when I open the page because I might want user to start typing right away I'm gonna give this input field an ID of name for example and then a placeholder of name capital n whose type is text so what have I done here I've created an input field where the user can type in some text the placeholder the thing the user see is filled into that input field originally will just be capital and name telling them they should type their name in here and I've given this input field an ID some unique identifier such that I later on can reference and find this particular input field and then I have input type equals submit some way for me to now submit this form as well and so if I load this page load hello dot HTML here's what I see hello a field where I can type in my name the placeholder name shows up there for me and then a button where I can submit this form and now what I'd like to do inside of my JavaScript is instead of this hello function what I'm going to do is I'm going to first run some JavaScript when the Dom is done loading and so I'll use that same line from before you're gonna see it quite a bit we're gonna say document add event listener Dom content loaded and then this function to mean go ahead and run this code when the Dom is done loaded and the code I'd like to run is to say when I submit the form I want something to happen when I submit the form maybe I want to display an alert that if I type in Brian it'll say hello Brian or if I typed in David it'll say hello David for example so how many I do that well how do I get the form that's the first question anytime you want to get at an element one particular element on an HTML page usually what we're going to do is document dot query selector to say get me the element that is a form and there's only one form on the page so I don't have to worry about ambiguity I'm just saying get me that form and then I can say dot on submit when you submit the form what code should run and if I had a name of a function like a function f I could just say like run function f when the form is submitted but alternatively just as before instead of providing the name of a function I can also just provide the function itself I can say function and then in between these curly braces I can specify exactly what code should run when the form is submitted by providing this anonymous function instead using this anonymous function as the value of the on submit property of this form and so now what I'd like to do is somehow get access to whatever the user typed into the input field whatever the user's name happens to be and so I could get the input field by a document dot query selector input and that would work this time but we'll want to start to be a little bit careful because on this page there are multiple different input elements as an input element here for typing in the name and a second input element here for telling me giving me a button where I can submit this particular HTML form and so what I probably want to do is be a little bit more specific and it turns out that inside of query selector I can use all of the standard ways in CSS that we could select for a particular element so in CSS if you'll recall we had the ability to run CSS and just say style all the h1 or we could say style all the things with this particular ID or with this particular class and document our query selector works the same way that I can say document query selector and pass in a tag to say like get me the h1 element or get me the button or get me the form but if there are multiple h1 elements are multiple buttons and multiple forms I can be more specific than that if for example an element has an ID in which case I can say document query selector and then in quotation marks the hash mark and then the name of the ID to say get me the element with that particular ID again using the exact same syntax that CSS uses if I want to apply a particular set of styles to only one element that only has one ID likewise two I can say document query selector and then use dot followed by the name of a class if there's a particular particular class of elements and I want to just get one of those and to say get me an element that has this particular class in order to manipulate it as well so the same types of syntax that we could use in CSS for trying to reference and get at a particular HTML element we can do the same thing here with document query so to go ahead and try and get a particular element based on its tag name based on this ID or based on its class and it was for that reason that inside of the HTML page for my input I gave the input an idea of name I wanted some way to be able to uniquely reference it and I can uniquely reference it not by input but by pound name where I can say get me the element that has an ID of name and that is the element that I would like to extract inside of my JavaScript code once I have that HTML element what I want is like what the user actually typed into that input field and it turns out that if you have an input field in HTML I can get access to what the user typed in by accessing its value property value is a property that fur that refers to what it is the user actually typed in so I can say dot value and I'm going to go ahead and save that inside of a variable so I could say something like let name equal whatever the user typed in but if I'm not going to reassign name to something else inside of this function inside of this function I'm really going to get the name once and I'm not gonna change it inside of the function so I can use a constable instead that would be better designed to say I have a constant variable called name which is equal to document query selector get me the element whose ideas name and get access to its value and now I can display an alert I can alert something like in backticks hello comma and then using the dollar sign curly brace syntax I can say plug in the name there followed by an exclamation point so I've extracted the name from the form get me the input field where they type to the name get access to its value and then I'm displaying an alert that is going to say hello to that person for example and so now for refresh the page I type in my name I press submit I get an alert that says hello Brian press ok I can try it again I can type in something like David it press submit and now the page says hello David so here again we've been able to combine event listeners and functions and query selector to be able to both read information from the page in order to say get me this particular HTML element find me an HTML element and access like what the user typed into it the dot value property that gets me what the user typed into an input field and we've been able to combine that with event listeners and alerts that are able to actually respond dynamically to when a user submits the form or when the entire content of the page is done loading in order to produce some interesting effects as well but it turns out we can do more than just change like the HTML that is contained within an element we can also change CSS as well change the style properties of a particular element as well so let's go ahead and see an example of that I'll go ahead and create a new file then I'll call colors HTML and inside of colors I'll include the same standard HTML boilerplate code that we often start with a head section with a title and a body section and inside of the body of this page I'm going to display a heading that just says hello for example and maybe I'll give it an ID just so I can reference it by name maybe it has an ID of hello and then I'll have three buttons I'll have a button called read a button called blue and then a button called green for example where now if I open up colors dot HTML here's what I see I see a big heading that says hello and then I see three buttons red blue and green but of course right now these buttons don't actually do anything how do I get the buttons to do something well that's where JavaScript's going to come in I'll add a script tag to the top of my page and I only want to run this JavaScript when the Dom is done loading so again we'll use the same syntax as before document dot add eventlistener Dom content loaded and then run this function to say everything in between these curly braces this is all the code that should run once the page is done loading and what I'd really like to do is get at these three buttons and say when you click on each one of them do something different like change the color of a particular HTML element and in order to do that I need some way of uniquely referencing these buttons so to do that I'm going to give them all IDs this button will have an ID of red this button will have an ID of blue this button will have an ID of green unique names I can give to the buttons in HTML such that in JavaScript I'm later able to reference them so what I what do I include now here inside of my JavaScript code well let me say document dot query selector hash read to say get me the element whose ID is read and when you're clicked on on click go ahead and run this function what should the function do well I want to take this h1 element and change its color to red I want to change the font color to red and I'll leave a comment to myself in JavaScript the way you can leave a comment just a document what you're doing is using these two slashes the two slashes indicate everything after that on the page is going to be a comment browser will ignore it but it can be useful to use a programmer and to someone who's reading your code to be able to see what it is that you're describing here on the page and now what I'd like to do is document query selector hello get me the HTML element whose ID is hello and go ahead and modify its style property and now inside of this style object I can modify any of the CSS style properties one of them for example is something like color so I can update the color property and set it equal to red so here now I'm saying when you click on the red button go ahead and run this function and what the function should do is find the hello element update it style what part of the style update its color what should we update it to we should update it to red and I'm gonna do the same thing for the other two buttons as well and it's pretty similar codes I'm just going to copy paste copy paste here I'm gonna have one for changing the color to blue when I click the blue button you should change the color to blue and then we'll do it one more time change the font color to green when you click on the green button you should change the color to green so now when i refresh the colors wml right now hello by default it's just in black standard font color for HTML I click red hello changes to red I click blue it changes to blue I click green it changes to green so depending on what button I click that triggers some event listener that's going to then say when the button is clicked run this function and what the function does is it grabs this h1 element the element whose ID is hello modifies it style updates its color property to be something like red or blue or green and that's showing that we can modify style in addition and just modifying the content of the page itself but it turns out that as you looked at me writing that code something should have struck you is probably not optimal design then in general any time you find yourself writing the same code again and again and again especially if your copy pasting that that is a generally a bad sign usually a sign that there is some better way of trying to modify of trying to implement the behavior that I'm trying to create and it turns out that there is and there are a number of ways that you could do this one way here is that I might like to consolidate these three event listeners into just like a single function that is going to handle changing the color to whatever the button says the color should be changed to but one problem here is that if I just attach the same event listener to all three of the buttons it's not going to be clear to me when I click on the button how does the button know what color we should change the text to and so to that effect we can add some additional special attributes to a particular HTML element that are called data attributes where a data attribute is my way of saying that I would like to associate some data with this particular h2 what HTML element we're here I can say data - color equals red data - color equals blue data - color equals green data attributes always start with data followed by a dash and then I can specify really any name that I want for some information that I would like to store about the HTML element and here the information I want to store is I want to store data about what color you should change the text to when the button is clicked on and so what we're gonna have the ability to do now is the ability to say that if I have access to this element this button I can access its data color property to know whether we should change the text to red or blue or green by adding these data attributes to these HTML elements and so now what I want is some way of getting all of these buttons now document query selector as you recall just gets one element it's just going to get for me a single element and it's gonna get the first one that it finds if I want to get multiple elements what I can do instead is something like document dot query selector all query selector all is going to return the same thing the query selector does but instead of query selector returning a single element that matches what it looks for query selector all is going to return to me an array of all of the elements that match my particular query so if I want to select not just the first button I find but all of the buttons I find I can here say query selector all for button and that will give me back a JavaScript array the equivalent of a list that represents all of those buttons and we can actually test what this looks like by looking at things inside of the JavaScript console that if I go ahead and refresh this page colors I can open up the inspector go into the JavaScript console and just as you could see error messages here you can also actually write JavaScript code here as well so I can say something like document query selector button say all right what's going to happen when I try and select for a button on this particular page and what I get is all right I get just this very first button button whose data - color is equal to red that's what I would expect query selector just finds me one element and it's going to find me the very first element and likewise I can say all right instead of query selector let's do query selector all and what I get back is a node list which you can think of as kind of like an array or a list in Python that's got three buttons in it button 0 1 and 2 and just as with a list in Python as you can index into things arrays and python arrays in JavaScript can be indexed into as well but if I have something like constant Eames equals Harry Ron and Hermione like a array of 3 names I can say name square bracket 0 to get the first name name square bracket 1 to get the second one name square bracket 2 to get the third one for example and that gives me each of the individual elements in the array if I want to get the whole length of the array I can do names dot lengths to get all right the length of the names array happens to be three so just some additional features that we have access to if you happen to have an array of things turns out query selector all returns to me a node list which is kind of like an array and that's going to be useful because when I say document query selector all button I am saying get me all of the buttons on the page and now what I would like to do is effectively loop over all of those buttons and say for each of the buttons inside of this list that comes back to me I would like to add an event handler for when that button is clicked on to say for each of the buttons that comes back go ahead and say when you're clicked on change the color of the h1 element and so there are a number of ways again that you could do this but one way is to use a particular property called for each and for each is a function that accepts as an argument another function where the idea is going to be I would like to run a function for each of the elements inside of an array or inside of a node list for example so here I can say for each button go ahead and run this function this is going to be a function now that takes something as input it's going to take one of the elements in the list as input something like a button and now for each button what would I like to do for that button well when the button is clicked on button dot on click then go ahead and run a function that is going to document query selector get me the element whose ID is hello change its style within the style change its color and what do I want to change its color to well I have access to this button this argument to the function is whichever button I'm currently trying to add an event listener for and in order to access its data properties I can access a special property of an HTML element called it's a data set property and then I can say something like button data set color to get at the data - color attribute so a lot of stuff going on here let's go ahead and try and read through this entire thing and just get a feel for what's happening because we have functions nested within other functions nested within other functions up at the very top I said add an event listener to the document when the documents Dom content is loaded meaning all of the content of the page is done loading go ahead and run this function this is the body of the function so what do I want to do when the page is done loading I'm going to document dot query selector all looking for all of the buttons and if I wanted to if there could be more buttons I could have added a class to these buttons and just look for things of the particular class query selector all just returns all of the elements that match a particular query and then I'm saying for each of those buttons for each of the buttons that came back I would like to run a function on each of those buttons I'm basically saying if I have three buttons that came back let me run a function on the first button then the same function on the second button then the same function on the third button and what is that function well it's this function here a function that takes as input the button its first gonna pass in as input the first button then the second button then the third and what this function does is it adds an onclick handler to the button it says when the button is clicked on go ahead and run this other function and this function now is the function that will run when the button is clicked on to say when the button is clicked on get me the hello element change its color to button dataset color and button dataset that color takes a button takes an HTML element like this one here and accesses its data set all of its data properties and specifically accesses the color data property which in this case is equal to red and that is what we would like to set color equal to so a little bit more complexity we've seen before but now we've been able to reduce what was three different event handlers into just a single one and now this is going to work the same way change it to red blue and green all by just using those data properties that we have access to and so when in doubt about how these things are working about what query selector is returning the JavaScript console can be a very powerful tool for this so you can go into the JavaScript console and actually manipulate things you can running run queries you can run functions you can even modify their values of variables like if I go back for instance to counter dot HTML or head this counter that's counting 0 1 2 3 4 if I wanted to I could say something like counter equals 27 just like change the value of the counter nothing appears to have changed on the page I didn't say update anything on the page but now next time I run count it's going to update the value of the count to 28 because I had updated the value inside of the JavaScript console it's going to increment that value display that value inside of the h1 element so you can modify variables that you can run functions you can run document query selector to figure out what particular elements are going to come back all through the use of the javascript console which can be a very very powerful tool especially as you begin working on trying to debug these programs and trying to figure out what might be wrong with them it turns out too that there are other changes that we can make in order to optimize our code a little bit more in order to make it a little bit more succinct and one way is that in more recent versions of JavaScript they've introduced a particular notation for functions called the arrow notation for functions and I'll just show it to you because it'll come up but often times instead of using the keyword function before introducing a function you'll just have something like button and then arrow the curly braces and strictly speaking you don't even need the parentheses around the input where button arrow and then in these curly braces some code just means here is going to be a function that takes as input a variable called button and then runs this particular block of code when that function is run and likewise if a function takes no input like this function up here you could express it using arrow notation with just parentheses a arrow block and so this is often a notation that you'll see in Java scripts if you ever see it know that that's really just shorthand for creating a function whatever is to the left of the arrow sign is the input to the function and whatever is to the right of the arrow is what code should actually run when the function body gets executed when the function is called upon so what other changes might we want to make two colors dot HTML well if we look back at colors dot HTML here's what it looks like now we've got a heading that says hello and then to change the color to red or blue or green for example we might instead if we want the user to choose from one from a number of options decide upon the user interface choice of using a drop-down instead of a bunch of buttons for example and JavaScript supports that as well and we'll use this as an opportunity to explore some of the other event handlers that exist within JavaScript so for example instead of having these all inside of buttons I can make my life a little bit easier by making this a select drop-down where the Select is going to have an option whose value is I'll say black is the default option and I'll say black and then we'll add another option whose value is red and then we say red and the value is what we'll get in JavaScript when we try and extract the value of a particular select drop-down well it's in between the option tags themselves is what the user is going to see on the page when they actually view it so I'm capitalizing it just for them option value equals blue that'll be blue and then option value equals green and that'll be green so now what the user sees is they see hello and then a drop-down menu where they can choose from a list of colors rather than click buttons in order to do so and now of course this select drop-down doesn't do anything at the moment but I can modify it so that it does so now instead of selecting for all of the buttons and doing something with all the buttons we don't have any buttons anymore what I do have is I have a select drop-down and now just as we've seen like on click to say when you click on something as we've seen Dom content loaded as an event there's another event called on change which applies to things like select dropdowns where when something changes in the select drop-down when a user chooses something different I can run some code for example so I can run a function that in this case is going to take document query selector hello meaning get me the hello HTML element change its style what part of the style changed its color and I want to change it to something I want to change it to the value of this select drop-down but how do I get access to this particular select drop-down well in JavaScript we have access to a special value called this and this has special meaning in JavaScript and its meaning varies based on context but in the context of an event handler a function that is called when a particular event happens this is going to be a special keyword that always refers to the thing that received the event so what received the event it was the select drop-down that is what received the event is being changed and so this is going to be a special keyword that always refers to that that always refers to the drop-down menu where I made a different selection so if I want to get the value of that drop-down menu what it is the user actually selected I can just say this dot value to mean get that drop-down menu and get at the value the thing that the user is selected in that idea and now much more succinctly than before I've been able to implement the same kind of idea says hello right now in black but if I choose from the drop-down menu to change its color to something like red for example color changes to red if I instead choose blue it changes to blue green changes to green I choose black it changes back to black so now I have this ability to detect these other types of events and respond to them as well and there are many many different events that exist in JavaScript there's on-click which we've seen already on mouse-over can detect like when you mouse over something when you're hovering over a particular element if you've ever seen web sites that somehow respond when your mouse moves over something that can be how it's implemented on key down and onkeyup can respond to keyboard event something like when you press a key on the keyboard when you press down on the key that's on key down and when you lift your finger off the key that's on key up and there are other events as well many more events that are just listed here that you can listen for and respond to so that you can really interact with the user based on what it is that they're doing so now let's take a look at an example of how we can use some of these events to now begin to create a little bit of a more interesting application we'll go ahead and build a to-do list application this time using exclusively JavaScript we've seen to-do lists before that involve communicating with a server making requests and responses will now build it to-do list that only uses JavaScript to do so so I'll create a new file called tasks HTML and we'll use a we'll create a head section whose title is tasks and a body section and inside the body of the page I'll go ahead and have a heading that says tasks and underneath that I want an unordered list of all of my tasks so I'll have an unordered list I'll give it an ID of tasks just for good measure so I can reference it later but initially nothing's going to be in here but what I'll have underneath the unordered list is a form a form where I can submit a new task for example so I'll give myself an input field also given an ID the ID will be tasks singular for the new task that I am typing in the placeholder will be new tasks just so the user knows what to type in and the type of the input field will be text so I have an input field where the user can type in some new tasks and I'll also add an input field for good measure whose type is submit that allows the user to submit a new task once they've created it so if I open up tasks dot HTML here's then what I see big heading there is technically an unordered list underneath it here but there's nothing in that unordered list yet so it just shows up as empty then a text field where I can type in a task and then a submit button where I can submit my new task so now I'd like some JavaScript such that when I submit this form we actually do something so add a script tag I want this JavaScript to run after the Dom content is loaded so we'll go ahead and add the usual Dom content loaded event listener and now I want to run code when the form is submitted so I can say document query selector form dot on submit equals and then I want to run a function and I could use the keyword function again but I can just use an arrow function which would be a little bit faster to type just say alright here's the function that I want to run when the form is submitted and what would I like to do well I'd first like to figure out alright what did the user actually type in and what the user typed in well that'll be document query selector task dot value get me the element with ID task that's the input field dot value gets the value of the input field which is what the user actually typed in and I can save that as like Const tasks that is what it is the user typed in and if I'm curious as to what the user typed in I can actually print it out to the JavaScript console and the way to do that is using a special function called console.log and that just logs something to the console the equivalent of printing something out in Python where just shows up in the Python terminal here this is going to show up in the JavaScript console and one other thing I'll add is by default forms will try and submit when you press the submit button like take you to another page we've seen this before already in the context of Django that when you submit a form it tries and submits another web request if I want to prevent that behavior stop the form from submitting it's a stop form from submitting I can return false at the end of my form submission handler to say don't actually submit the form we're gonna do everything client-side everything just inside of the browser so now this won't quite work yet but it'll be progress i refresh the page I'm gonna open up the JavaScript console so I can see what's going on if I add a task something just like foo press submit this now gets logged to the JavaScript console it's the equivalent of a way of like providing debugging information to myself to know all right I now have access to this value foo and it's also telling me what line of code logged it it was tasks HTML line 9 is the line of code that logged foo and so this can be useful when you're debugging a program when you want to see what the values of variables are you can just print them out using console log to figure out what's going on in your program and any particular point in time but what I want to do is not console dot log n what I want to do is really create a new element that I'm going to add into my body of the HTML so how can I do that well to create a new element for my document I can run a function called document dot create element followed by what type of element do I want to create well I have an unordered list a ul and every item inside of an unordered list is a list item in Li so I'll go ahead and create an Li element a list item and I'll save that in a variable that I'll call Li so I've created a new list item and this list items inner HTML the HTML content inside of that list item well that's just going to be tasks this variable from up here which is whatever the user typed in so I've now created newest item and said what GML should go inside of the list item it should be whatever task the user typed in and now I'm going to say document dot query selector tasks get me the element whose ideas tasks and that's gonna be this unordered list here the unordered list whose ideas tasks and if I have an HTML element I can add a new element inside of it by saying dot append Li and with that now is going to do is it's going to say get me the unordered list whose ideas tasks get me the element whose ideas tasks by a query selector here once I have that element append to the end of what's inside of that element this value Li which happens to be this new element that I've created a new list item so I've been able to add a new HTML element and this line of code is going to say add it to the Dom add it to the unordered list that I am here now constructing so now I rerun this I see tasks I type in something like foo I press submit and alright foo now shows up I type in something like a right to leave that type in bar bar now shows up I'd have been Baz Baz no shows up now one minor user interface annoyance is that it seems that every time I submit a new task this input field retains the value of what it used to be and that's probably not what I want because I'd rather it just clear out I've already submitted the task no need for it to stay there but that's easy to manipulate in JavaScript if I want to clear out this input field the input field whose ID is task then all I need to do is say document dot query selector task get me that input field change its value equal to the empty string equal to nothing just to say clear out the value of what happens to be inside of that input field right now and now if i refresh the page type in foo press submit input field clears out and now I can type in something like bar and then something like Baz to continue to add tasks as well now one thing that might be slightly annoying is that I'm not careful if I press submit well it submits the empty string is a task and so I just get this empty bullet point that shows up here nice press submit and I just get all of these empty bullet points it might be nice from a user experience perspective if I were to not allow the user to do that not allow them to submit a task if they haven't actually typed something in to the new task field and we can do that just by modifying properties of elements that it turns out that HTML elements have a property called disabled that can be true or false that allows us to disable something like a button so if I want to disable the submit button one thing I might want to do first is give this submit button an ID I'll give it an ID of submit so that in my JavaScript code I can reference the submit button and now inside of this JavaScript code when the Dom content is loaded by default the submit button should be disabled like when I first load the page I don't want the submit button to be enabled because I want the user to type in a task first before I enable the submit button so how do I do that well I can document query selector get me the element whose ID is submit get me that submit button and just said it's disabled property equal to true javascript has boolean values true and false I set the disabled value equal to true to disable the submit button now if i refresh the page I can type in a new task but the submit button is disabled it doesn't do anything now obviously I don't want to keep it that way I'd like it such that as I begin to type things in then the submit button stops being disabled disabled get set from true to false instead and so what I really want to do is listen for me like pressing keys on the keyboard and so the way I can do that is by adding yet another event listener document query selector what I want to add a query selector to what do I want to add an event handler for well I want to add an event handler for when I type something into this input field and this input field has an ID of tasks so let me go ahead and get the input field the element whose ideas tasks and add an on key up handler on key up again is the event when I lift my finger off of a key go ahead and run this function and what should the function do well it's going to say document query selector submit set the disabled property equal to false and so now here's what we're doing we're saying by default when I first load the page take the submit button and disable it said dot disabled equal to true then anytime I type a key and my finger comes off the key that means on key up is the event that gets triggered run this function and what the function is going to do is take that same submit button and set its disabled property equal to false so now instead of being disabled it will be enabled so if I go back to the page go here I type in it right now by default the submit button is disabled but as soon as I start typing something now the submit button is active and I can actually click on it and all right this isn't great because I clicked on it but the submit button is still enabled so what I might like to do is all right after I've submitted the forum after I've added a new task let's go back and disable the submit button so after I've submitted the form after we've added the new task to my list of tasks after we've cleared out the value from the input field let me also get the submit button set it's disabled property equal to true now even after I submit the form the submit button is still going to be disabled such that I type in foo now submit is active I press it but the submit button goes back to being inactive as well it turns out that even now there's still a little bit of a bug if I go back here and I type in something like bar but then I backspace back to like nothing here the submit button is still active so I can still technically submit a task that has no content inside of it and so I might like to have some way of preventing against that as well and that's just some additional logic we now have access to JavaScript that has conditions that has loops that has functions and so if I want to do something like conditionally check I can say if document query selector task dot value dot length is greater than 0 meaning like something's actually typed into the task field will then go ahead and set disabled to false but otherwise go ahead and set disabled equal the true so now here we're checking if the length of what the user has typed in is greater than zero they actually type something in then yes give them access to the submit button but otherwise don't give them access to that button so now i refresh the page disabled by default I typed something in it's enabled I delete delete delete and it goes back to being disabled so javascript has allowed us to really make our pages much more interactive and immediately interactive based on how the user is interacting with the page as they begin to type things as they begin to delete things as they press buttons we're able to have the page respond either by adding content to the Dom by literally adding parts to the HTML page of changing the styles of things changing particular properties of elements and this is really where the power of JavaScript begins to come in isn't allowing ourselves to do things like that now so far we've only been able to have events happen when the user does something when the user clicks on a button or when the user presses a key for example but it turns out JavaScript has other ways of allowing functions to run in fact on their own we can set what are called intervals where a particular function runs every some number of milliseconds for example and so if we go back to like the counter example from before right now for this counter example I have to be the one to press the count button that is going to increment the value of count every single time but I could put that inside of an interval instead so let me go back to counter dot HTML whose JavaScript is inside of counter j/s and now what I'd like to say is I would like when the Dom content is loaded let me set an interval for count and 1000 so what is that going to do set interval as a function built into JavaScript here where I'm saying that I would like to create a new interval where every so often go ahead and run a particular function and I would like to run the count function will recall that count function is going to increment the value of count and I'll get rid of this alert for now just for simplicity all I want the count function to do is update the h1 with the new value of the counter and go ahead and run that count function every 1000 milliseconds otherwise known as every one second go ahead and run the count function so now when I open counter dot HTML it's zero but every second now it's going to change every second updating one by one by one I don't have to click the button of course I could and the event handler would still work but the interval is saying now every one second go ahead and run the count function and that has this particular result so if you've ever seen a webpage that like displays the current time in seconds and like a countdown timer or is displaying the current time with seconds it might be doing something like this just having some sort of interval that every second is going to count and increment in order to say update the number to the one greater one greater and one greater than that of course if I close the page and go back to it if I close these pages and then open counter dot HTML again I've gone back to zero like JavaScript is not saving any state about my page it's just every time we're running the page it's going to go back to counter j/s it's going to say all right we're defining a variable called counter we're setting that variable equal to zero so every time I load the page it's going to be set back to zero and that might not be great depending on the type of page you're trying to create that maybe you want to page that is somehow able to store information such that on subsequent visits were able to utilize the information that was already stored some way of remembering information for later use in later versions of JavaScript and more modern browsers now allow us to do something just like that called local storage and what local storage is is it's a way for us to be able to store information inside of the user's web browser that a page can ask to store particular values inside the web browser and later on on subsequent visits to that page we can go back and say let's extract those values that were previously stored inside of local storage local storage it's going to give us access to two key functions that we're going to use to manipulate this local storage the first is local storage getitem where we would like to get something out of local storage based on its key some name that we have given to that value and we also have access to local storage dot set item which goes ahead and adds a new value to local storage or replaces an existing value in local storage setting this key equal to a particular value so we can use local storage then to allow our webpages using javascript to be able to store information and retrieve information from the browser and let's now try to use that in order to solve this problem of the counter that seems to always reset back to zero so now in counter jeaious instead of sending counter equal to zero the first thing I want to know is is there already a value for the counter in local storage so I can ask a question like if local storage dot get item counter meaning go to local storage try and get the counter and anything in this if expression will happen if there is something inside of local storage for counter but it turns out that if I want to do the inverse of that say not I can just use the exclamation point much like in C in JavaScript the exclamation point just means not so meaning if there is not something in local storage called counter well then let's go ahead and just set the value in local storage local storage dot set item counter and we'll set it equal to zero so what this is doing here is before anything else happens we are checking local storage to say is there already a value for counter and if there is not already a value for counter we need to make sure there is something there inside of local storage for the counter so we are going to set the value of counter equal to zero for example and so now what needs to change I'll go ahead and get rid of the interval so that it only happens when I click on it but what should this count function actually do well first let me get the value of the counter counter is going to be whatever local storage get item counter is I'm gonna get the counter out of local storage I'm going to increment it counter plus plus we'll go ahead and set the value of this h1 elements innerhtml equal to that counter but the last step is I'll also do local storage dot set item counter is equal to the new value of counter so what I've done here is to say that when I click the button count function is going to run we're first going to go into local storage get value for the key counter whatever the value of counter happens to be save it inside of this variable called counter we'll go ahead and increment that variable setting it equal to itself plus one update the h1s innerhtml same as before just to update what we actually see on the page but then go ahead and local storage set item counter gets set to counter for example so now let's go ahead and see what's going to happen if I go ahead and open counter dot HTML we see 0 we count 1 2 3 4 5 everything so far so good now watch what happens if i refresh this page i refresh the page and alright that seems a little bit strange at 0 let me try counting and see what happens i press count and alright the count changed to 6 so it seems like it did remember that i counted up to 5 0 1 2 3 4 5 but when i refresh the page it still showed me 0 but then let me count up to the number 6 and I can keep counting 7 8 9 10 what happens if i refresh the page now I can try it i refresh the page I've gone back to 0 but I count and okay now I'm at 11 so somehow I am still remembering but the first time it's still giving me 0 every time why might that be well if you look back at counter dot HTML you'll notice that the reason is just inside the body of the page the initial value of the h1 is just always 0 so if I want to fix that then what I need the same is when the Dom content is loaded go ahead and get document query selector h1 go ahead and update the innerhtml equal to whatever local storage get item counter happens to be so every time I open the page even before I click the button even before the event listener is triggered I'd like to say go ahead and replace this heading update its inner HTML to be the result of getting the counter out of local storage for example so now for refresh the page it's all at 11 I can update update update click again some number of times bring it up to 18 for example refresh the page and it stays at the number 18 and no matter what value I get it to it's going to store that number inside of local storage such that when i refresh the page that number is going to stay there we can actually see the value inside of local storage but again going into Chrome's inspector I go into Chrome if I go to the application tab and I go to local storage here on the Left I can see that I have a value for key counter whose value in this case happens to be 28 and you could go into local storage you can manipulate this value you could delete it if you want but this just goes to show you that we have now stored this value inside of my browser such that on subsequent visits if this page gets loaded again we can access that value from inside of the application as well and so now we've been able to see how our pages are able to store data in order to just make the user experience a little bit better if we want the user to be able to have information remembered from the last time they visited a particular page we can sometimes actually be quite helpful all right so now we've seen a lot of features of JavaScript we've seen a bunch of different ways of representing data we store data in variables and those variables have had types like integers those variables of sum has been strings and some times have been HTML elements sometimes they've been arrays or lists of our items sometimes they've even been functions so we can set a variable equal to a function but perhaps one of the most useful data types inside of JavaScript is the JavaScript object so go into the JavaScript console just to demonstrate this what the JavaScript object is is it's really the equivalent of like a Python dictionary some Association of keys to values where you can look up something by a key or by a property and see what his value happens to be so if I had a variable like person I could set person equal to a JavaScript object who's like first name is Harry and whose last name is Potter again using syntax very similar to what the dictionary syntax looks like inside of Python as well and now that I have this variable person which is first Harry last Potter I can access a particular property of the person in a number of ways I can say something like person dot first to say get me the first name property of this particular object and I see that it's equal to Harry I could equivalently use square bracket notation the way Python does square bracket first and that will also give me Harry but this turns out to be quite powerful to be able to represent data in this structured way like this where I have an association of keys or otherwise known as properties with particular values and then I have the ability given a JavaScript object to be able to access a particular value and it turns out that one of the ways this is most useful is in the exchange of data moving data around from one service to another and so here we're going to introduce what are known as api's otherwise known as application programming interfaces which in the context of the web you can think of as some well-defined structured way for services on the Internet to communicate with each other that if you want your application to be able to talk to some other service maybe you want your application to interact with Google Maps or to be able to interact with Amazon or some other weather service to get the day's weather then you might be able to access some API some mechanism whereby you can communicate with another service by sending a request and receiving back data in some sort of very well structured format and very often that well structured format happens to be a particular type of data known as Jason which stands for JavaScript object notation which is a way of transferring data in the form of JavaScript objects these sort of objects that happen to have properties and values associated with them and so what does javascript object notation look like well if we think back to the applications that we've been creating these applications that are able to represent things like an airline and many movements of planes between particular destinations a JavaScript object representing a flight might look something like this a JavaScript object that has properties for origin is something destination is something duration is something things we've seen before but you might imagine that if we wanted our airline to be able to make its data available to other services so that other web applications or other programs could programmatically access information about flights we could pass data in this format to those other applications so that they could then treat this as a JavaScript object and get access to the information about it and the nice thing about this particular representation is that it is both human readable and machine readable that we as people can look at this and get an intuitive understanding for what all of this means but also a computer knows how to access particular properties that appear before the colon and get access to what those values are which appear after that colon as well so JavaScript object notation otherwise known as jason offers a very convenient representation and this isn't exactly what the JavaScript object syntax is in JavaScript objects you don't strictly need the quotation marks around the keys you could just say origin colon and not origin in quotation marks so JavaScript object notation uses slightly different syntax but ultimately very reminiscent what we've seen in JavaScript objects and JavaScript knows how to take data in this form and turn it into something like a JavaScript object and turns out there ways of doing this in Python as well in other programming languages have the ability to interpret JSON data in order to use it in some meaningful way and another advantage of the JSON representation is it is very conducive to representing structures of things so these values don't just need to be strings or numbers they could be lists or arrays that happen have a sequence of possible values or they could even be other javascript objects that if we wanted to represent not just a city name but represent the city name and the airport code for example as we saw that we wanted to do before I could instead of having origin be equal to a string like New York have origin be equal to yet another JavaScript object that contains a city property and a code property where the city is the name of the city and the code is the name of the airport code and the important thing is as long as I and the person I'm communicating with agree upon this representation agree upon what the names of these keys are and what the structure of this JSON payload this JSON object happens to be then the person on the receiving end can take this data and write a program that's able to interpret it and use that data in some meaningful way and so we'll see an example of this now of using javascript to be able to communicate with yet another online service in particular for accessing information about currency exchange rates currency exchange rates are always changing we want access to the latest currency exchange rate data and if there is an online service an API that provides access to that data in JSON form in a format like this that is machine readable then we can use that data to write a stock a currency exchange application that uses real time data in order to make those conversions what might that data look like well the data could look something like this that we make a request for accessing what are the exchange rates for converting from US dollars of the West Newton is USD and we get back a JSON object that looks like this and it has a base key of USD and then has a rates key that has a whole bunch of rates within it so conversion to euros and Japanese yen great british britain pounds as well as Australian dollars and all of the various different currency exchange rates for all of these different currencies for example and this doesn't have to be the way that this data is structured but it happens to be a convenient way and so long as the person providing this data to me and I both know what this structure is we can begin to write programs that are able to use that data and so will now see our example of an API which is exchange rates API I owe and if we go to API dot exchange rates API am / latest and provide a get parameter of base equals US dollars then what we get back is data that looks like this now it's a little bit messy looking not nearly as clean as we saw before but it's the same exact thing just without the whitespace we have a JavaScript object that has a rates key that tells me all right here is the exchange rate between US Dollars and Canadian dollars in the pound in the euro and other currencies that exist as well and down below we have the base of what base currency we're converting from so all of this data can come back to me if I just make an HTTP request I make a web request to this particular URL I then get access to all of this currency exchange rate information that I can then use inside of my application so how can I do this how can I now begin to use this information inside of an application let's now create a new page I'm gonna call this currency HTML inside of currency about HTML at our usual HTML a title of currency exchange and a body and inside the body and we're just going to include nothing for now what I really care about is the JavaScript that is going to make a web request in order to get access to additional data so far in JavaScript our JavaScript code has exclusively been running code that exists only on our computer it's running inside the web browser and all happening inside the web browser we're not communicating with some external server what we'll take a look at now is something known as Ajax which was about asynchronous JavaScript where the idea is that even after a page has loaded using JavaScript we can make additional web requests to ask for additional information either from our own web servers or from some third party web servers if we want additional information on our page and what we want in this case is for our page to make an asynchronous request to request for additional data about the current currency exchange rates for example so how am I going to do that well I want to do this after the Dom content is loaded so we'll add that usually there and what we're going to take advantage of as a function built-in to more recent versions of JavaScript and supported by most major browsers now and if the function called fetch and what fetch is going to do is it is going to make a web request it is going to query some website it could be our own it could be someone else's and it's gonna get back some HTTP response from that page and I'm going to fetch in the page I'm going to fetch is this URL API not exchange rates API dot io / latest base equals USD and the only reason I happen to know how this API works is because I've read the api's documentation that describes how the URL parameters work and what the structure of the data that I get back isn't and so I'm here going to say go ahead and fetch from this URL make a HTTP request asking for additional information from this URL and get back what the results are going to be and what fetch gives back to us is something in JavaScript known as a promise and a promise is going to be a way of representing the idea that something is going to come back but it may not come back immediately we're not going to go into the details of exactly how those promises work but it turns out there's a particular syntax for dealing with them which is that I can say after I fetch I can add a line called dot then that says what should I do when the promise comes back once I get back something like a response and so when I get back the response what I want to do is convert the response into Jason treat it as Jason data Java a JavaScript object as something that I can then manipulate and so what I can do is just use this as a function to say go ahead and return response Jason and so what this is saying is go ahead and get me the latest exchange rates and then after that's done this is an asynchronous process it might take some time but once I get back those results then run this function take the response and return the jason version of the response convert that response into just the raw JSON data such that I can use that data to then access the currency exchange rates and it turns out that with arrow functions if you ever have a very simple function that all it's doing is taking something and returning something else I can simplify this function even further and just say I can omit the curly braces I can omit the return I can just say response arrow response Jason and this is a shorthand way of saying a function that takes as input the response and returns as output response to Jason so here I'm saying go ahead and fetch me in the latest exchange rates from this particular API then convert the response to Jason data and then once you have the data here's what I want you to do with that data and for now let's just go ahead and console dot log that data just to print it out to the terminal so we're not doing anything else to us yet all I'm doing is saying get me the exchange rates convert the exchange rates data into Jason and then let's go ahead and print out that data so I'll open up currency at HTML it's a blank page but if I look in the JavaScript inspector I see what got logged is a JavaScript object here indicated by the word object and if I click the triangle at left I can open up and see all right inside of this object is all of this data about exchange rates for a whole bunch of different exchange rates for converting from the US dollar we're here u.s. dollar one means one u.s. dollar is one u.s. dollar for example so now that I've got this data let's actually try and use this inside of the program maybe let's say I want to convert between US Dollars and the to figure out what the conversion rate is between dollars and euros well if we recall what the data looks like the data is a JavaScript object where we have a key called rate and inside of rates is this object and inside of that object I can access the EU our property to get the exchange rate of one US dollar is equal to some number of euros for example so it's inside of the rates key and then inside of the EU our key and that's how I know what to get access to inside of my data so what I really want to do is access data dot rates dot EU R it says get me to all the data that came back access the rates key and then access the euro key and we'll go ahead and save that in a variable called rate and now I'll just document query selector body dot innerhtml equals rate just like take that rate put it inside of the body so now if i refresh currency dot HTML what I see is just this value 0.9 zero eight eight four three which means that right now one u.s. dollar happens to be equal to about zero point nine one euros for instance so that's useful I could make this a little more human-friendly by putting this inside of a template string I could say one US dollar is equal to and then rate euros for example and so now if i refresh the page I see one u.s. dollar is equal to this many euros and even this is a little bit annoying I probably don't care about it too this many decimal places and some really in the mood to be very precise about these exchange rates if I only care about it to like 3 decimal places for example it turns out JavaScript has functions I can use on numbers like rate dot two fixed passing in three as an argument there to mean I'd like to take this exchange rate and just round it to three decimal places for example so now i refresh the page and I see one u.s. dollar is equal to zero point nine zero nine euros and the interesting thing about what's happening here is this is happening as a result of an asynchronous request I am asking for the latest exchange rates and when I get back the exchange rates date javascript is plugging that information into the body of the page I now communicating with an API getting back that api's data in JSON form and then using that data to update the contents of my HTML page of course in practice if I really want a currency exchange web page I probably don't just want to display the exchange rate between US dollars and euros I probably want to let the user pick what currencies they would like to exchange between and so here's how I might go about doing that inside of the body of the page now rather than just have an empty body let's go ahead and add a form that form is going to have an input whose ID is currency just so I have a way of referencing it later the place holder will just be currency and the type of it is text and then I'll have an input whose type is submit and we'll give it a value of convert that'll be what the button says it says convert and then I can convert to a particular currency and then I need some place to put my results so I'll go ahead and add a div whose ID is result and this is where after I've done all the currency conversion this is where I'm going to put the results of doing that currency conversion so now rather than fetch right away here's what I need to do I need to do something only when the form is submitted so I can get the form by saying document query selector form dot on submit equals this function and I'm gonna go ahead and just in advance return false at the end of the function so we don't actually try and submit the form to another page I just want to run everything locally on this same page but now inside of this form once you submit it that is when I want to run this code that is going to fetch new data so I'm going to fetch data from the exchange rates API convert that data to Jason same as before then go ahead and get access to that data but now what I want to do is I want to figure out what the user actually typed in to the input field and that is going to be the currency that I care about getting access to so I'll create a variable called currency which will be equal to document query selector and I write the input field if I scroll down it has an ID of currency so if I want to get that input field I'm to say get the element whose ID is currency and get its value so this now is the currency that the user wanted me to get access to and I can then say data rates currency instead of data rates dot you are and importantly I can't do data rates dot currency that would literally try to access a property of rates that is called currency if I use square brackets instead that allows me to use a variable something like the currency variable which are defined up here on line 13 as the currency that the user typed in I would like to access that particular currency inside of the rates and so now I can ask a question there are two possibilities here either the currency the user typed in it is a valid currency or it's not and it turns out that if you try and access a property of an object that doesn't exist what you get back is a particular JavaScript variable called undefined meaning there is no value there so for example if I have something like let person equal first name is Harry and last name is Potter like we did before I can access something like person dot first and get Harry I can access person dot last and get Potter but if I access person dot middle that is going to be a special variable in JavaScript or a special value in JavaScript called undefined meaning there is no value there it's slightly different from null which also has a similar meaning they're used in slightly different contexts so here what I can say is if the rate is not undefined well then let's go ahead and update not the body but the result to say one u.s. dollar is equal to this rate not necessarily euros but whatever the currency happens to be and otherwise let's go ahead and document query selector result dot inner HTML equals invalid currency just to let the user know that the currency they tried to provide is not actually a valid currency and so we're going to need to try a different currency in order to get the all to work so now here's what we can do if I open up currency dot HTML again I now see a form where I can type in a currency I can type in something like the Europe for example press convert and I see alright one u.s. dollar equal to 0.9 0.0 something like the pound press convert one u.s. dollar equal to 0.77 one pounds I type in the Japanese yen one u.s. dollar is equal to 109 point eight five two Japanese yen and all of this is happening where every time I submit the form it's making yet another request so if the exchange rates happen to change in between when I submit the form the next time I submit the form I will be getting the latest exchange rates according to that exchange rates API and the results are going to come back here and of course if I type in a currency that doesn't exist I type in something like foo for example and press convert invalid currency so it's going to report back to me that it wasn't able to find that currency and so it tells me that I need to type in something valid and so I can type in something valid maybe I try just US dollars itself it tells me one u.s. dollar is equal to one US dollar exactly what I would expect it to be now there are a couple of optimizations and improvements that we can make here one is that I can search for euros right now with EU our press convert but if I search for euros in lower case for example it turns out it thinks that's an invalid currency and the reason why is because if you look at the data that comes back to me from the API this is the data that I get back from the exchange rates API what you'll notice is that all of the currencies are all in capital letters that are all capital letters all capital letters which means the only keys that I'm allowed to access are in fact those that have capital letters in them because these are the only keys that this API makes available to me so if I want to convert between US dollars and euros lowercase what I might want to do is first take the currency the thing the user typed in and first just call to uppercase on it which is a JavaScript function that takes a string and converts it Dabra case I'd like to take whatever the user typed in and now just first convert it to uppercase that way if I go back here I can type in Euro lowercase press convert and I'm still able to get the correct conversion rate the other thing that we won't noticeably notice the difference with is that right now I'm assuming that all of this is going to go successfully that we're gonna successfully be able to make a web request will successfully convert the response back to Jason but you never know an API could go down the API could change and do something unexpected and so anytime you're dealing with these types of promises where you fetch something and say then do this then do that it can often be a good idea to add one last case which is a catch case that basically says what should you do if something goes wrong so I can say catch the error and what I can just do is say like console dot log error and then log the error there and all that's really saying is that if anything above goes wrong with the fetching and trying to process the response it's gonna catch the error and then we'll just like print out to the console that something went wrong some error message happened and so that can be a helpful nice to have just to make sure that when things crash they crash in a predictable way that you're able to see exactly what the error is and just by looking inside the JavaScript console and so now we have a fully working web page that is able to communicate with an external API that is able to ask for information from another service on the Internet use those results and put them back into the page really just going to show the power now that we get by taking advantage of the JavaScript language we have the ability now to not only use JavaScript to be able to run code on the client where we weren't able to before were right before we only had Python code that was running on a web server but using JavaScript the really powerful thing is now the ability to manipulate the dog the ability to use JavaScript to take the page and change the contents of the page by updating things by reading what happens to be on the page whether it's inside of a particular element or what a user happened to type in and using that in conjunction with event handlers ways that we can listen for when the user clicks on something or when the user Scrolls through something or when the user types a key to be able to respond and therefore make our webpages all the more interactive next time we'll continue our discussion of JavaScript looking at how we can leverage the features of JavaScript to continue to build even more interesting and engaging user interfaces so we'll see you next time
Info
Channel: CS50
Views: 237,188
Rating: undefined out of 5
Keywords: cs50, harvard, computer, science, david, j., malan
Id: x5trGVMKTdY
Channel Id: undefined
Length: 111min 25sec (6685 seconds)
Published: Mon Jun 21 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.