Placeholder Image

字幕列表 影片播放

  • SPEAKER 1: All right, this is CS50, week 10.

  • And you'll recall that last time we introduced

  • one of our additional languages in CS40, that of SQL, Structured Query Language.

  • And this, recall, was a language that we used to query databases, insert data

  • into databases, delete, update, and more,

  • so that we actually have a way of persisting data

  • once we built a web-based application, or really any other application

  • that we want to be able to store data long-term.

  • And we had such statements as create for creating a database or a table, insert,

  • select, update, delete, and a few others as well.

  • And with these relatively few building blocks,

  • we're able to start building a back-end for a web service.

  • And indeed weeks ago when we first implemented a front-end for Google,

  • simply by implementing that web form, we didn't really

  • have anything to do with the data or anywhere to query for data.

  • But now we actually do via our own database in the form of SQLite

  • and via this new language, SQL itself.

  • But today we introduce really the last of our formal languages in CS50.

  • Recall that we began the semester with Scratch,

  • transitioning quickly thereafter to C where we spent a lot of the semester.

  • We have since pivoted to Python of course,

  • whose syntax is quite different, but whose ideas

  • are really fundamentally the same.

  • Today we transition to JavaScript.

  • And JavaScript you'll find is more syntactically similar probably

  • to C than it is to Python itself.

  • So you'll see that a few more parentheses are back,

  • perhaps some semi-colons as well.

  • But what's most important today is that really the fundamentals of programming

  • aren't changing.

  • But rather the method via which we actually execute or run this code.

  • In particular, thus far, when we've written

  • C code, when we've written Python code, all of that code has run on the server,

  • so to speak, within CS50 IDE or maybe on your own Mac or your own PC

  • if you have some prior programming experience.

  • But today we introduce a language that is generally, though not always,

  • used within the client, the browser.

  • Which is to say the code that we start writing today--

  • and when you generally use JavaScript in order create front-end user interfaces,

  • you will find that the code you write, like HTML or CSS,

  • is actually sent to the user's browser where it's executed, again

  • client-side, on the Mac on the PC.

  • It is not executed server-side.

  • Now to be fair, JavaScript can be and is increasingly used on the server-side

  • as well via frameworks called Node.js, if not others.

  • But we'll focus predominantly on client-side usage thereof.

  • And you'll see that you can start to do some pretty powerful things,

  • because not only now do we have the ability to have a dynamic back-end that

  • serves up data and searches things for us,

  • but a front-end that gives us all the better user interface and features

  • still.

  • So I was thinking back yesterday on when I first started using JavaScript.

  • And it was in a very, very small isolated instance.

  • But way back in the day-- and this is thanks to the wayback machine,

  • you may recall Frosh IMs was something I did in college.

  • Not so much in sports but more the website.

  • And this was essentially the layout-- apologies-- of the Frosh IMs website

  • some years ago.

  • Now this actually post-dates me by a few years,

  • since it seems the codebase actually survived me by quite a few years,

  • surprisingly.

  • But early on, when you would hover over these menu options at top right,

  • those would have what are called event listeners attached to them so

  • that when you hover over some of those menu options,

  • the color would actually change.

  • And I think they shifted positions slightly.

  • So [INAUDIBLE] ultimately took over the site and took it further than that.

  • But this was my first taste of JavaScript.

  • And it was just to give the website a sense of dynamism

  • and to give it a sense of interactivity that wasn't possible, certainly

  • not at the time, with HTML alone.

  • So let's do a quick compare and contrast of JavaScript

  • with things we've seen in the past, just to kind of bring ourselves up

  • to speed on some of the syntax.

  • But you'll find we need to spend relatively little time

  • on the syntax and the language itself, because you'll

  • find syntactically it's so similar.

  • And so instead we'll focus more on ideas and new features of the language

  • itself.

  • So as in C and in Python, we have the ability

  • to express functions in JavaScript.

  • They look a little bit different, at least at first glance.

  • But fundamentally they're really the same.

  • In JavaScript, if we want to function, we're

  • going to use the keyword function to say,

  • hey browser, here comes a function followed by the function's names,

  • zero or more parameters, and then between the curly

  • braces a bit of code that implements that function.

  • So gone is the ability to just indent your code

  • and have the interpreter know what you mean.

  • Those curly braces are back as are more parentheses for us here in JavaScript.

  • But in terms of loops you should find this fairly familiar.

  • In JavaScript if you want to iterate over something again and again

  • and again, the do while construct is actually back.

  • So we have something very similar here as we do in C.

  • And what you use that loop for can be any number of things.

  • But we do have that capability again.

  • Similarly, do we have while or while true loop here,

  • which would induce an infinite loop.

  • And again, these are the kinds of things that might trip you up unnecessarily

  • at first, but quite reasonably.

  • Like if you start capitalizing true again,

  • it's not going to work in JavaScript.

  • So again, reasonable people will disagree when

  • it comes to designing these languages.

  • And so the authors of JavaScript decided to lower case true and false,

  • where again in Python we've been capitalizing recently, true and false.

  • Meanwhile, if you want to declare a loop using a for loop, that is back.

  • But you'll notice perhaps implicit in this example

  • is the fact that JavaScript is, like Python, not strongly typed.

  • It does have the notion of data types.

  • And you can access or look at those data types.

  • But you don't have to specify them as the programmer

  • when you're declaring variables.

  • Rather, in the case like this, when you're

  • declaring a counter like I, which should be an integer from 0 up to 50,

  • you literally say, var, for variable, than the name you want to declare

  • and then just the rest of the syntax is as we've seen before.

  • Meanwhile, there's another handy feature-- and you'll see this in use

  • in various examples perhaps online-- is the very easy ability, like in Python,

  • to iterate over the keys in an object.

  • So recall that an object, at least in Python,

  • is really just a collection of key value pairs.

  • But it's an object can also have methods inside of it.

  • But if we focus entirely on data, keys, and values,

  • this syntax here would allow you to iterate over all of the keys

  • and some value coming back.

  • So maybe if you have a stock object, you could

  • iterate over its name and its price and its symbol,

  • simply by using syntax like this, and an index into the object

  • to get at that object's value.

  • Meanwhile, variables are fairly straightforward.

  • To declare a variable like I, we would say var I equals 0, and a semi-colon.

  • Boolean expressions, meanwhile, are with us still.

  • And these are no different.

  • I is less than 50 might be expressed with this.

  • X is less than y might be expressed with this.

  • So nothing new there.

  • Meanwhile with conditions, we have syntax identical to C.

  • So again, the curly braces are necessary,

  • at least if you have multiple lines that you intend to be associated

  • with the if or the else if or the else.

  • Again we're back to, else space if, instead of L if in Python.

  • But again, there's nothing really new here in terms of content, really just

  • syntax.

  • So after practice and after some trial and error,

  • you'll generally find that it becomes second nature.

  • Meanwhile, we have arrays in JavaScript.

  • So for instance, if we want to declare an array called numbers,

  • again we don't specify the type of this array or the members therein.

  • We simply say var, to give us a variable,

  • number shall be the name of that variable.

  • And then a list here of arbitrary numbers themselves

  • nested in between square brackets.

  • So in JavaScript, as we've seen in Python,

  • we have the ability to express lists or arrays specifically

  • in JavaScript that simply use square bracket notation to define them

  • in a context like this.

  • Meanwhile, speaking of objects a moment ago,

  • we have that same ability in JavaScript to declare them.

  • So for instance, if we wanted to declare an object, and we'll call it quote,

  • we use, as in Python, curly braces.

  • And I say as in Python because in Python really

  • when I say object, focusing entirely on data,

  • I really mean a Python dictionary or dict object, which again

  • is this collection of key value pairs.

  • We don't necessarily do things quite the same way.

  • But in this case here, var quote is a way of porting,

  • say, from a CS50 finance example, a company's name

  • and its price and its symbol.

  • And worth noting here, that as in Python, you actually

  • have choice over the quotes that you use, at least in this context.

  • Single quotes are fine.

  • Double quotes are fine.

  • So long as you are stylistically consistent,

  • it's probably fair to say that many people in the JavaScript community

  • tend to use single quotes here.

  • There's no functional difference as there is in C.

  • However, they do matter, as you'll perhaps

  • eventually see, when you're using not JavaScript per se, but JSON notation.

  • JavaScript Object Notation, which is a simple data

  • format not unlike CSV, but that allows you to store a hierarchical data

  • inside of an object.

  • And the subtlety there is that when you want to store data in this JSON format,

  • you have to quote literally everything with specifically double quotes

  • on the left and on the right.

  • So it's an annoying distinction.

  • And don't fret too much about it now.

  • But just realize any time we're talking about JSON

  • and a technology called AJAX-- more on that soon-- it's

  • got to look like this with the double quotes

  • on both sides of the colon for those key value pairs.

  • Now with that said, let's start to give ourselves some context.

  • Let me introduce a few features that we've kind of sort of seen in Python--

  • didn't necessarily leverage, but are going

  • to be really integral to the way in which many people use JavaScript

  • within browsers.

  • So here, for instance, is that old simple example

  • of HTML, perhaps the simplest web page that we can write,

  • that quite simply says in its title and its body, hello world.

  • And recall that the indentation here is functionally meaningless.

  • The browser doesn't really care how pretty your HTML looks, just

  • nicer for us humans to see everything nested and nicely indented,

  • because it's just a lot easier to read.

  • And it's also a lot easier to detect if you type something wrong, if something

  • doesn't really line up as you expect.

  • But another way, recall, of viewing this same piece of HTML

  • is in the form of a data structure like a tree, which

  • we discussed way back when in the context of C.

  • And we might draw this same example of HTML

  • with a Dom, document object model, which is a fancy way of saying tree.

  • And that tree might look like this.

  • It's got some special root node that we'll just generically call document,

  • because there might actually be some other stuff like comments

  • or whatever up there.

  • But the root element of a web page, recall, is HTML.

  • The second thing you type is open bracket HTML.

  • The first thing you should type with HTML5 is open bracket doc type HTML.

  • So you can think of the doc type as meaning this node essentially,

  • and the open bracket HTML close bracket meaning this root element.

  • Of course this page here has both a head and a body.

  • That head a title, and that title has a text value inside of it,

  • or a text node so to speak as does the body that happens to be identical.

  • So what's nice about this mental model is that if we tie everything together

  • from weeks past, sort of the markup language of HTML

  • and the data structure of trees and specifically this Dom

  • here, it turns out that you have the ability with JavaScript-- something

  • we didn't have in C really and didn't really

  • have with Python-- but the ability to change this tree in real time.

  • After a browser has downloaded some HTML from a server,

  • typically that content has been static.

  • You can open up Chrome's console in the elements tab and futz with it manually,

  • but those changes aren't persistent, even though you see them.

  • And certainly no user, or no typical user is going to do or know to do that.

  • But you the programmer, if you want a user

  • to be able to download some web page, but then interact with it

  • and have that content change-- very similar in spirit

  • to something like Gmail, whereby every time you get an email,

  • a new row in your inbox appears without the whole page

  • having to reload and certainly without you having to click Reload.

  • Or something like Facebook Messenger, where no matter the time of day

  • if you have Facebook open in a tab, it's just going to pop up a message

  • and keep adding to that little window-- another line, another line,

  • another line of text.

  • So there's this dynamism you get that you can't get from HTML and CSS alone,

  • but you can with JavaScript.

  • If you think of it just intuitively, if you have the ability

  • to run code inside of a user's browser, you

  • could have essentially kind of a while loop that's just constantly waiting.

  • Did the server send me more data?

  • Did the server send me more data?

  • And if so, go ahead with an if condition and write more text to the web page.

  • Write another message in the little Facebook chat message.

  • Write another row to the Gmail inbox.

  • And that's what we're going to get and more with JavaScript.

  • And it turns out, with JavaScript, can we listen for a whole bunch of events

  • so to speak.

  • I eluded to an event, a listener being attached earlier.

  • And this is just a small sample of the events

  • that can be triggered within the confines of a web page.

  • So unlike our Python programming thus far, and unlike our C programming,

  • we have in JavaScript this asynchronicity.

  • Multiple things can kind of sort of happen at the same time

  • or really at unpredictable times because users, of course,

  • are interacting now with our web pages.

  • And who knows when or where a user is going to click.

  • Who knows when he or she is going to click and drag something

  • across the screen or select some menu option or click check some checkbox.

  • So we can't really just write a program top to bottom in JavaScript

  • as we've done in the past per se.

  • Rather, we have to start writing code that says, if I hear a mouse click,

  • or if the user drags their mouse, or if the user checks a checkbox,

  • do something.

  • So kind of like if this then that, if this then that.

  • So a lot of conditions.

  • But it turns out that it's relatively simple

  • to register functions-- that is, associate functions

  • with these various events.

  • And so for instance, when you check a box in Gmail and all of a sudden

  • the row becomes a different color or whatnot,

  • that's because there's an event listener for the click event

  • that Gmail is saying, as soon as the user clicks

  • this event go ahead and change the color or change the interface in some way.

  • Or if you click the little X in the top right-hand corner of a Facebook chat

  • window, the reason it goes away is because there's

  • a click event happening.

  • And Facebook has written code that listens for that click event.

  • And as soon as they hear that event, they close the window

  • and remove it from the web page altogether.

  • So Google Maps, for instance-- drag is an event.

  • So if you've ever kind of wondered, well,

  • how do I click and drag in Google Maps and they just know to show me

  • more of the map, whatever direction I'm clicking in, they're

  • listening for the drag event.

  • And so this is where things get really interesting with GUI side programming--

  • graphical user interface programming.

  • There's this whole event model, where a bunch of events, a bunch of things

  • can happen at any number of times.

  • Or at any point in time.

  • So let's offer a few general definitions of terms and features of JavaScript.

  • But let's actually discuss them in the context of examples.

  • So JavaScript supports and really, really leverages,

  • typically things called anonymous functions,

  • otherwise known as lambda functions.

  • And these quite simply are functions that have no name.

  • And that seems a little strange.

  • But we will see contexts in which functions don't need names

  • if you're only going to call them once, or if you only

  • need to refer to them really once.

  • So we'll see how to declare and define a function that doesn't actually have

  • a name like foo or bar or whatever.

  • Meanwhile, we're going to see a methodology involving callbacks,

  • which is very similar in spirit to the events I rattled off a moment ago.

  • Whereby a call back is just a function that's

  • supposed to get called when something happens.

  • So in other words, Google and Facebook with those user interfaces,

  • they are registering functions.

  • Really, they're registering callbacks, so that when the user clicks on an X

  • or when the user clicks on a checkbox, or when the user clicks and drags

  • on a map, they have in advanced register a function that gets called back.

  • It's like leaving a message for someone on voicemail.

  • They call you back in response to that voicemail.

  • They call you back in response to the beep

  • that their phone makes when they've received that.

  • So it triggers some kind of functionality, these callbacks.

  • Callbacks are just functions that have been

  • configured to be called at a certain point in time when something happens.

  • Now meanwhile, and lastly, we'll talk about

  • AJAX, which isn't a technology unto itself

  • but a use of various existing features within browsers

  • that allow you to query from a browser, a server

  • to get more data even after the original page has been loaded.

  • Let me go ahead here and create a file called, say, Dom 0 dot HTML.

  • Document object 0 dot HTML just to line up with some of the examples

  • that we'll place online for everyone to play with.

  • I'm going to go ahead and start my page as I usually do.

  • And I'm going to go ahead and say HTML.

  • And then in here I'm going to have a head tag

  • and in here I'm going to have a title tag.

  • And I'm just going to call this Dom 0 for simplicity.

  • Down here I'm going to a body tag.

  • And in here I'm going to have a form.

  • I'm going to give this form, similar in spirit

  • as we did in our discussions of CSS, a unique ID, simply

  • so that I can refer to it as a demo, a demonstration.

  • But let's come back to what more I want to associate with that.

  • First let me go ahead and give it an input, an ID of names

  • so that I can refer specifically to this input field.

  • Let me give it a placeholder of name.

  • And let me say that the type of this field

  • is a text field to close that tag.

  • And then input type equals submit.

  • So a very, very simple web page that looks like this.

  • Now what could go wrong if I present a user with a web page like this?

  • Well, he or she might not give me their name.

  • They might just click submit and this form

  • is going to get submitted to some server.

  • Well that doesn't seem all that great, because I don't have a chance to check,

  • did they actually type in a name?

  • I don't have a chance to do something with it on the client.

  • And indeed that's now the new feature we get with JavaScript.

  • Notice what I can actually do.

  • Let me go into the head of this web page,

  • where thus far we've pretty much only put the title tag.

  • We've put the link tag for CSS.

  • And you may have seen with CS50 Finance that we also

  • had a script tag that referenced a library called Bootstrap,

  • and another one called Jquery.

  • More on those in a bit.

  • But indeed, inside of the head of a web page can go with script tag.

  • And you know what, inside of a script tag

  • can go code, specifically JavaScript.

  • And in here I can define a function, literally.

  • I'm going to call it, greet, just to kind of say what it does.

  • And inside of this function I'm going to do the following-- alert,

  • quote unquote, hello, comma, world, semi-colon.

  • So this is how in this example I've defined a function called greet.

  • I've put it inside script tags, open and closed inside

  • of the head of this web page.

  • Now, nothing's going to happen with that unless I

  • tell the browser to do it on an event.

  • So I'm going to go into my form tag here and say on Submit,

  • go ahead and execute the following code.

  • Go ahead and call the greet method and greet function,

  • and just for good measure return false.

  • But more on that in a moment.

  • So again, my function's defined up top.

  • But nothing happens.

  • Again, when you define a function, nothing automatically

  • happens until you call it.

  • So when am I going to call it?

  • On the form tag here, I have an on submit attribute,

  • which is new today, that says, call the greet function and then return false.

  • But again, more on that in just a moment.

  • So what actually happens here?

  • Let me go into another window, open up DOM 0.

  • And you'll see, if I now zoom in on this form,

  • will see that it's a very simple HTML form with just a name

  • field and a submit box.

  • And if I go ahead now and type in my name, David and click Submit,

  • hello world.

  • So it's not actually saying hello, David, it's just saying hello world.

  • But notice what happened.

  • This is a very bad user interface just using this built-in prompt.

  • But it demonstrates the built into JavaScript

  • are a bunch of functions, one of which is alert.

  • And that function is designed to do exactly this.

  • The window will look a little different if you're

  • using Chrome or Edge or Firefox or Safari or whatever other browser,

  • but you'll see that it simply says, hello world.

  • And it's going to say whatever the URL on your page happens to be.

  • In my case it's just this local IP address for lecture's sake.

  • But this isn't all that interesting to just hard code, hello world,

  • especially when I have the opportunity to take in a user's name.

  • So if I instead go back into my code here,

  • and don't just print out, hello world, but perhaps

  • concatenate with JavaScript's plus operator,

  • the result of this method call, document dot get element by ID,

  • quote unquote name, then dot value.

  • So that's a mouthful.

  • Let's see what this does before we explain what it does.

  • Let me go ahead and reload the page.

  • And now we see the same form again.

  • But this time I'm going to type in David and click Submit.

  • And now it says, hello, David.

  • So how does this work?

  • Somehow or other, I wrote code that not only alerts the user with this window,

  • but it somehow grabs data that he or she has typed in

  • and embeds it in this message.

  • Well here is where we can leverage the DOM, the Document Object

  • Model, and a bunch of functions that come with JavaScript that

  • allow you to programmatically get elements and get data ultimately

  • from a web page.

  • Specifically notice we're doing this.

  • We're calling alert, and then open paren close

  • paren because it's a function call.

  • Quote unquote hello comma, with a space.

  • And again, single quotes, double quotes, doesn't

  • matter so long as I'm consistent here.

  • Plus, which is concatenation, document doc get element by ID, quote

  • unquote name, dot value.

  • So it's kind of a mouthful and it's definitely verbose.

  • And we'll see before long slightly more succinct ways of expressing this.

  • But you can think of document as being this special global variable that's

  • just accessible to JavaScript code that you write.

  • And that really is that uppermost node in our tree,

  • that top-most node in our DOM.

  • And associated with that node, which is just an object,

  • are a bunch of methods or functions, that just come with JavaScript,

  • and that your browser just supports for you.

  • One of those is called get elements by ID.

  • And recall, we've used this jargon before.

  • An element in a web page is the combination

  • of an open tag and a closed tag and everything in between it.

  • So get element by ID quote unquote name means, hey browser,

  • go get me this entire element from start to finish.

  • And this is an empty element because we've

  • closed it within the it's own tag.

  • So that just means, go get me.

  • Kind of a pointer to that node in the tree.

  • There's no pointers in JavaScript.

  • So we should really call this like a reference to this node.

  • But it really just means that.

  • Go get me somehow this node in the tree.

  • And what do I care about once I have that node?

  • I care about its value.

  • So dot value, you can think of like syntax like a struct.

  • That means, if you have this node now, via get element by ID, go inside of it

  • and look for the field with a property called value.

  • And that's going to line up, it turns out, with exactly what the user types.

  • So I can do this again to be clear.

  • Let me go up here and for instance type in Andy and click Submit.

  • And voila, now it says hello, Andy.

  • But now the browser-- and this is perhaps a curse from 10

  • and 20 years ago when people started to abuse JavaScript and give you

  • hundreds of popovers so to speak, hundreds of

  • prompts if you visit a website that's trying to mess with you.

  • Chrome and other browsers will let you check a box like this,

  • prevent this page from creating additional dialogs,

  • just because it thinks that maybe the page is buggy, maybe it's malicious,

  • and it's really just pestering you as these things are annoying.

  • But at least during CS50 development for P-sets projects,

  • don't check this because it'll only confuse if the page no longer does

  • as you tell it to do.

  • Fortunately that doesn't come up too often on actual websites.

  • All right.

  • So we seem then to have the ability to not only get data

  • from a web page programmatically and display it dynamically.

  • But can we design this code a little better?

  • Well it turns out that we technically don't need

  • to co-mingle our code and our HTML.

  • And notice too there's one other line of code here that's a little sloppy.

  • I mean literally between these double quotes

  • do I have two statements-- greet, which is a function call,

  • and then return false.

  • The reason I had return false is that if I didn't, after clicking Submit

  • and submitting this form, the only thing stopping

  • this form from just being submitted to the server is return false.

  • This says, hey browser, even when the user tries to submit this form, don't.

  • Return false.

  • The default is true.

  • Otherwise, if I didn't have return false and I click Submit,

  • I would see that alert as expected, but the moment I dismiss it,

  • I'm going to be led to some other web page, presumably wherever

  • the form is going to be submitted, which coincidentally

  • happens to be the same page.

  • But now that we're developing client-side applications,

  • client-side web apps, we don't necessarily

  • want forms to be submitted to the server.

  • We want to use them, for now, only within the confines of a browser.

  • Indeed there is no back-end, there is no action attribute

  • for this particular example.

  • But this feels messy.

  • Any time in CS50 when we've introduced some new language like CSS

  • in the context of HTML, or our HTML in the context of Python via our Jinja

  • templates, did we try to factor out one language from another, so as not

  • to blur these worlds and make the code very messy, very unmaintainable.

  • So how can we begin to remove, from these quoted values,

  • code, but still have this feature of listening for a form submission?

  • Well let me go ahead and propose another variant of this program,

  • that I'll go ahead and call DOM 1 dot HTML.

  • I'm going to start with the code from before,

  • but I'm going to make a few changes.

  • Instead of putting it in the head of my web page, for now,

  • I'm actually going to put it down here in the body.

  • More on that soon.

  • But instead of even declaring this as a function,

  • I'm going to instead simply do this.

  • I'm going to get rid of this event handler.

  • So now all that remains up here, to be clear, is just pure HTML.

  • I still have those ID attributes so that I can uniquely

  • identify those forms and that form and those inputs if I want,

  • or that input if I want.

  • But notice what I can do now.

  • Document dot get element by ID quote unquote demo, because that's

  • the name of my form, dot on submit, gets function open paren close paren.

  • And then just for stylistic purposes, let me go ahead

  • and do this, which is what most JavaScript programmers would do.

  • So what am I doing now?

  • Now I have pure HTML appear.

  • But to be fair, I now have a script tag inside of which is code.

  • But at least I've removed the code from like an attribute, which

  • just looked or felt a little sloppy.

  • And look at the code now, document dot get element by ID demo.

  • So this gives me essentially a reference to the entire form, not just

  • that name field.

  • And it turns out that provided that node in the tree is a form,

  • and indeed it is, that has associated with it a property

  • by the definition of HTML5 called on submit.

  • This is a property, that if you assign it the value of a function,

  • that function will get called when the form is submitted.

  • And yet what function do I want to Call Well, function open paren close paren

  • seems to omit a key detail that we've seen in Python and C, which

  • is the name of the function.

  • But here's an example where I don't care what the name of this function is.

  • I don't need to know the name of this function.

  • Because all I need is a function, a chunk of code that will ultimately get

  • executed when this form is submitted.

  • And that line of code is identical to what it was before.

  • So just to be clear, this anonymous function, so to speak that I'm using,

  • is not strictly necessary.

  • If I really wanted to, I could do something like this.

  • I could declare a function called greet, just as before.

  • And I'll format it exactly as I did before.

  • And I could declare this right up here.

  • And then down here I could say, greet.

  • In other words, the on submit handler just

  • wants to know what function to call.

  • So fine.

  • If I find a function call greet, I can tell on submit to call greet.

  • Notice, no parentheses here.

  • I don't want to call the greet function when that line of code is executed.

  • Rather, I want to assign that function, which

  • you can think of as a variable unto itself to this on submit handler.

  • But why?

  • This hasn't really gained me anything.

  • Yes, it's nice that it's called greet.

  • But I'm defining a function called greet only to configure my browser

  • to call that function one line later.

  • The nice thing about anonymous functions is that you

  • can just kind of tighten things up.

  • Why clutter your namespace so to speak?

  • Why fill up your brain with names of functions

  • that you're never again going to need?

  • And so more common and cleaner, better design arguably,

  • would be something like this.

  • All right.

  • And actually just for good measure because this

  • is all part of a statement, in this example

  • let me put that semi-colon there.

  • So the example is going to work exactly the same.

  • Indeed if I go back to my browser and go into DOM 1

  • dot HTML and type in something like summer and click Submit.

  • Hello, summer.

  • And so it behaves exactly as before.

  • And for good measure, let me go ahead and change the title here

  • to match the name of the file.

  • But now let me go ahead and open up an example

  • I wrote in advance, like many of these, called

  • DOM 2 dot HTML, the code for which admittedly

  • is much more cryptic at first glance.

  • And indeed the syntax will take some getting used to.

  • And you don't strictly need to do things this way.

  • But a super popular library in the world of JavaScript today to this day

  • is something called jQuery.

  • And indeed the bootstrap library with which

  • you're now acquainted by CS50 Finance actually uses,

  • for some of its features, the jQuery library.

  • So let's introduce the syntax so that you've seen it, so that you can use it.

  • But realize, this is not giving us any new functionality.

  • It's just giving us a different syntax.

  • And over time, you'll see that jQuery, like certain other libraries,

  • it tends to make it more pleasurable, more efficient to write JavaScript,

  • because you can do things a little more succinctly.

  • The price you pay is a little bit of complexity.

  • So let's take a look syntactically at this library called jQuery.

  • Notice, in DOM 2 dot HTML, I have this URL up here.

  • There's any number of places to get the jQuery library and libraries more

  • generally.

  • But this one happens to be hosted, for instance, at this URL.

  • And it's the latest version thereof.

  • And this attribute source simply says, hey browser,

  • go get the JavaScript code that I want to have access to from this URL,

  • and assume that it's equivalent to my having written in this web page

  • itself, like our other script tags thus far.

  • Meanwhile, after that, an order is generally important

  • when including things like this.

  • Let me go ahead and do the following.

  • Up here notice that I have this line of code,

  • which generally is a good thing to have because it

  • says the following to the browser.

  • Hey, browser, when the document is ready--

  • that is, when the whole web page has been loaded,

  • when all the bytes have come back from the server,

  • please go ahead and execute the following code.

  • And we'll see that this allows us to ensure that things don't

  • happen sooner than we actually expect.

  • Specifically, let's do the following.

  • When the document is ready I want the browser to execute

  • the following lines of code that I've highlighted here--

  • dollar sign, quote unquote, hash demo.

  • It's kind of a mouthful.

  • But this is simply reminiscent perhaps of the CSS syntax

  • that you might be familiar, that simply says, hey browser, go

  • get me the element from the DOM, from the tree representing this page, that

  • has a unique ID of demo.

  • So hashtag demo is just a more succinct way of saying,

  • document dot get element by ID.

  • You can do this all in just a few characters.

  • And the dollar sign here is a feature of jQuery.

  • It's actually just a synonym for jQuery.

  • Dollar signs can actually be variable names.

  • So dollar sign quote unquote hash demo means, hey, browser,

  • execute the equivalent of document dot get element by ID, quote unquote demo.

  • Just more succinct, even though it's a little bit cryptic at first glance.

  • Meanwhile, submit, not to be confused with on submit submit-- submit

  • is a function that per jQuery's documentation says,

  • hey, browser, register the following event handler for the submit event.

  • The way you do this is you provide the library

  • with an anonymous function, which in this case I've just said function.

  • It takes one argument.

  • And I would only know this from having read the documentation.

  • Function takes an argument that we'll call event.

  • But we can call it call it anything we want.

  • And then inside of this code, what do I want

  • to do when the demo form is submitted?

  • Well, I want to use alert.

  • But I want to paste in this value.

  • So again, just new syntax here.

  • And it's fine if you prefer the other syntax for now.

  • Dollar sign quote unquote hash name, means

  • go get the element from the DOM that has a unique ID of name,

  • and go get its value using this method call.

  • So jQuery essentially does this. jQuery wraps existing elements in a DOM.

  • It goes ahead and adds like another bigger rectangle

  • around those smaller rectangles that give you

  • additional features, among which is the ability

  • to use these CSS-style selectors, among whose features is to call like dot val

  • and get the value without having to do dot value,

  • which isn't all that compelling in this case.

  • And then we're appending, in this case, an exclamation point for good measure,

  • just so to show that we can to continue to concatenate beyond one string.

  • And then lastly, is this, which granted, more verbose-- event dot

  • prevent default just means, hey, browser,

  • whatever your default behavior is for handling forms, don't do it.

  • Prevent it, because I want to handle this form submission.

  • So this is a really long way of saying, this is another way

  • to implement exactly the same program that we did earlier,

  • albeit with an added exclamation point, which

  • has nothing to do here with jQuery.

  • So why is this a good thing overall?

  • Well one, your code will actually get shorter over time.

  • But it's fine if you'd rather not use this.

  • But this first line was actually rather important.

  • If I instead were to implement this code like this, there's actually a problem.

  • And actually there's a problem even if I were to do it this way.

  • If I were to go back to DOM 1, and I were

  • to do something like this in this example, and not use jQuery at all,

  • but just, in my head tag, have a script tag that has this code here,

  • there's a problem of the order of operations.

  • On this first line, when I say document dot get element

  • by ID quote unquote demo dot on submit, assign that listener this function,

  • it's too soon.

  • Because the browser at this point in the story

  • literally is reading the file top to bottom, left to right.

  • And the browser has not got to the line of code,

  • where in this form, and its demo ID is actually defined.

  • So this would actually be broken, in so far as the browser's reading

  • it top to bottom, left to right.

  • But it sees this code and it says, hey, browser, go get the element by ID demo.

  • There is no element with that ID at this moment,

  • because it doesn't come until later.

  • So a way of solving this using just JavaScript,

  • is you could do something like the following.

  • Window dot on load get function, and then you could do something like this,

  • albeit fairly verbosely.

  • So that would work.

  • Hey, browser, when the whole window is loaded,

  • then please call this anonymous function.

  • Or we can use jQuery which frankly tends to be

  • more common, at least when using other libraries as well,

  • which says that exact same thing.

  • And in fact, a little bit more than that via this line of code here.

  • So just another way of doing something, another form of syntax.

  • But we won't necessarily assume that or complicate things

  • by using that library syntax along the way.

  • All right.

  • So now that we have the ability to access data inside of my web page,

  • specifically in forms.

  • And I have the ability to alert the user,

  • it would seem we can actually create useful features,

  • not silly little programs that just say hello, world, or hello, David.

  • What if I now started updating past examples

  • to do client-side form validation?

  • In the past, a couple of weeks back, when

  • we did like the Frosh IMs website, or really any website

  • that submits data-- maybe CS50 Finance, if the user doesn't cooperate

  • and doesn't give me a valid symbol or doesn't type his or her name

  • or password or the passwords don't match in the case of registration,

  • the data gets submitted to the server nonetheless

  • and then your Python code thus far has been using an if condition

  • or l if or whatever to check if the user provided the data that you expect.

  • And if not, you apologize to them in some way

  • by just printing out some message to the screen.

  • That's a lot of work.

  • If you can anticipate that something is wrong,

  • why bother sending all of that data or lack thereof to the server,

  • letting the Python code figure out what's wrong

  • and then wait for this response to get back,

  • even though frankly, it happens pretty fast on today's internet, certainly

  • on campus.

  • That's a lot of unnecessary work if you have

  • a programming language like JavaScript that

  • allows you to run code in the browser.

  • Let's open up an example that we did in the past

  • wherein we just have a form that asks for a user's

  • name, their password, their password again,

  • and then has a checkbox by which they can agree

  • to some terms and then a Submit button.

  • And you'll recall that in the past we might have used something

  • like this to have them register.

  • And then we said, no, not really, because we didn't actually

  • have a back-end at that point.

  • But a lot of things can go wrong when we present the user with this many things

  • to do.

  • Now we know from Python, we can catch these things,

  • and we can apologize and display an error message on the screen.

  • So we have all of that program added capability.

  • But what if we could create a better UX, user experience.

  • A lot of websites do fancy things these days

  • like, they don't actually submit the form

  • and then show a big erroneous message with a cat.

  • Instead, they just show the text box into which

  • you were supposed to type a value into in red, or green if you got it right.

  • Or a little alert message saying, you need

  • to give us a longer password, or your name, or your email,

  • or your passwords don't match.

  • But you can do all this instantly on the client side,

  • if we somehow can hook into this HTML.

  • So all of these inputs can be uniquely identified,

  • especially if we go at our own IDs.

  • So let's see if we can't take things up a notch

  • and actually write some code that validates a form like this.

  • I'm going to go ahead and do the following.

  • Inform 1 dot HTML, our next version of this program.

  • We'll start with where I began, with just a simple form.

  • But below this form, just for now so we can get things started,

  • I'm going to go ahead and have a script tag.

  • I'm going to declare a variable called form and call document dot get element

  • by ID quote unquote registration.

  • Why?

  • Well, I'm going to go ahead up here and add an ID that equals registration.

  • And again, here I'm using double quotes in HTML,

  • even though both single quotes or double quotes are allowed.

  • Down here I'm using single quotes, mostly

  • just to be conformant with convention.

  • But you can certainly stylistically do whatever you want with both of these.

  • Now I'm going to do form, which is just an HTML form,

  • and say on submit, get function.

  • So in other words, hey, browser, when this form is submitted,

  • call this anonymous function.

  • But again, the fact that the function is anonymous

  • really is not an interesting detail.

  • It just means it has no name.

  • This is the chunk of code that will be called when this form is submitted.

  • All right.

  • What do I want to do?

  • How about this.

  • If form, its e-mail field has a value that equals

  • equals quote unquote, that's a problem.

  • Let me go ahead and just alert the user, missing email.

  • And because we don't indeed want the form to be submitted, let me go ahead

  • and return false.

  • Else if, form dot password equals equals nothing--

  • the so-called empty string-- then let me go ahead

  • and alert the user that we're missing their password.

  • And then let we return false so that the form does not go through

  • because it's not ready to go through.

  • How about else if form dot password dot value.

  • Oops, and up here I need value as well.

  • Otherwise you get the element from the DOM,

  • you don't get the value inside of that rectangle.

  • Else if form dot password dot value does not equal form

  • dot confirmation dot value.

  • And why confirmation?

  • Well, if I look back at my HTML, the first field was called e-mail.

  • The second field was called password.

  • The third was called confirmation, even though it's

  • also a password field, because that's where I want the user's password again.

  • But if those passwords don't match, let me tell the user,

  • passwords don't match semi-colon return false.

  • Now wait a minute, my color-- my syntax highlighting is all messed up.

  • Why?

  • So this is a common gotcha.

  • If I just want to use English grammar in this case,

  • don't is the right spelling there.

  • But because I have quotes just like in C or in Python

  • when you've used double quotes inside of double quotes,

  • you're going to confuse the program in this case.

  • And so I need to escape this.

  • But as in other languages, escaping a back quote here is as simple as this.

  • Or if you don't really like that because it just

  • looks a little ridiculous and a little harder to read,

  • we could switch to double quotes here.

  • But again, just because I'm using single quotes everywhere else,

  • I'm going to stick with single quotes and escape it.

  • But again, you could make an argument either way.

  • Ouch.

  • There's still that checkbox.

  • And that checkbox, let's see, was called agreement.

  • So it turns out in JavaScript you can express that as follows.

  • Else if it is not the case that the form's agreement checkbox is checked.

  • So it turns out, associated with checkboxes

  • in JavaScript is a property called checked

  • that's going to be true or false.

  • So if that's not checked, I'm just going to tell the user as much.

  • Checkbox unchecked, and then return false.

  • Otherwise, if none of these checks fail, and I get all the way through all

  • of these if's and else if's and nothing seems to be wrong,

  • you know what, the form is ready for submission, return true.

  • And so now it actually makes a little more sense perhaps,

  • to return false or return true, because in all of these erroneous cases

  • you want to return false.

  • But if everything's OK, by default, we're just going to return true.

  • And the browser's default behavior in that case

  • is going to be to go ahead and submit the form to the server.

  • So let's try that.

  • Let's go into form 1 dot HTML.

  • Notice that if I zoom up here, we have more fields than before.

  • E-mail, password, password, again I agree in register.

  • So let's try this.

  • Let me go ahead and say, no, I'm not going

  • to give you any of this information.

  • So let me click Register.

  • Missing email.

  • All right, fine.

  • I'll cooperate and give you at least my e-mail, mail in at Harvard dot edu.

  • Let me click register now-- missing password.

  • Now there's the additional checkbox there

  • because now Chrome, or your browser more generally

  • thinks that, maybe this website's buggy or it's

  • being malicious or annoying at best.

  • Let me not check that box, otherwise none of the rest of the demo will work.

  • All right.

  • I'll give you a password.

  • Register.

  • Passwords don't match, that's because I didn't type it again.

  • So let me type the same password again over here.

  • Nice.

  • Ah, checkbox unchecked.

  • All right.

  • Agree, register.

  • Ah, and it even wants to save my password, but not really.

  • So where did this actually go?

  • Well just to show you what's going on behind the scenes,

  • notice that the action attribute of the past couple of forms

  • have been slash register.

  • Well it turns out with today's examples, I'm actually currently running Flask.

  • And inside of there I have a couple of routes.

  • We're going to use one of those in just a bit.

  • For now I'm just using this one here.

  • I have a route for slash register, that calls

  • a function register that simply renders a template called register dot HTML.

  • So where did that text come from?

  • Again, this is just stuff from a couple of weeks back.

  • If I go into registered dot HTML in my template's directory, it's just that.

  • You are registered.

  • Well not really.

  • So we're not focusing on the back-end.

  • We're not focusing on Python.

  • We're not focusing on Flask.

  • But I do have it running right now, so that we can see what

  • does happen if the form is submitted.

  • But that could be any server in the world.

  • It could even be Google if we're building that search engine again.

  • I just need something running there.

  • Let me go ahead and show you just an alternative take on this form, version

  • two, that does things using jQuery.

  • Again we won't dwell as much on this.

  • But do get familiar with the syntax, because you'll see it everywhere

  • online.

  • This says, hey, browser, when the document is ready,

  • go ahead and associate this anonymous function

  • with the submit handler of the form with this unique ID.

  • And then here a slightly different syntax by which you can select

  • fields on the web page.

  • Let me wave my hands at that for now.

  • Because again, you can go with the DOM-specific functions

  • we've been using thus far.

  • Or when the time comes, just read a little more

  • closely some of this code here.

  • But this is the equivalent code in jQuery,

  • which is just a library that just gives you different ways of expressing things

  • in JavaScript.

  • But this form is pretty ugly, right?

  • Like, this is really not something to write home about.

  • This also does not suggest the best error

  • handling if every time I do something wrong

  • I just get this ugly looking alert.

  • Can I make something prettier?

  • Well we certainly could with JavaScript alone.

  • And I could certainly write some HTML, some CSS,

  • and a whole bunch of JavaScript myself and get

  • a much better UX, user experience.

  • I could get a much better aesthetic to the site,

  • so that maybe we print some red text or green text,

  • depending on whether the user is cooperating.

  • But that's a whole lot of work.

  • And honestly, there are millions of websites out there these days.

  • Surely someone else has had to validate a form before,

  • and he or she has done it with JavaScript,

  • and he or she has been nice enough to make their code freely

  • available as open source online so that the rest of us making

  • the other millions of websites can stand on their shoulders

  • and not reinvent that wheel.

  • And indeed, just like in Python, there's lots and lots of libraries,

  • and lots and lots of frameworks, so in JavaScript it's there the same.

  • So it turns out, if I go into form 3 dot HTML,

  • I have a slightly prettier version that is using the bootstrap library.

  • There's no banner or menu or anything like.

  • I kept it pretty simple here.

  • But just by adding a little bit of more HTML markup, and a little more CSS, can

  • I stylize my form to be much prettier.

  • Indeed in CS50 Finance we had much nicer forms than the previous few examples

  • because we used Bootstrap, though you could use most

  • any other library that's out there as well just

  • to make the forms a little prettier.

  • But I'm adding one additional library.

  • This one that supports Bootstrap, so that if the user doesn't cooperate

  • with this version three, notice they can't even click Register

  • without the following happening.

  • Red email, please fill out this field.

  • Red password, please fill out this field.

  • And by the way, not long enough, because it's not even any characters.

  • Password again, please fill out this field.

  • Checkbox unchecked.

  • So you can immediately give much prettier output to the user

  • without using that sort of a lame prompt that's just going

  • to pester the user again and again.

  • And even though there's still an opportunity,

  • I think, to improve the aesthetics, this is much more akin to web 2.0.

  • So modern websites that are using these and other libraries to just create

  • better user experiences.

  • So let's cooperate now.

  • M-A-L-A-N. And notice, whoops.

  • That's not even my email address.

  • The error message now goes away entirely because the field is not blank.

  • All right password, 1, 2, 3, 4, 5.

  • OK.

  • It's now no longer telling me to please fill it out,

  • but it's still not long enough.

  • All right.

  • 1, 2, 3, 4, 5, 6, 7, 8.

  • Eight characters seems to be enough.

  • All right.

  • Let me go ahead and type in foo bar baz.

  • Passwords don't match.

  • OK.

  • 1, 2, 3, 4, 5, 6, 7, 8.

  • That one now matches.

  • And finally, I agree.

  • So we get so much functionality for free.

  • We could implement all of that ourselves using just the primitives we've

  • looked at thus far, just our understanding of where JavaScript

  • has to go in the web page, just our understanding of how to write functions

  • and if conditions and for loops and while loops or whatever.

  • But it's not interesting work.

  • If I'm trying to build a finance website or a final project more generally,

  • I don't really want to focus on form validation.

  • I want to focus on my own intellectual property, my own ideas, my own project

  • itself.

  • And so in form 3 dot HTML is a few additional things.

  • Not only have I included the Bootstrap library at the top,

  • as you might have noticed in CS50 Finance, as well as the latest

  • version of jQuery, and Bootstrap's own JavaScript, I've also included--

  • and I found this just by Googling around.

  • A very nice person made his or her code available at this URL.

  • And there's documentation online.

  • And he or she based it on Bootstrap so that if you

  • want to use Bootstrap and have pretty error messages, that you don't

  • want to think about creating yourself.

  • You can use their library.

  • And indeed, notice how I changed my HTML.

  • It's a little more verbose to be fair, but you'll

  • remember some of this from maybe your log-in form

  • or registration form from CS50 Finance.

  • Most of this just comes from Bootstrap and you're using the classes

  • that they tell you to.

  • But there's a few fields here that control

  • how this new library is working for form validation.

  • Notice, on my input, not only do I have a Bootstrap class, which

  • I just read from the documentation and in the unique ID,

  • I've got a required attribute.

  • And by saying required, that's a clue, not only to the browser,

  • but also to this library specifically that I should not

  • be allowed to submit this form until this field is filled out.

  • Now notice down here, input class equals form control,

  • which is just a Bootstrap thing.

  • Data dash min length equals 8.

  • This is how that library knows that I, the programmer of this page,

  • wanted the user to type in a password that's at least eight characters long.

  • It turns out, in HTML5, you can prefix, or rather you

  • can invent your own attributes.

  • Any attribute that starts with data dash, and then

  • some other sequence of characters can be your own custom attribute

  • that does not come with HTML itself.

  • So a lot of libraries, this one among them,

  • use those data attributes in order to configure themselves.

  • In this case, it's configuring itself to use a minimum length of eight.

  • That's also required.

  • Down here it's a little more advanced.

  • But I just figured this out by reading the documentation.

  • Down here, notice, I've got that confirmation text box that's

  • also an input with a Bootstrap class data dash match

  • equals hashtag password.

  • So this is-- and you'd only know this from the documentation of the library--

  • this is how the author decided to let us configure this text field in such a way

  • that it must match this password field.

  • And you know what, data match error-- I would only know this too

  • from its documentation.

  • But the way the author designed his or her library is if there is an error

  • and the passwords don't match, this is the read text

  • that I want the library to display on the screen.

  • And though it's cut off, this field too is required.

  • And meanwhile the checkbox, if we scroll to the last feature here,

  • that too has been prescribed as required.

  • And notice, I've also added some divs here and there, help block with errors.

  • This is not some fundamental HTML thing.

  • This is, again, just the author of the library who's

  • decided that wherever you, the programmer,

  • put a div with these classes, the library will plop those

  • read error messages.

  • So they don't have to be right there.

  • You could centralize them at the top of the screen.

  • You could put them in a banner at the bottom or wherever you want.

  • You have some programmatic control.

  • And so this library is implemented in JavaScript,

  • though we haven't written any additional JavaScript code because this author has

  • been pretty clever and is using special HTML attributes

  • to configure his or her library.

  • And it suffices, at the top of the page, simply to include that library.

  • And it has been written, probably with a line of code like document on ready.

  • Like when the document is ready, search the HTML for those special tags

  • and make sure that this form shall be validated accordingly.

  • So this is what's really exciting about JavaScript and Python as well,

  • and any of these higher level languages is just how many features

  • you get access to for free, without having to implement them yourselves.

  • How you use them is going to totally differ.

  • And indeed, part of the process of making a final project or a web

  • application or a mobile application in general,

  • is using a fundamental understanding of programming

  • and loops and conditions and functions and so forth, but then googling around

  • and looking up documentation that empowers

  • you to do other things with that understanding,

  • using other people's code.

  • So again, the goal is not to absorb all of this en masse,

  • but rather to realize the fundamentals, the ingredients by which we

  • can configure and do things ourselves.

  • Let me go ahead and propose now this example.

  • So back in my day, when I first learned HTML, for better or for worse,

  • mostly for worse, there was a blink tag.

  • So someone back in the '90s thought this was a good idea.

  • Let's empower people to have blinking text on their screen for everyone

  • to see.

  • There was even worse, perhaps, or as bad,

  • like a marquee, where you could scroll text across the screen

  • from left to right or right to left-- I forget which direction-- and that too

  • felt like a good idea at the time that has since been removed as well.

  • But it invites an opportunity, I dare say, to reimplement this feature,

  • even though browsers do not support the blink tag now.

  • But I can figure out how to do this.

  • Right.

  • What's going on?

  • There's some big text on the screen, that's roughly centered.

  • So I can probably use some CSS for that to make it big and bold and centered.

  • It's blinking on and off.

  • Well what does it mean to blink on and off?

  • Again, reduce this to first principles.

  • What capabilities does a browser have?

  • Clearly to display text, also to display colors, we have seen.

  • So maybe the act of blinking, hello, world,

  • is really just a matter of hiding it, showing it, hiding it, showing it.

  • Maybe there's a way to do that.

  • And indeed there is in CSS.

  • Or maybe it's still there, it's just going black to white to black to white

  • to black to white.

  • So it feels like, so long as I have the ability to kind of sit-in a loop, maybe

  • even an infinite loop if this just keeps going, and every second or so,

  • every half second go ahead and change from black to white, to black to white,

  • or hide show, hide show.

  • I just need to kind of commingle these capabilities of JavaScript and CSS.

  • And right now I can't stare at this anymore.

  • So let's go ahead and open up blink dot HTML and see how I implemented this.

  • So here's a body tag.

  • Here's a div tag that has unique ID greeting.

  • And then, hello, world as my text.

  • So the HTML to this page is super simple.

  • If I scroll just a little bit, this is why that text is now centered and big.

  • So 96-point, I decided, pretty arbitrarily,

  • just to make big centered text on the screen.

  • What about the JavaScript code?

  • It turns out with JavaScript, just as you

  • can gain access to data in the page, so can you gain access to CSS in the page.

  • And in fact, even though we won't dive in underneath the hood

  • of that library for Bootstrap that made our text fields read,

  • how did it make our text fields read?

  • Well, if we really looked underneath the hood, that library,

  • upon seeing that you didn't type your name or your passwords don't match,

  • it changed underneath the hood the CSS of my web page

  • to go from default colors to red or to green or to whatever.

  • But how did it do that?

  • Well, it turns out that browsers have the following capability--

  • one, to declare functions.

  • And we know that already.

  • Two, to get elements by their ID.

  • And we know that already.

  • And here I'm just declaring a variable called divs,

  • so my code's a little more succinct.

  • But it turns out that elements on a web page,

  • certainly divs, which are just big rectangular divisions of the page,

  • have a style property associated with them.

  • And a style property, in this case, lines up with that div element,

  • CSS properties, if any.

  • And if I want to change the visibility of this div style,

  • and visibility happens to be a CSS property that we haven't necessarily

  • used, but if you googled around you'd see an online reference

  • of available CSS properties.

  • If the visibility of this element equals equals hidden,

  • I'm going to make it visible.

  • Else, I'm going to make it hidden.

  • So if visibility is hidden, make it visible.

  • Else, if the visibility is visible, make it hidden.

  • For whatever reason, the opposite of visible in CSS is not invisible.

  • It is hidden, which makes this a bit of a mouthful.

  • But this if block here, this if else, really is just saying, if visible,

  • make it hidden.

  • If hidden, make it visible.

  • So just toggles the state, so to speak, from one to the other.

  • But why would this function operate more than once?

  • There's no loop.

  • There's no for loop, no while loop, no do while loop, nothing.

  • Look at this last line of code.

  • It turns out that in JavaScript you have the ability

  • to do things again and again with a clock that's running inside

  • of your computer, essentially.

  • Window dot set interval is a function you can call in JavaScript that says,

  • hey, browser, call this function every 500 milliseconds.

  • So couldn't quite glean it before visually.

  • Every half a second, call this function, call this function, call this function.

  • And notice again, as before, when I'm passing around a function by its name,

  • I don't want to do this.

  • If I said, blink open paren close paren, that would call the blink function,

  • and it's only going to call it once.

  • I instead want to pass this function by its name.

  • In C we would call this a function pointer.

  • In JavaScript we call it by reference, passing in the name of this function

  • to set interval.

  • So that set interval knows later what function essentially

  • to append parentheses to, so as to call it every 500 milliseconds.

  • Now how that's implemented, I don't know.

  • I don't care.

  • It's abstracted away from me.

  • But set interval is a function that comes with the browser that probably

  • has some kind of infinite loop that knows

  • to check every 500 milliseconds what's going on underneath the hood.

  • So this is to say, in JavaScript, we have the ability to control CSS.

  • And indeed, if we now think back retrospectively,

  • that must be how that bootstrap library was doing the form validation

  • and making my fields red when I did something wrong.

  • So you have another feature in JavaScript called local storage.

  • This is relatively newer, but it's a way, on a website,

  • of storing information for the long term, in a user's browser.

  • So in CS50 Finance, and in Web Programming with Flask more generally,

  • we had the ability to store data in sessions.

  • And that's fine.

  • But sometimes it'd be nice to store data locally inside of the user's browser

  • so that you don't have to remember states on the server side.

  • So that you don't have to contact the server to get that information.

  • And so this is particularly common in web applications

  • that you kind of want to be able to run offline.

  • Right.

  • It's increasingly convenient, especially on mobile devices,

  • to be able to run those web pages when you're not connected to the internet,

  • when you're underground or on a plane, so long as you

  • loaded the page in advance.

  • So with local storage, you actually have exactly that feature in HTML

  • to store information locally.

  • So let's take a look at this page does and then

  • we can deconstruct how it's doing that.

  • If I open up storage dot HTML, notice that it says in the top corner--

  • and I'll zoom in, just the number 0.

  • If I reload, and reload, and reload-- and to be clear, all I'm doing

  • is reloading by using my keyboard-- and reload, and reload, and reload,

  • the counter is going up.

  • But why is that happening?

  • Well, let me go back into the IDE and focus on these lines of code here.

  • If it's not the case that there is an item called counter

  • in this special global variable called local storage, then you know what,

  • set an item called counter equal to zero.

  • So local storage is really just a JavaScript dictionary-- an object

  • that's accessible globally to you.

  • Now we've not seen this before, and it's not all that common to need,

  • but I did it just so I could display something dynamically in the web page.

  • You can call it document dot right, which is similar in spirit

  • to prints in Python or print F in C. But, again, we don't really

  • print to the screen as much as we change values

  • or HTML as we've done in the past.

  • So we won't really use this too often.

  • But for now, I just want to write local storage dot get items return value

  • when I ask it for counter.

  • But then, and this is the key detail.

  • Every time I print or write that value to the screen,

  • I want to go ahead and reset the item, called counter,

  • to the result of calling parse ent on local storage

  • dot get item dot counter plus 1.

  • So long story short, local storage is going to store key value pairs for you,

  • but as strings.

  • And that's fine, because like quote unquote one, quote unquote two

  • is still useful, but parseInt is a function built into JavaScript

  • that's going to allow me to parse this string that I get back

  • and convert quote unquote something to an actual integer

  • so that I can then add 1 to it and set it back.

  • So this example is only to say, there is an ability

  • to store data locally in the browser.

  • And this is a fundamental alternative, especially for offline mobile apps,

  • to storing data in sessions on the server side.

  • But things get much cooler, quickly.

  • In fact, let me go into geolocation dot HTML, which

  • creepily wants to know my location.

  • Not my location in the sense of the IP address.

  • I'm seeing the IP address of my computer here.

  • You'll see something with CS50 dot IO or the like most likely.

  • But this is standard prompt that Chrome and Edge and other browsers

  • will trigger if a browser is running JavaScript code that is creepily

  • trying to get your GPS coordinates.

  • So it's a good thing that there's privacy defenses in place.

  • And you really see this on Android and iOS,

  • which don't let apps do anything without your permission typically.

  • But I'm going to go ahead and let it know my location.

  • I'm going to go ahead and click Allow, and see what happens.

  • It's taking a moment.

  • The computer is thinking.

  • I am apparently at GPS coordinate 42.38 comma negative 77.11.

  • So that's my latitude and my longitude.

  • Now that's not all that interesting unto itself,

  • but let me go to something like maps.google.com.

  • Turns out you can search by latitude and longitude.

  • OK.

  • We didn't have to go very far to triangulate my position there.

  • There we are, roughly in the middle of the building, Sanders Theater

  • here in Cambridge.

  • So that's kind of cool.

  • This is all to say that a browser can apparently infer your location.

  • Now why is that useful?

  • Well if you're building a website that is designed to show maps

  • to the user like Google Maps or MapQuest or Yahoo Maps or Bing

  • Maps or any number of tools, it's kind of a nice feature

  • to just let the user see where he or she is in the world by default,

  • rather than just showing them the generic United

  • States or the whole globe.

  • It'd be kind of nice to at least show them the general area.

  • And indeed, that's exactly what happened when I went to Maps.Google.com.

  • It knew, within some range, where I was already, even before I typed this in.

  • If you're implementing Yelp or some restaurant review site

  • or something like that where you want to be able to find something near you,

  • it's nice to not have to have me, the human, type in my GPS

  • coordinates, which I certainly would never know.

  • And it's nice to not make me type in Cambridge, Massachusetts or New Haven,

  • Connecticut or whatnot, which is in 06511.

  • Rather just let the browser actually figure out where I am, so long as I

  • consent to actually doing that.

  • I did get that right this time, right?

  • OK.

  • So why is this a useful thing?

  • So this, of course, is useless.

  • Like, who cares what GPS coordinates I'm at?

  • Not all that useful unless you want to target me right now in a map.

  • Rather, we can do something more interesting.

  • So we need the ability to actually get a map.

  • Thus far I have no ability to pull down pictures of maps.

  • But what if I could make a website, that after downloading some HTML and CSS

  • and JavaScript, what if, ala Google Maps, I could go get maps of Cambridge,

  • go get maps of New Haven or wherever I am in the world

  • and display them to the user.

  • And better yet, what if I could then use the drag event

  • and actually get more of that map-- whatever's off the screens

  • above, to the left, to the right, or below me,

  • when that user clicks and drags.

  • Drag being one of the events we can listen for.

  • Well it turns out, as mentioned earlier, that browsers today support

  • AJAX, which is formally called asynchronous JavaScript in XML.

  • But people don't really use XML for this anymore.

  • They use JSON, JavaScript Object Notation.

  • And this is ultimately referring to the ability of modern browsers today,

  • upon already having downloaded a web page and CSS and JavaScript,

  • to make additional HTTP requests from browser to server,

  • without having to reload the whole page, and certainly without the user

  • having to click Reload and then see a big blank screen for a moment,

  • after which they see content.

  • It can all happen dynamically.

  • So Facebook Messenger, Google Maps, Google Gmail

  • and so forth-- any number of websites you

  • use today, certainly the most modern of them, all use this capability.

  • So how do we go about using it?

  • Let me go ahead and open up a file called AJAX 0 dot HTML.

  • And here is now where honestly you want to use something like jQuery.

  • It tends to still be super popular.

  • There's other libraries that can do this for you.

  • But what you don't really want to do is start writing native browser code,

  • so to speak, that's specific to Chrome or specific to Edge

  • or specific to any number of browsers.

  • One of the nicest features about libraries today

  • is that there are so many stupid cross-browser incompatibilities whereby

  • reasonable smart people can disagree, and so different companies have

  • implemented browsers ever so differently in terms of JavaScript,

  • in terms of HTML, in terms of CSS.

  • So literally, you might build a beautiful looking website.

  • Spend hours and hours getting it to look perfect on your Google Chrome browser,

  • and you open it up in Internet Explorer or Edge or Firefox or Safari,

  • and damn it, it doesn't look right.

  • Something's off aesthetically.

  • It doesn't even work maybe.

  • It doesn't even load.

  • And so a lot of the process of getting websites just right

  • is certainly building them in the first place,

  • but then that last stretch is really about making

  • sure in testing that things work on multiple browsers.

  • So this is all to say, this is when it gets really useful to use something

  • like jQuery, because stuff like AJAX does get relatively simpler as follows.

  • Here is a web page that's including the jQuery library up top.

  • Inside of my own script tag now is a commented function called quote,

  • similar in spirit to what we might have wanted in CS50 Finance

  • if we were using JavaScript at that point.

  • Notice what I'm doing in JavaScript though.

  • Give me a variable called URL.

  • Set it equal to quote unquote slash quote, which looks like a route,

  • question mark symbol equals, closed quote,

  • plus which is concatenation, the value of the symbol field.

  • Now what is this?

  • Let me fast forward to the HTML down here in AJAX 0.

  • Pretty simple web form and I'm doing it old school here.

  • Form on submit, call the quote function return false.

  • And then have an input whose ID is symbol of type--

  • and it's a little cut off-- is text.

  • So what does this page look like?

  • If I go over to AJAX 0, and open this here,

  • it's a very simple web page that simply has

  • a text field with a placeholder that says symbol,

  • and then an HTML submit button that says get quote.

  • But I want this site to do is the following.

  • If I type in GOOG for Google's stock ticker symbol,

  • I want to know right now that it's worth $772.02.

  • If I type in something like Microsoft, that's $59.705.

  • So I'm getting another digit of precision from Yahoo Finance

  • as it turns out, as we'll see.

  • Netflix, get quote, $123.3405.

  • So in this case we're really getting some additional precision.

  • But all of that is immaterial at the moment.

  • What I really just care about is how this is working.

  • So again, when that form is submitted, the quote function is called.

  • And then it returns false.

  • And that's just so that it doesn't get submitted to a back-end,

  • because there is no back-end at the moment.

  • Rather, I'm using JavaScript to talk to my back-end as follows.

  • Var URL gets this URL equals this value.

  • And this value is whatever the user just typed in.

  • Me, like Google or Microsoft or Netflix.

  • So this a way, notice, of constructing your own path for an HTTP get request.

  • If you think back to week six, we know that you

  • can contact websites ultimately via this route, like slash quote.

  • The question mark is what separates the route from the HTTP query,

  • or the request parameters, the HTTP parameters that you're passing in,

  • one of which I've decided to call symbol.

  • And now notice what the jQuery library does for us, pretty straightforwardly.

  • jQuery comes with a method called get JSON.

  • Now what is this weird syntax?

  • Again, this is just JavaScript being cool, or jQuery being cool.

  • The dollar sign is literally a synonym for an object

  • called jQuery, a global object that happens

  • to exist because of this line of code.

  • But the author of jQuery, some time ago realized, dollar sign

  • is actually a valid character for a variable name,

  • which is not the case in C.

  • So you know what, I am just going to call my library's global object dollar

  • sign.

  • Why?

  • Well one, it kind of looks cool, but two, it's just much shorter to type.

  • You don't have to actually write out the whole word.

  • But that's all.

  • There's nothing syntactically interesting about this.

  • It's just valid variable symbol.

  • Get JSON does that.

  • It contacts a server at a certain URL and expects

  • to get back a JSON object, which we saw an example of a bit ago.

  • And what does it do?

  • It will call a function, in this case anonymous,

  • but that's an immaterial detail at this point.

  • And it will pass to that function a reference

  • to the data it gets back from the server.

  • So again, get JSON somehow figures out underneath the hood,

  • how to make an HTTP request to that URL that's passed in as the first argument.

  • And when the server finally replies, this anonymous function is called.

  • It's passed that data.

  • And then we call alert on data dot price.

  • So what is inside of that object?

  • Well I can actually simulate this.

  • Right.

  • If you understand HTTP, you can do all of this yourself.

  • My IP address happens to be on my local machine, 127.0.0.1.

  • And then I'm on port 80.

  • Your URL might be different, on CS50 IDE.

  • But what I do know is I can construct my own HTTP

  • request by just doing slash quote question mark symbol equals NFLX

  • and Enter.

  • And notice what comes back.

  • If I zoom in on that, this is JSON, JavaScript Object Notation.

  • Why does it look like this?

  • Well, the world just decided, we need a way

  • of standardizing how you get back data.

  • It's useful to get back data in terms of metadata keys,

  • and the actual values you care about.

  • So the world decided that JSON data is going

  • to start with a curly brace, end with a curly brace.

  • It's going to have a whole bunch of key value

  • pairs, which are separated by colons.

  • Each of the values, each of the keys rather, is quoted.

  • Each of the values is quoted if there are strings.

  • Otherwise if it's a number you can just write it like that.

  • Commas are separating each of those key value pairs.

  • And again, you must use double quotes in this context, which

  • is a long way of saying, this is what my slash quote route returns.

  • This is not a web page.

  • This is not my quote route from CS50 Finance, which was must prettier

  • and it actually had CSS and HTML and it said,

  • a share of Netflix costs such and such.

  • This is just raw data.

  • And this is where AJAX gets compelling.

  • AJAX is the use of raw data like that, you have programmatically

  • requested from browser to server, after the original web

  • page is already loaded, because you want to get more data for the user,

  • perhaps in response, as in this case, to his or her input,

  • like when I typed in Netflix or Google or Microsoft.

  • This web page isn't all that pretty though, of course.

  • Right.

  • It's ending up just using that alert.

  • And it probably is the case that we can do things a little bit better.

  • And indeed we can.

  • Right now, again, I've kind of regressed.

  • I should not slip into this habit.

  • It's fine for perhaps a lecture demonstration,

  • but let's clean this up right now.

  • If I go into AJAX 1 dot HTML, notice I've gone in and cleaned up my HTML.

  • No longer do I have some hackish call to a function semi-colon return

  • false inside of the value of an HTML attribute.

  • It's just bad design to do that.

  • It's fine to sort of get warmed up.

  • But let's get rid of that, clean up my HTML,

  • and now relegate everything to the top of a file.

  • I'm still using jQuery, but I need one additional line, recall.

  • Now I need this line here.

  • Because a browser reads my code top to bottom,

  • I want to make sure that this code is not executed until the page is ready.

  • Before, I didn't need to worry about this, because by the time

  • the browser got to my HTML, saw the on click or on submit attribute, rather,

  • and saw the code to execute, that's fine because everything else had already

  • been loaded.

  • But in this case, I have my code up front before the HTML.

  • So I have to say, hey, browser, don't do this, until you're actually ready.

  • What do I want you to do?

  • I want you to, as before, register a submit handler,

  • calling in this function, calling get JSON as before,

  • and then return false here.

  • As an aside, let me point out just one thing.

  • It turns out that putting your JavaScript code in your file, that

  • too is not generally good design.

  • Certainly as your pages get more involved

  • and your code gets more complex, just like in CSS

  • when we factored out our CSS, we should be

  • able to factor out our JavaScript code too.

  • So actually a better practice longer term and certainly with projects

  • would be to do something like this.

  • To take all of this code that I've written,

  • save it in a file called whatever, scripts dot js is perhaps common.

  • And then in my HTML page, don't just have this big open tag and closed tag.

  • Instead, go ahead and say something like this, scripts dot js.

  • In other words, have a URL or partial URL

  • that says to my browser, hey, browser, besides the page you're currently

  • reading, go get this file as well.

  • Execute any code in there and then proceed to run whatever's inside.

  • All right.

  • But-- but, but, but, I bet we can make this even cooler.

  • It is pretty, pretty lame to keep using these alerts.

  • What if instead we had this capability as well.

  • In AJAX 2 we have this example here.

  • Let me go ahead and zoom in.

  • And let me go ahead and type in NFLX for Netflix and click get quote.

  • I don't want that damn alert anymore, which is pretty hackish.

  • And again, it's going to look ugly and different on different browsers.

  • Let me click, get quote.

  • Woo, hoo, hoo.

  • Very nice.

  • So this time it seems to have embedded the response in the web page itself.

  • And that's going to change GOOG, get quotes, aka Alphabet, or Microsoft,

  • or whatever other company.

  • Somehow we're changing the page.

  • In other words, now we're not just using this out of band alert function.

  • We are changing our DOM.

  • And in fact, let me do this.

  • Let me reload the page to get back to original state.

  • Let me control or right click on Chrome and go into Elements.

  • As you may know here, notice that here in my web page,

  • apparently is a paragraph that we can't see,

  • because it's got no text inside of it.

  • It's just an open tag and a closed tag.

  • But notice the unique ID called quote.

  • And notice what happens.

  • I'll have to zoom out to see this.

  • But notice what happens.

  • If I type in like GOOG and click, get quote.

  • Don't watch the top.

  • Watch the bottom.

  • A triangle appeared, because now there's something inside of that.

  • So that sentence was dynamically inserted.

  • Let's try this again.

  • Let me try with Microsoft click, get quote, and my page's HTML is changing.

  • And it's also flashing it in purple just so Chrome

  • can draw your attention to it.

  • How about Netflix, get quote.

  • So this is where we're really now tying everything together.

  • We have the ability with JavaScript to get values from this field.

  • We have the ability with JavaScript via AJAX, which is just a use of JavaScript

  • to get more data from the server.

  • We have the ability with JavaScript to change my DOM, my web

  • page, which really just means change the HTML in that page, not permanently.

  • None of this is happening on the server, these changes here.

  • It's just in my own local browser.

  • And indeed if I reload, the changes go away.

  • But if you think of this sentence here as being like another row in your Gmail

  • inbox, or another message in your Facebook chat window,

  • that's all that's happening.

  • Now I might be just clobbering, that is deleting and changing

  • the previous sentence.

  • But there's nothing stopping me from just

  • writing every individual message to the screen again and again and again.

  • I don't have to overwrite it as I'm doing here.

  • So how do we do this?

  • So if I go ahead and open up now, AJAX 2 dot HTML, it's almost entirely the same

  • as before, except I am now embedding inside

  • of my DOM via these method calls, the actual data I want the user to see.

  • Indeed, this is saying, hey, browser, go get the HTML element

  • whose unique idea is quote.

  • Call a method associated with that, called

  • HTML, which we haven't seen before.

  • But it just literally changes the HTML of that element

  • to be whatever I pass in as an argument.

  • It's a long argument, but that's just the concatenation

  • of a bunch of strings-- A share of, plus data dot name, costs,

  • dollar sign data dot price, period.

  • Now, what is data dot name?

  • What is data dot price?

  • Well data is just the argument to the callback function, which

  • was, again, the anonymous function that I passed in the second argument

  • to get JSON.

  • Data dot name gives me the name therein.

  • Data dot price gives me the price therein.

  • If I really wanted the symbol again, I could

  • do data dot symbol, based on what we've seen inside of that object.

  • But, just like in C, structures, we just use the dot operator in JavaScript

  • to get at the properties of the data inside of an object.

  • Now again, the only way I would know how to do this with jQuery

  • specifically is by looking up its documentation.

  • And I would know that if I want to get JSON I called dollar sign dot get JSON.

  • I give it a URL, which I've constructed here.

  • And it can be just the relative path if I'm

  • assuming that page is on the same server,

  • that route's on the same server.

  • And then the second argument should be a function.

  • It can be anonymous, doesn't have to be anonymous,

  • doesn't matter so long as that function, per jQuery's documentation

  • takes at least this one argument, which I could called data.

  • I could call it anything else.

  • But the documentation for jQuery says, hey, user, I will pass to this function

  • that I will call back as soon as I have some data for you,

  • whatever the server gives me.

  • And the server has given me a name, a symbol, and a price

  • all inside of this object, this JavaScript Object Notation.

  • Finally, this last line is just kind of nice to have.

  • I realize, you know what, it'd be a nice feature if after the user searches

  • for a stock quote that we not only see it

  • but we also reset the form to be a blank value.

  • So notice that this symbol refers to a unique element,

  • the unique ID of an element that's not a paragraph tag, as this one is.

  • This is an input field.

  • And input fields don't have HTML inside.

  • They literally just have textual values.

  • So I use dot val instead, passing it in an empty string.

  • But the net effects, notice, this time with that line is the following.

  • Once I've added that line, I have, GOOG, get quote.

  • And notice the field clears itself this time.

  • Once I have Yahoo here, get quote, it clears itself this time.

  • So by adding that kind of line to this example, which

  • just happens to be using a bit more jQuery,

  • I now have the ability to reset the field as well.

  • All right.

  • Now where was that JSON coming from though?

  • Well recall in application dot pie, we had a couple of routes, one of which

  • was register, which was not all that interesting.

  • It just rendered a template called registered dot HTML.

  • But the other route, which we only glanced at a moment ago,

  • was slash quote.

  • This one's a bit more involved.

  • And I've actually omitted some error checking

  • to keep the code a little tight.

  • You'll see more error checking and more code inside of helpers

  • dot pie from CS50 Finance.

  • But long story short, these five rows of code

  • simply contact Yahoo Finance, passing in that symbol that's been provided,

  • get back the response in CSV, convert the CSV to JSON, and return that JSON.

  • And so this is the code that responds to get

  • requests of the slash quote route, which is what my JavaScript code is using.

  • So again to be clear, we don't have new capabilities

  • necessarily with rendering this financial information that we

  • didn't already have with Python.

  • What has changed is, now I am doing that HTTP request,

  • and I am changing that web page client-side.

  • I'm contacting the server, yes, but only for additional data, only

  • to get that JSON data, only to get the name, the symbol again, and the price.

  • I am not asking the server, hey, server, could

  • you also give me a brand new web page with HTML tags

  • and a body tag and a head tag and a title tag and all that.

  • I'm not asking the server for a whole darn new page

  • as Jinja might have given me by using a template in, say, CS50 Finance.

  • All I'm asking the server for, is please just give me a stock quote,

  • and I'll take it from there.

  • And so now we have, frankly, a much more responsive interface,

  • because I'm requesting less data of the server.

  • That's going to be a smaller number of bytes, which means

  • it's quicker to send it back to me.

  • And I already know how to display it so there's just a lot less work to do.

  • So in this case, it would seem that the introduction of JavaScript

  • hasn't changed what I can do, but certainly has changed how I can do it.

  • But it's easy to be misled.

  • In our previous examples, when we did some form validation,

  • recall that we could similarly validate that the user typed

  • in the right thing or the wrong thing, client-side, without talking

  • to the server.

  • And the result was prettier for sure.

  • We had a little red text and so forth.

  • Though technically we could do that server-side as well.

  • It's just easier to do it client-side.

  • But it was faster.

  • I mean, we don't really notice on the wonderful internet speeds

  • we might have right here on campus.

  • But certainly on mobile devices, if I took out my own phone,

  • it's going to feel slower, certainly if you're on a slower connection

  • it will certainly be slower.

  • But it's not sufficient to just get rid of the server altogether

  • and only do client-side.

  • In fact, it turns out, an adversary, whether maliciously or just

  • accidentally, could do something like this.

  • Recall that this form here asked for my email, password,

  • password again, and an agreement.

  • And if I don't cooperate, it yells at me--

  • missing email, missing password, passwords don't

  • match, checkbox unchecked, or whatever.

  • But it turns out that hacking JavaScript, turning it off,

  • is as simple in Chrome or any other browser, poking around your settings,

  • as I'm doing here, scrolling down to an option called,

  • in this case, disable JavaScript.

  • And now after simply disabling JavaScript, woo.

  • I am registered.

  • Well, not really.

  • But I am not registered.

  • I did not give an email address.

  • I did not give a password.

  • I definitely didn't give it the same password again.

  • And I certainly didn't agree to those terms and conditions.

  • So JavaScript is really just a client-side nicety.

  • It gives us amazing new features.

  • It gives us amazing responsiveness.

  • It is not an alternative to security checks,

  • to validation of data on the server.

  • All of those lines of code from CS50 Finance, all of the lines of code

  • you might have on the server in Python or whatever language that

  • are validating user submissions to make sure they're cooperating, apologizing

  • or admonishing them accordingly, if they don't cooperate are still necessary.

  • So it's a little annoying that in order to benefit

  • from this client-side responsiveness, this better user experience,

  • you have to now pretty much invent the wheel in two places.

  • In the client-side in JavaScript, on the server in Python or whatever language.

  • But that's the way it is.

  • If you want to achieve the best of both worlds.

  • The security that you get by actually doing something

  • as close to your database as possible on the server,

  • and the nicety that you get, the user experience that you get,

  • and the immediacy of responding to the user by using JavaScript alone.

  • So it turns out, there are some libraries

  • that allow you to, on the server, specify what fields are valid.

  • And you can let the library on the server

  • generate the requisite JavaScript code with which to validate your form.

  • So long story short, thankfully, other people

  • have helped us solve this as well so that you only

  • do need to write the code once if using the right library.

  • But it's the principle that's important.

  • In fact, too often on poorly written websites,

  • is it possible to circumvent some silly checkbox or some requirements that's

  • not really a requirement.

  • It's really just a JavaScript imposed request for data,

  • if they're not actually validating as much on the server.

  • So realize that that need on the server remains.

  • All right.

  • Back to that map.

  • We have the ability, recall, to get the GPS coordinates of where someone is.

  • We have the ability, with AJAX, to get more data from the server.

  • And though the data we've gotten this far has been stock data,

  • there's nothing stopping us from getting images from the server-- more

  • and more images as might composer ultimately a map.

  • And indeed, let me go ahead and open up the following.

  • In map dot HTML is a relatively short page that has a few characteristics.

  • The top of my page.

  • I've got some CSS.

  • To be cleaner I could factor this out to a separate file

  • but I wanted to keep the demo in lecture pretty succinct.

  • So everything's in this one page.

  • HTML, body and hash map.

  • So the commas in the CSS declaration here just mean,

  • apply the following properties to the HTML tag and to the body tag

  • and to whatever element has this unique ID.

  • I want to make sure all three of those are 100%, because by default your web

  • page has no height.

  • Because if you have no content there's no height.

  • But I want to make sure that my web page literally fills the browser.

  • And I don't want any white margin around the edges.

  • I want everything flush up against the sides and the top and the bottom.

  • So that's all this does for me, nothing more than those aesthetics.

  • Down here, in the body of the page, notice

  • that I have quite simply a div that has nothing inside of it,

  • open tag close tag, but that has unique ID called map.

  • This is really a place-holder where I want to put a map.

  • Down here I have my script tag.

  • And I could have put this in the head page.

  • Really what I've done is mimic one of the getting

  • started examples in some of Google's online documentation,

  • so that if you'd like to play along further,

  • you'll see that this lines up almost perfectly with some of their getting

  • started exercises.

  • Indeed, even the function name I have here, INET map mimics theirs.

  • And you'll see too, even though in Python, or rather not in Python, in C,

  • we generally put these curly braces on the same line.

  • You'll see that stylistically, probably more common in JavaScript

  • certainly to do it on the same line here,

  • even though the closing brace ends up over here.

  • Again, all that matters is that you are consistent with respect

  • to your own code and nice and neat.

  • So what's going on inside of this INET map

  • function, which I know to implement because Google told me to

  • by reading its documentation.

  • Go ahead and declare a variable called map.

  • Go ahead and instantiats-- it turns out that JavaScript

  • allows you to create or instantiate new objects, much like you can in Python.

  • And JavaScript though, in this kind of context,

  • you need to say new, which says to the browser, kind of like malloc,

  • hey, browser, give me memory four-- although we're not

  • managing memory like we do at a low level in C for a map.

  • And Google dot maps dot map, you can think of as a class in JavaScript

  • that represents a map.

  • Like literally a world map.

  • It's not technically a class in this case here,

  • all the newer versions of JavaScript will introduce that and other features.

  • But this is Google's way of allowing me to specify hey, Google, I

  • want to map at the location identified by this unique ID.

  • So document [INAUDIBLE] gets me that div,

  • because its ID was quote unquote map.

  • And hey, Google, here's how I want you to configure that div.

  • I want you to center a world map at this latitude

  • and this longitude-- which based on some googling

  • is apparently roughly the middle of the United States, arbitrarily.

  • Zoom level is four.

  • I want to be able to see a lot of the country, not the whole world

  • because then it won't fill the page.

  • But I don't want to just see some middle state for instance.

  • I want to be zoomed up higher.

  • And I would know what number to use by trial and error

  • or from the documentation.

  • Then I want two markers.

  • I want one marker, one little red pushpin on Cambridge,

  • one pushpin on New Haven.

  • And from some googling, I found that the latitude of Cambridge

  • is roughly 42.3762 and the longitude is negative 71.

  • And New Haven's 41 and negative 72, give or take.

  • And the map I want those markers to be positioned on is map.

  • So map is the key, per the documentation.

  • Map is also the name of my variable.

  • A little confusing, but it also keeps things clean because I mean what I say.

  • So with just these few lines of code, I have

  • implemented a function called INET map, whose purpose in life

  • is to instantiate a map-- create a map, and put it in this div.

  • Then with these chunks of code, I'm saying

  • give me a marker, a little pushpin, at this position.

  • Give me another marker at this position.

  • That's pretty much it.

  • The only other thing I'm doing in this page, notice, is this.

  • At the bottom of the file I have a script tag

  • whose source value is this long URL.

  • It's got a key, which I signed up for earlier.

  • And indeed, if you want to play with this example,

  • you'll have to go to Google's documentation for the JavaScript API--

  • Application Programming Interface-- for Google Maps

  • and sign up for your own key, paste it in there so that it actually works.

  • But what's key at the end of this line is this call back.

  • This is just Google's way-- it's completely

  • a design decision of their own.

  • But they have configured their documentation and their back-end code

  • base to say this.

  • Tell us the name of your function, because as soon as the Google Maps

  • server hears from you, we will call this function of yours,

  • as soon as the Google Maps API is ready.

  • And I keep saying API.

  • API is just application programming interface.

  • It's a generic way of saying, someone else has written code that you can use,

  • and the API describes how you use it.

  • Indeed, when I keep saying, I've read the documentation,

  • I've read the documentation, I really read

  • their API or some human-friendly version there of-- a user's manual.

  • And for instance, their API prescribes that this special object

  • map it takes in a reference to the elements in which you

  • want to put the map.

  • Then it takes in an object as implied by the curly brace and the curly brace

  • that takes at least these keys, the center of the map,

  • and a zoom level-- or at least those are the two keys that I'm using.

  • Meanwhile, the API for Google's marker specifies

  • that you should also pass in an object, per the curly braces, that gives it

  • a map on which to put that marker, that pushpin, and a position

  • at which to put it.

  • And I'm just doing that twice.

  • So application programming interface will

  • mean a little something different in real terms

  • depending on whether you're using Google or Bing or any number of tools

  • completely unrelated to Maps.

  • But it just refers to features-- functionality that someone else

  • has provided that you can then integrate typically into your own program.

  • So what if I now visit Map dot HTML?

  • What do I get?

  • I get a map of the Earth, or of the United States

  • in this case, centered roughly around the middle of your country.

  • And then I have a marker here for Cambridge, a marker here for New Haven.

  • But, notice, this map has so much functionality built into it for free.

  • I can click and drag.

  • And notice-- and if you look quickly-- well now

  • we are literally over the edge of the Earth.

  • So let's go back.

  • If you do this quickly, you'll see that those rectangular gray spots appear.

  • And that's because, at that moment in time,

  • Google has not yet downloaded the images, the pings

  • or whatever they are, PNGs for that part of the world.

  • But, notice, if we do this.

  • If I go into my Chrome tools and open up my Developer Tools

  • and watch the Network tab, notice what happens every time I click and drag.

  • Each of those rows in this table at the bottom represents another HTTP request.

  • And a lot of them, notice, are pings.

  • So really useful when developing JavaScript code

  • is to watch the network tab because you can see your own data or someone else's

  • data coming back and forth for you that's

  • then somehow being used by your JavaScript code to update the map.

  • We in our previous example were updating a price

  • and a name of a company on the screen.

  • But in this case, Google is clearly updating images on the screen

  • after having initially drawn these markers.

  • And if I now go to the Elements tab here in Chrome,

  • you'll see that script tag that I had before,

  • and this other script tag, which contains my own JavaScript code.

  • But notice this.

  • Div ID map, which was previously empty-- let me zoom in.

  • If I expand this triangle, apparently inside of that div now is another div.

  • Inside of there is another div.

  • Inside of there is a whole bunch of divs.

  • And indeed, this is what Google's Maps API has done.

  • They have dynamically generated, using JavaScript, all of this HTML.

  • I didn't write any of that.

  • All I gave them was an empty div with a unique ID of ID,

  • and the Google Maps API, upon being told where to put this map,

  • has filled in that blank so to speak with a whole lot

  • more content from its server thanks to JavaScript and thanks to this technique

  • known as AJAX.

  • Meanwhile, we can zoom in and out, because in addition

  • to that drag handler that you see there, there is the plus sign over here.

  • There's the minus sign over here.

  • There's the satellite map, where it's going to re-download all of the tiles

  • all together.

  • So all of these features-- this is my website.

  • Like, I made this.

  • Well, I made this.

  • All I had made was an empty div and maybe

  • a dozen or so lines of JavaScript code.

  • But this is again where programming gets really exciting and really fun,

  • because you can start building things on top of other people's work in a way

  • that they've made available so that you can do this.

  • And if you think about apps you might have

  • in your pocket, Lyft or Uber or the like,

  • those apps have maps built in, right.

  • And Uber probably didn't go around the world with cars or other technologies,

  • figuring out where all the roads are.

  • Rather, they're probably using Google Maps API or something like it,

  • in order to show you those maps.

  • And they built their business on top of that API.

  • And this is again where things get really powerful, really quickly.

  • Now there's another feature still.

  • And just to show you that we're only scratching the surface,

  • let me open up something like this so that we've at least filled in one gap.

  • Earlier today we started with the alert function,

  • which really should never be used.

  • If you ever see a website that has that ugly alert pop up,

  • that is cutting corners, just as I have because I wanted to focus on the ideas,

  • not on the printing of information.

  • But this underwhelming button at first glance,

  • has actually been implemented using Bootstrap.

  • So that's why it doesn't look like a default button.

  • It's got more of a nicer gray border around it,

  • even though it's still there in the top left-hand corner.

  • But there's an event listener on this button for on click.

  • And when that button is clicked, we're going to see an alert,

  • but it's an alert that's a lot nicer.

  • And maybe it's not perfectly beautiful as you would have it,

  • but it's being generated entirely with JavaScript HTML and CSS.

  • It's not the browsers built-in default.

  • And indeed, notice what just happened.

  • The back of my screen went kind of gray.

  • There's this nice drop shadow here.

  • There's a title.

  • There's a body.

  • There's a close.

  • And for convenience there's this little x up here.

  • And that's because Bootstrap, the library to which I've been referring,

  • has bunches of other features-- not only these things, called modals, which

  • are fancier alerts.

  • And indeed, notice what a modal does.

  • It deliberately, by design, blocks you from seeing other things

  • until you dismiss it.

  • Now it's dismissed itself and it's gone.

  • But these are the kinds of features you get with JavaScript.

  • So form validation, maps, interactivity like that.

  • We're really just scratching the surface.

  • But at the end of the day, it just boils down to a few features.

  • And it's these libraries that take advantage of features like that.

  • jQuery, which you can take a look at in a bit more detail here.

  • Bootstrap, which again you'll recall from CS50 Finance,

  • but you can see more about it here.

  • It doesn't just come with CSS.

  • It comes now with JavaScript capabilities.

  • And then this is the URL of that other library that uses Bootstrap and gives

  • us form validation.

  • So let's look at one last example so that we can now

  • tie together what we did some weeks ago with what

  • we're now doing in JavaScript.

  • It turns out that in C we of course manipulated

  • images for forensics problems and whodunit and so forth.

  • But you can do this in JavaScript as well.

  • In fact, if you go to this URL here, there's some fun,

  • exercises if you will, from our same friend Nick [INAUDIBLE] from Stanford,

  • whom you may recall starred in that binky claymation video.

  • Well, what Nick has put together online is a bunch of JavaScript examples

  • that give us puzzles like this.

  • So iron image puzzle.

  • So here's something, not just with red noise,

  • but with red and green noise still.

  • And no matter what angle I look at this one, I really can't tell what it is.

  • And it's not actually one of those magic eye things

  • where you just kind of stare through it and something appears.

  • Rather, there's a lot of noise here.

  • And there's that image hidden.

  • If we actually read the information here,

  • we'll see that it contains an image of something famous.

  • However, the image has been distorted.

  • The famous object is in the red values.

  • However, the red values have been all divided by 10.

  • So they are too small by a factor of 10.

  • So it's like Nick turned a knob and ratcheted down

  • all the red by a factor of 10.

  • The blue and green values are all just meaningless random values, noise,

  • added to obscure the real image.

  • And Nick tells us, you must undo these distortions to reveal the real image.

  • First, set all the blue and green values to zero, to get them out of the way.

  • Look at the result. And then if you look very carefully you may see the image,

  • although it's very dark.

  • So at which point we can multiply the red values by 10.

  • So let me go ahead and do this.

  • This now is using a simple image API that Nick has provided here.

  • And I know this only from having read through his documentation,

  • poking around the source code and understanding what exists.

  • And I gleaned, by poking around and reading his documentation,

  • that there's at least six functions or methods

  • associated with this simple image API.

  • This API doesn't get more data from the server per se.

  • It's just an API in the sense that it provides me with a set of functions

  • that I can call.

  • So these functions include, get red, get green,

  • and get blue, and set red, and set green, and set blue.

  • And it turns out that Nick's already given me

  • some starter code here in JavaScript.

  • And I can now add some additional code inside of these nested for loops.

  • Because much like your own forensics piece

  • set where you probably iterated from left to right and top

  • to bottom over your image's scan lines and pixels,

  • so can we do the same in JavaScript as follows.

  • So Nick suggests, and I'll take that advice, that I should first

  • set the green and blue to 0.

  • So I'm going to do IM for image.

  • And that's the variable he's defined up there.

  • And just for good measure you can think of this identical as before.

  • We'll make it just like we did with our variables declarations.

  • Image dot sets green at location x, y to 0.

  • So again, I know the syntax for this API only by having read his documentation.

  • Image dot set blue at location x comma y to 0.

  • And Nick has given me this handy run save button.

  • Let's do that.

  • He is right.

  • So this is another copy of that blue and green image.

  • And I definitely can't really make out the image.

  • I mean, it looks like-- there's a little bit of red there.

  • I can actually way up close here-- and perhaps on your screen

  • you can see the faintest of red.

  • Let me enhance that.

  • But the red is there.

  • The information is there.

  • I've set all of the green and blue bytes to 0, but there's still some red.

  • I just need to bump that up.

  • Well let me go ahead and do something like this.

  • Var red equals image to get red at location x,y.

  • All right.

  • So let me do, image dot set red at location x,y, equal to red times 10,

  • as Nick suggests.

  • Click run save.

  • Ho, ho.

  • It's all very red, but now I can clearly see the Eiffel Tower.

  • So we're really just scratching the surface now.

  • I mean there's this whole field of steganography,

  • the art of hiding information within images, for instance.

  • And this is just an example-- a simple example at that.

  • But notice the things that we did in C are all the more

  • possible now in Python, or are just as possible if not more possible

  • in JavaScript.

  • But it's ultimately the mental models that are important.

  • There's no server interactivity here once we've downloaded this page.

  • We have been using today, JavaScript entirely on the client side.

  • Which is to say that even once you've download an image,

  • can you permute that image, in memory, in the browser, to manipulate it here.

  • Or we could have sent it to Python.

  • You could do the exact same kind of thing in Python.

  • Use the appropriate library with extra read, those pixels, and those RGB

  • triples if you will, and do it server-side.

  • So it really just depends on what problem you want to solve.

  • It did JavaScript itself, by a framework called node js can

  • be written on the server-side too.

  • You don't need to use Python or PHP or Ruby or Java or anything.

  • You can use JavaScript.

  • And as an aside, JavaScript has nothing to do with Java.

  • It was really just a marketing ploy at the time.

  • But JavaScript is the programming language

  • that is typically used in the browser.

  • It can be used on the server.

  • And its syntax is exactly what we've seen here today.

  • But it's especially useful in the context of web pages

  • because it gives us a language with which we can manipulate the DOM

  • that we've seen, the tree structure.

  • It gives us a language with which you can change and add

  • to and remove the HTML, and the CSS, and really anything you see.

  • And indeed, it's this trio of HTML, CSS, and JavaScript,

  • coupled with some back-end, Python or Ruby or PHP or Java or C+ or anything

  • else, that together implement today's web apps.

  • And so now with that, have you the vocabulary,

  • coupled with SQL and your own database back-end

  • to build most anything you want in the world.

  • This was week 10.

  • SPEAKER 2: Like I said, I don't know anything more than you do.

  • SPEAKER 3: There must be something from your grad school days.

  • SPEAKER 4: Hey, man.

  • Not going to the party?

  • We really should get started on that [INAUDIBLE].

  • It's a doozy.

SPEAKER 1: All right, this is CS50, week 10.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級 美國腔

CS50 2016 - 第10周 - JavaScript (CS50 2016 - Week 10 - JavaScript)

  • 18 5
    小克 發佈於 2021 年 01 月 14 日
影片單字