[ Silence ]
>> Okay. Welcome back to Computer Science S-75.
This is Lecture Six, JavaScript.
This seems to be fun to start these classes
by asking what we did last time
because no one ever seems to know.
So let's go there first.
So, last time on Monday we dived a bit deeper into SQL,
talked about a few topics, among which were?
Axle?
>> Well, joining tables.
>> Okay, so joining tables which refers to what?
>> It's defining something in the tables [inaudible].
>> Okay.
>> Which refers to a similar field in another table
of these two and [inaudible] join those two together
and simply gives you the things associated with that [inaudible]
from one table and puts it next to another one.
>> Okay, good.
So just to summarize, if you have a relational database,
inside of which is at least two tables and one
of those is a primary key, like an ID,
and another of those is the same ID but not
in the same kind of relationship.
You can join those two tables on that shared ID
so that you get back essentially the union of the rows
from this table with the corresponding rows
from this table.
And when I said it's the idea is a little bit different
in the second table, we call this a foreign key,
because it's there not necessarily
to uniquely identify the row but to somehow link that row back
to a corresponding primary key.
So what was an example that we did involving primary
and foreign keys?
>> We had an inputting table and then we had a sales table --
>> Okay.
>> -- so we joined the actual sales to the [inaudible].
>> Okay, good.
So we had an order -- a sales table, an orders -- sorry.
We had products, we had orders,
and there were some keys shared among those tables,
for instance, an employee ID.
Sorry, we had an employees table,
and we had an orders table, and the shared key
between those two tables was some employee identifier.
So what's an upside of actually factoring out something
like an order into an orders table?
What was the motivation for introducing two tables on Monday
as opposed to just one bigger table?
Like if we already have an employees table on day one
and we only have that one table, why not just add another column
that lists the product ID that that person sold?
Jack?
>> [Inaudible] a whole lot
of redundant information that's taking up space
on wherever [inaudible].
>> Okay, good.
You could end up with a whole bunch of redundant information.
For instance, if you clutter the employees' table with all
of your orders you might have Jack, Jack, Jack,
just because Jack sold three different items,
and we certainly don't need three different copies
of his name.
And alternatively, if we didn't -- if we weren't as bad as that,
if we didn't actually just duplicate Jack's name
or the employee's name again and again,
what if we instead just put another column
in the employees' table?
>> Well that wouldn't be good either because that would be
like faking a table because you would have to use commas
or some kind of [inaudible] characters
to actually identify the individual sales.
>> Okay. So, okay.
So, you've interpreted my proposal of another column,
let's call it the orders column, as potentially containing zero
or more order ID's, or product ID's, and we would have
to resort to some kind of hack whereby we just separate those
product ID's by commas and at that point we might
as well just have multiple columns.
Okay, so let's do that.
That was a stupid mistake I made the first time,
let me have one column per order in the employees' table.
Why not go that route?
Why introduce this additional complexity
of a whole other table?
Let me sort of -- let me play naive for a moment.
So what would I name this column?
I'm going to call it Order One.
What would I name the second column?
Order Two.
What do I name the third column?
Order Three.
Now, start to find faults with my proposal.
Jack?
>> Well, so you have one customer --
well, one employee that sells, let's say, 300 items.
>> Okay.
>> And another who sells maybe two or three.
>> Okay.
>> First of all, now you have 300 columns in your --
>> Good.
>> -- table, which is way more than you need
for the one who's only sold two or three items.
And let's say if you [inaudible] the customer that sold 300 items
but you want to keep the sales you wouldn't be able to do
that because they're all on the same page.
>> Excellent.
So a couple problems arise here.
One, the table just gets really wide.
For instance, to handle an employee who has sold as many
as 300 items you now need Order One, Order Two,
Order dot, dot, dot, Order 300.
Which literally means 300 columns,
but remember this is a spreadsheet of sorts,
it has rows and columns and it has the same number of columns
for every one of the rows,
so now just because you have a really good salesperson he
or she has 300 orders to his or her name,
but suppose the norm is far fewer than that.
Or you have a guy who's not doing so well
and he only has two orders to his name,
well you're wasting it seems a huge amount of space.
Even if we've not filled
in the blanks there's definitely some overhead involved
in having all of these columns there for all of the rows.
So you just have this very ragged edge
to your table whereby it might be 300 orders long,
it might be two orders long,
but this doesn't feel like the best design.
As moreover, as Jack points out, if you delete
or fire an employee, you're going to lose in this model all
of his or her order numbers, which doesn't seem ideal.
Now we can mitigate that one by instead
of deleting the employee we could just have another field
that's called terminated and it's one if yes or zero if no.
So that might mitigate that but still this doesn't feel
like the cleanest design.
So the where we ended up on Monday was pretty good.
So the [inaudible] schools table still had some other faults
with it but at least this factoring out of orders
and having it as a distinct table
from employees was a good thing
because we can always recover the relationships
by doing joins, whether implicitly or explicitly.
So what was the analog now for project one?
Even though you probably haven't dived into it
yet project one involves stocks, and portfolios, and users,
and so forth, so what's the similarity there
with this project?
Axle?
>> Maybe you would want to have one table containing all the
portfolios on your entire site.
>> Okay.
>> And another table containing all your user names
and passwords.
>> Okay, good.
So maybe you'd have one table for all of your portfolios.
And on Monday we defined a portfolio somewhat arbitrarily
as being a stock symbol, a quantity,
and it also had one other field associated with it,
in the portfolios table.
Stock symbol, quantity, and?
>> Sales price?
>> Could have sales price if we wanted to remember
that information, but we crucially need one other field
in this portfolios table.
Yeah?
>> How much money is [inaudible] sorry.
>> Okay. Retracted.
So I've got my users table, now I've got my portfolios table,
and at the moment my portfolios table only has quantity
and symbol.
>> You need to tell -- you need to [inaudible]
which user actually has [inaudible].
>> Exactly.
We need the user ID.
We need some kind of identification for the user
so that we know who owns four shares of GOOG,
in the case of a Google stock.
Now we could store price if we did care about that history,
and that's ultimately up to you, the [inaudible] allows you
to simplify and allows a user to sale all of his or her shares,
not just individual ones.
So you don't really have to know exactly
which of your shares you're selling.
But that could be a compelling feature.
Now in terms of this user ID, let's go there.
In the users table we presumably have a username,
which might as well be email address,
password, or a hash thereof.
Shouldn't be storing clear text passwords even though we did
initially for John Harvard.
What should the primary key be
in the users table for project one?
And again, don't take this as law,
different designs are possible, but what could be?
Yeah?
>> A unique identifier.
>> Okay. Unique identifier, I propose an email address.
Like it or hate it?
Or do you like it or hate it?
>> Well, you can do email address.
>> Okay. So you say, okay, you kind of like it.
Email address, who dislikes email address
as the unique identifier as the primary key for my users table?
Ben?
>> It seems to be easier just to use a number.
>> Okay.
>> If you're [inaudible]
who owns [inaudible] a number [inaudible] link
that to an email address.
>> Good. So just to recap,
the upside of using a numeric identifier, like an int,
that just auto increments, would be one,
it's a little more efficient because you just search on a 32,
or 64-bit value rather than some arbitrary length varchar.
And you can also index it a bit more readily
because there's just less --
there's fewer bits to actually index.
So it feels like that should be higher performing,
certainly for large datasets.
Jack?
>> You're also saving space from also repeatedly putting
in whatever someone's email is and however long it is
when you could just be putting in some sort of --
>> Exactly, so the space savings can certainly add up because
if this user owns a lot of stocks and his
or her email address was in every row
of the portfolios table it just feels kind of ridiculous
to store 10 or 12
or 20 characters just too uniquely identify that user.
Moreover there's another problem that would arise.
Suppose that I wasn't this savvy, I didn't use numbers,
I just used email address.
Think about other corner cases that arise --
could arise, not necessarily in project one, but if you continue
to roll out project one as sort of an actual commercial website.
What's a design flaw you might regret a few months later?
>> Email addresses change, they disappear [inaudible] password.
>> Good.
[ Inaudible Speaker ]
Good. So you leave Harvard
and you lose your Harvard.edu address.
You leave your company; you just decide you got
to stop using that AOL.com address.
You want to change your email address.
Now what's the implication?
Well, you the programmer could certainly allow a user
to change his or her email address,
but how many different tables or rows are you going
to have to update now?
If they change their email address you have
to minimally update what?
>> You have to -- if you have a separate table for user ID's
and emails then it's easily done you just need
to deal with that table.
But if you have it on all stocks it's a mess.
>> Exactly.
Right? You have to do an update on the users table,
you have to do an update on the portfolios table,
or wherever else you've used it.
And then there's the issue of well, how do you do
that all atomically because it'd kind of be ideal that this kind
of change happen all at once and not a little bit of change
over here, then over here, then over here,
because for whatever reason if that user decides to hit reload
in some other browser window in which they're already logged
in you could end up with some very funky undefined behavior
if some of your tables have malan@harvard.edu
and other tables have malan@yale.edu,
just because you happen to look at your database while
that change was in process.
Jack?
>> And beyond that if you do have some sort
of [inaudible] atomic process so it does it all
at once you're going to shut down the --
using the SQL database for all the other users who [inaudible].
>> Well, good.
So if you resort to lock specifically
and you're using MyISAM tables, which was one of the formats
that you can have for a table, then you would indeed have
to lock out other users.
In this case you could use NoDB, which now is
in fact the default, and transactions would not be as --
would not have the same impact on users.
So we can at least mitigate that.
But there's then at least the additional complexity
of just updating all of these darn tables just
because you made a foolish design decision upfront.
So, realize that when I say there's many different ways
of doing these things, it's fine if you still for this project,
for instance, want to use email address as your identifier,
but you're going to have to justify that to us.
For instance, in the [inaudible] that you were asked
for project zero and also now for project one, you're invited
to explain your various design decision,
so if you feel strongly about something that's fine.
But what we're really looking
for when evaluating projects is did you give it the thought
and did you make a judgment call as opposed
to just picking something because it seemed easy
without really thinking through the implications?
So do be mindful of those kinds of things.
So in terms of project zero,
it has been distributed among the TF's.
You should soon, if you haven't already,
heard from your specific TF.
We have a team of four this semester
and so they'll be reaching our via email
and they'll also be providing you with feedback, both numeric
and qualitative on the project, and the aim is to get
that feedback back to you at least a day
or two before the next project's deadline so that you can absorb
that feedback and make any last minute changes
to your current code for project one based
on any repeated mistakes or decisions you might have made
that maybe weren't optimal.
So feel free to reach out to me and also
to your specific TF via email anytime if you have questions.
All right, so without further ado we move
on to things more client side.
So whereas thus far, we've looked at XML, and we've looked
at SQL, and we've looked at PHP.
All of that stuff thus far has been server side, and so we're
at the sort of midpoint of the course now where we transition
to things more client side.
Where we don't do away with all of our server side capabilities,
but we start focusing more on writing code that was going
to execute in the confines of the browser.
So JavaScript is an interpreted language, just like PHP,
and what does that mean, to be interpreted
as a programming language?
Yeah?
>> It's read line by line when it's run as opposed
to being compiled when it's translated into [inaudible].
>> Exactly.
So there's no step as there is with some languages like C,
or C++, or even Java, where you have to compile your code
from source code into some other representation,
often zeros and ones.
With JavaScript, as with PHP, you just write it
and then you hit reload on your browser, or you hit run
on the server, you do some execution of a command
that just starts to interpret that file line by line.
The upside of this is that there is quite simply no compilation
process, just a little more interactive
in terms of the programming.
But the downside is some degree of performance.
And so on the PHP side, and we'll talk about this
in our scalability lecture, there are ways of mitigating
that cost of interpreting the same darn PHP file again
and again.
You can do what's called cache, the up codes,
which is a fancy way of saying
that the PHP interpreter can save the results
of its first interpretation so that the second, and third,
and fourth interpretations are much faster
but that's purely server side.
On the client side you might have noticed
in the popular press that when Google comes
out with a new version of Chrome, or Fire --
or Mozilla comes out with a new Firefox version,
everyone's touting their various JavaScript performance numbers.
And that's in particular because so much more
of the web these days is based on client side code
and the faster that code executes the better the user
experience tends to be.
And the more necessary it is
to have good JavaScript interpreters,
especially in older hardware, or mobile phones,
or netbooks where you just have fewer CPU cycles
and less RAM to play with.
So let's take a look at JavaScript,
and you should find overall
that syntactically it's pretty similar to what you would find
in other interpreted languages, among them PHP,
but there's a few features and a few approaches
that are generally good to be mindful of out of the gate.
So, one, in terms of references, these are some okay references.
The first two are more authoritative than W3Schools,
but you'll find that these links might be some useful reading.
But today what we'll focus on are some of the core features
of JavaScript, the syntax, most of which you'll find familiar,
and then some concrete examples.
And then what we'll do next Monday is focus in particular
on Ajax, asynchronous JavaScript and XML,
although it doesn't necessarily involve XML anymore.
Rather, Ajax is all about using JavaScript
to program more dynamic websites,
things like Google Maps, and Facebook,
that even once you have landed on their homepage they continue
to pull in more and more data, whether it's different parts
of a map, whether it's status updates from your friends,
and that's all thanks to JavaScript and the ability
in JavaScript these days to make additional HTTP requests
without reloading the whole page.
You can instead make other HTTP requests that get back subsets
of content and incorporate that content
into an existing webpage.
So we'll also see the topic of DOM
and tree structures recur today and next week as well.
So how do you go about writing JavaScript?
So JavaScript is not fundamentally tied to the web
or to HTML, but it's generally found inside of webpages,
or inside of JS files --
.js files that themselves are included in webpages.
Now as an aside they're increasingly common is
to actually use JavaScript server side.
A very popular framework, if familiar, is node.js,
which we'll talk briefly about toward the end of the semester,
but this is an alternative type of tool that allows you
to actually write JavaScript code on a server,
or even on your Mac, or your PC, and run it locally
without actually needing a browser.
So just realize that unto itself JavaScript is a full-fledged
programming language but tends to be used in webpages
and it tends to be used in between script tags
that look quite simply like that.
However, if you actually want to put your JavaScript code,
such as the stuff we're going to write,
in a separate file you can include it in a separate file
by a syntax like this.
So the script tag takes an optional source attribute,
which references a file, and then also a type attribute
which informs the browser what the type of that script is.
It's almost always JavaScript,
but in theory other languages could be supported.
So without knowing much about JavaScript,
without actually even seeing any JavaScript just yet,
just instinctively, why might you want to be able
to embed JavaScript code between script tags in a webpage
versus doing it via an inclusion mechanism like this?
When might you go one route versus the other do you think?
Yeah?
>> [Inaudible] a user to look at my code.
>> Okay.
[ Inaudible Speaker ]
Okay. So we can raise the bar to the user seeing my code
by putting it in a secondary file rather
than my .html file, or my .php file.
The one pushback there is
that because JavaScript is an interpreted client side language
when used in the web,
the reality is we can still see file.js, it's just not going
to be in the body of the main webpage.
But for instance, if we use Chrome, or IE's,
or Firefox's Inspector, it's a little debugging window
at the bottom, we can absolutely still see the contents
of my JavaScript file.
So it raises the bar a little bit but not fundamentally.
Jack?
>> It lets you use the same JavaScript commands
on all sorts of different pages.
>> Good.
>> Instead of having to paste and copy and all that stuff.
>> Good. So much like CSS it can be used across multiple pages
if you factor it out into an individual file and then include
that file with a link tag in the head of your webpage.
Same deal here, with JavaScript if you want
to use the same functions or the same widgets
in different webpages, whether it's a .html file, or .php file,
or whatever, you can factor it out here, include this tag
in every one of those pages so that you can then use
that JavaScript functionality anywhere you want.
So there's just an efficiency mechanism to it.
One, you don't have to download the same file again and again,
indeed you get the benefits of caching in this case,
because if the browser realizes, wait a minute,
I already downloaded file.js before,
even if you're including this tag in 20 different webpages
of yours the browser most likely is not going
to keep re-downloading file.js.
By contrast, if you paste it, a whole bunch of JavaScript code
between script tags in your HTML, well then that just has
to be downloaded again and again,
because when you request a file via HTTP you really get the
whole thing typically, you don't get everything but the part
of it that you downloaded before.
So there's that mechanism.
And then there's just the design opportunity whereby you don't
have to comingle it with your aesthetic markup, your HTML,
you can really relegate your logic to a separate file
and it lends itself therefore to better designs,
certainly for complex projects.
So initially we'll start by just embedding everything
in our HTML files because one, we don't care
yet about performance because these are going
to be tiny little scripts at first.
Two, it's a little bit easier to read pedagogically
if it's all in the same file.
But as soon as we get to the point
of doing more powerful things with JavaScript it'll make sense
to adopt this model here.
All right, so here is JavaScript in list format.
These aren't all the keywords but I tossed these up here
in bullet form really just to convey the message
that JavaScript is quite similar to most of the languages
with which you're probably already familiar.
So not just PHP but whatever languages you've used before
coming into the class.
You have break statements to break out of things
like loops, or switches.
You have do while, you have for loops,
you have while loops and the like.
You have the return statement, switches, throw, try, and catch,
which relate to exception handling,
which we talked briefly about on Monday
and also is quite popular in Java.
Var for variable we'll see is a little bit different from PHP
where we sometimes want to declare explicitly
that something's a variable before using it.
And functions are actually going to be quite powerful.
One of the most powerful and useful features of JavaScript is
that it supports anonymous functions
and in turn things called closures
which for now [inaudible] are going
to let us do some fairly sophisticated things
like passing functions around as arguments
and not just passing variables around as arguments.
So this is quite a fancy feature that's now present in PHP
and other languages but it's quite a very common paradigm
in JavaScript.
All right, so some basic syntax.
In JavaScript to declare an array, call it a,
you can do syntax as simple as this.
Var, which means give me a variable, a,
which means here's the name of the variable,
equals open square bracket,
closed square bracket, semicolon.
That's it.
So this returns to you an empty array.
These arrays in JavaScript are only numerically indexed.
So whereas in PHP we saw associative arrays
and you could use an array by way of indexing in with numbers,
or you could use actual keywords,
like the super globals, get, and post, and session,
and cookie are all associative arrays.
In JavaScript arrays are by definition numerically indexed.
So for now, if I want to add things to an array
in JavaScript I can do this in a few different ways,
I can do a [0] gets equal 'foo'.
Totally arbitrary example but it just shows the syntax.
If your array is called a, and you want to get
at location zero, even if nothing is there yet,
you just go ahead and say gets equals bar --
or 'foo' in this case, or number,
whatever value you want to store there.
Same deal for bracket one and bracket two.
The one thing to realize here is
that they array is actually going
to grow automatically for you.
You don't have to resize it as you might in a language
like C. You don't have to know
in advance how big this array is.
You can just keep pushing additional items onto it
by knowing at what index you want
to place foo, or bar, or baz.
So you can actually be a little more deliberate
and you can actually call functions.
So JavaScript arrays are actually objects,
even though you're initializing it
with this somewhat shorthand notation of open bracket,
closed bracket, they are themselves full-fledged objects
in an object-oriented programming sense,
and therefore they have methods associated with them.
And one of the methods associated
with a JavaScript array is a push method,
which pretty much does what it says,
a.push means call the push method inside of the array,
called a, and give it an argument in this case of foo.
And that has the exact same effect of just adding foo
in this case to the first location in the array.
Why? Well the array is initialized to nothing
so pushing an element onto it means you now have a bracket
zero location.
Call it again and again,
you have bracket one and bracket two.
So push appends an element to an array,
it does not prepend the element.
As an aside you may also see syntax whereby you can declare
an array with var a equals new Array.
So A-R-R-A-Y, capital A, is actually the name of a class,
though JavaScript doesn't technically have classes,
it's the name of a JavaScript object that exists
but the common notation, daresay preferred notation,
is just to use the simpler square brackets.
But realize you might see that in various tutorials.
So good, we have arrays, which means we have the ability
to store lists of things and arrays are going
to be super useful once we get to Ajax
and more generally the retrieval of more data from a server
because if you can imagine how something
like Facebook is implemented or Google Maps,
you're often not just getting one thing back from the server,
you want to get back multiple tiles for your map.
You want to get back multiple friend status updates.
So you want to get back an array of stuff, so JavaScript is going
to lend itself to that
and you'll see it's a common syntactic tool.
So let's do an example and just to see how we might use this,
a very common thing in a webpage is to have a form,
like a login form with a username and a password.
And at least me, who is a little uptight, it drives me nuts
if upon visiting a page and being prompted to login I have
to manually click with my mouse inside
of the username field just so I can start typing my username.
Right? This is completely unnecessary, but if you think
about it any of the forms you've implemented thus far
without using JavaScript code do not automatically give focus
to any given field.
You have a text field, text field,
and however many more you have declared in your HTML,
but if you want to start typing stuff
into those text fields you have to click with your mouse just
like we did for the past couple of weeks
when we've been doing form examples
in order to start typing.
So this is not the best user experience, right?
If I visited Facebook.com, I'm not logged in,
let me just start typing my username and then my password,
don't make me click and then type my username and password.
So how can we express that idea programmatically?
So this is out of context, just in HTML element, called script,
inside of which is some actual JavaScript code.
So here we go,
if document.forms.login .username.value.
So, ridiculously verbose and we'll see before long ways
to clean this up and just make it a lot more straightforward,
but what is this referring to?
So in the context of a webpage you have a special,
super global, really just global variable called document.
And this variable is of type object
which means it has stuff inside of it, properties inside of it
and possibly methods associated with it.
So document actually refers to essentially the DOM
that we've been talking about.
We talked about DOM mostly in the context of XML,
but quick refresher, what was a DOM?
What is document object model all about?
DOM, yeah?
>> It's like the structure of the document.
>> Okay, it refers to the structure of the document.
It was a tree structure, recall.
In fact we drew a tree in picture form on a slide
that represented a snippet of XML.
So DOM is a way of modeling hierarchical data,
for instance XML, or HTML, in a tree structure and the roots
of that DOM is generally called the document node.
It was capital D the last time we talked about it,
here it's lower case d, but it's the same thing.
So when you're writing JavaScript code inside
of a webpage, inside of a whole bunch of HTML, you can access
that tree structure programmatically
by saying document.
And document dot means go inside of this object
and access some property inside of it.
So for those unfamiliar with object oriented programming,
though most of you would be from prior experience,
realize that object oriented programming is
about having data structures in memory,
generally called objects, and objects can have both data
and methods associated with them, our properties
and methods associated with them.
So, in the case thus far with document it turns
out there is a property called forms.
Forms happens to be a collection of all
of the forms in that document.
And there might be zero forms, there might be 10 forms.
It totally depends on how many form tags are in that document.
So document.forms.login specifically means get me the
form whose name is login among all of the forms
in the current page, whether there's one or more.
Document.forms.login.username, take a guess here,
what is username referring to in the context
of this story thus far?
Axle?
>> Well, [inaudible] field
of the ID username inside of that form.
>> Good, so in this case it's referring
to the input called username, happens to be name
as opposed to ID in this case.
Username field in the form whose name is login in the collection
of forms inside of the DOM.
So there's a hierarchy to these dots, just like in Xpath
and in the simple XML API there was this notion of stepping
where the arrow notation
that said go deeper, go deeper, go deeper.
Same idea here.
Document is sort of the highest level object you have access to,
document.forms dives in a little deeper,
document.forms.login a little deeper,
and .username even deeper.
Now, username really refers to the node in the tree that's
of type input, so think about how you would make a login form.
We've got at least two input HTML elements,
username and a password one.
So, username is now referring to a rectangle in DOM --
a rectangle in the sense that's how we drew it
on the screen the other day.
So dot value is actually referring to its string value,
whatever text is actually in that text field.
So let's see this in the context of some actual HTML.
Let me go over to the appliance and let me open
up a file called form1.html and let me skip the JavaScript code
for a moment and focus only on this.
So I propose this as one
of the simplest possible login screens we could have,
and I have a few things going on here.
One, I have a form.
Two, I have an element called email.
Next, I have another input called password1,
and then third I have another field called password2.
So you can imagine this being in the context
of a registration form.
So not necessarily login but registration where you want
to ask the user for the same password twice,
that'll lend itself to some validity checking in just a bit.
And then lastly I have a submit button.
So that's it.
Well, what if now I want
to start getting programmatic access
to these various fields, let's do this.
Let's open up instead version two of this, form2,
and let me propose the following approach.
Down here now let's do a registration form.
So I've given this form an ID, registration,
and I have given it similarly an email field, a password field,
another password field, and then a submit button.
But what I want to do this time is when the user tries
to submit this form I want to use JavaScript
to actually check the values that they've typed in and yell
at the user, reject their input if the passwords
for instance don't match, or if they haven't filled
out this form properly.
So we could do this in PHP, think back a few lectures now
where we had those various login examples,
and if the user did not give me a username
or a password we would reject their input and we would check
for that server side by checking the value
of dollar sign, underscore, post.
So we can already check the validity
of a user submission server side, so what's the point
of even doing form-checking, or validity-checking client side
with JavaScript today?
>> We can check without even having to reload the page
or deal with anything [inaudible] can immediately be
done [inaudible].
>> Exactly.
So, with JavaScript now,
with client side code we can check whether the form has been
filled out correctly immediately client side without even talking
to the server and to be more clear,
like what is really the value of doing that?
Yeah?
>> Well, [inaudible] efficiency, you're not sending any,
in this case, useless data to the server for validation
and then receiving it again.
>> Exactly.
Really it boils down to performance.
With JavaScript on really any computer, any phone these days,
it can execute so quickly
that you pretty much get immediate feedback for the user,
which means they see whatever problems they've created
right away.
Moreover you're just not adding extra load to the server
for really no good reason so you can reduce load on the server
which can potentially help with scalability if it has
to do less per a given unit of time.
So a couple of advantages here.
So let's take a look at this form
in the browser before teasing apart how we can impose this
kind of error checking.
So here's the original form, very simple, very ugly,
but it has my email field, password film,
password again field, and then I also decided I'm going to throw
in a terms and conditions checkbox,
because this really lends itself now
to did the user do everything we wanted them to do,
a very common certainly on webpages today.
But notice if I don't do anything here except type
in malan, but that's not even a valid email address, a password,
I'm going to type in whatever,
and then this time it's definitely not going to match
because it's only one character, and I'm not going to check this.
When I submit version one of this form,
which recall had no JavaScript, just the HTML,
here's all that happens on the server.
I have submitted to a file
on the server called what apparently?
Yeah?
>> Process.php.
>> Process.php, which clearly does not much at all.
All it does is apparently call the print r function in PHP,
the recursive print function, just because I needed a quick
and dirty tool to see what was actually sent to the server.
In this case that's what I just typed in on my keyboard.
Notice that the checkbox value was not even sent
because it wasn't checked, but the takeaway here is
that I could check on the server whether
or not the user cooperated.
Did they give me a syntactically valid email address?
Did they give me two passwords that match?
Did they check the box?
All of those things I can check server side,
quite like I did a few lectures ago with checking
if John Harvard gave me the right username and password.
So all of that you can sort of do already in PHP.
But let's do it better
or at least more rapidly in JavaScript.
So now, let me go back here to version two of form
and let me not cooperate this time, too.
Let me type in a whole bunch of nonsense and not check the box
and click submit and this time what I want
to see is an error message.
So this is sort of like a poor man's approach to error-checking
where I'm just using the JavaScript alert function.
Those of you who've been using the web
for some time will remember these used to be the scourge
of the internet whereby you would visit some website
that had spam or wanted you to click links and whatnot,
and you would just get peppered with all of these popups,
so not the best approach yet, but very easy way of signaling
to the user that an error happens.
So we can improve upon this eventually.
What's the error?
You must provide the same twice.
So that came from me it turns out.
So let's take a look at the JavaScript code
that underlies this particular error-checking.
Let me go ahead and open this up.
Let me use a different color background here.
We're going to go ahead and open up form2.html.
And I'll zoom in here.
So here again is the html, here's the form in question.
Let me scroll over to the right deliberately.
What is new or different about this version
of the form than last time?
Yeah, Axle?
>> You intercept the submit and run the function validate
on submit, which means that the submission
with PHP is not really done
until that function is [inaudible].
>> Exactly.
So in this case I have on submit,
which is a new HTML attribute, and it is attached
if we scroll back to the left to the form element,
and in this case I've said form, then ID, and then method,
and all that other stuff, on submit equals "something."
What is the value of this on submit attribute?
Well it's meant to be actual programing code.
Either the name of the function that I want to call,
or a string of JavaScript that I want to execute
and return some value.
So I've literally said return validate open print close print
semi-colon, and we've not written much JavaScript yet,
but validate is apparently the name of a function,
and open print close print means it takes no argument,
semicolon means that's the end of the line,
though it's not strictly necessary,
and return means do something with this value.
And indeed, the way the onsubmit handler is defined,
if I were to read the documentation,
is that if the code between quotes returns true submit the
form to the server as usual.
If the code between quotes returns false don't submit the
form at all.
So here seems to be our mechanism
that Jack proposed, being more efficient.
We can yell at the user right away and give feedback
by returning false and maybe triggering an error message
but if everything looks good we just return true
and the user doesn't even know we've validated
their submission.
So it's a nice transparent way of doing something
and then maybe intercepting the form submission.
So where is this validate function defined?
It doesn't come with JavaScript, I had to write it myself,
so let's scroll up to the top here.
So here's my script tag,
and notice below the script tag I have my validate function,
and here is how you define a function in JavaScript.
Inside that script tag I have function validate open print
close print which does what you would expect.
In fact the syntax is pretty much identical to PHP;
the only difference is involving how you would declare arguments
or these default arguments and the like.
So function validate means here comes a function
called validate.
All right, so now I'm using my verbose syntax for now,
if document.forms .registration.email .value
equals equals "" then I'm going to yell at the user
with an alert function which comes with JavaScript,
I did not write that one.
What it does is it triggers that popup with the message inside
of it, and its argument is, "You must provide an email address."
And then I return false.
So we didn't see this one
but under what circumstances would I have been yelled
at with, "You must provide an email address?"
Yeah?
>> If you didn't enter anything at all in the email field.
>> Exactly.
If I had not typed in Malan, but I just left that field blank
at the very top of the form,
I would have been yelled at with this message.
And just to be clear, why do I not only call alert,
I also return false?
Isaac?
>> Well, it has to be false or true on submit.
>> Okay.
>> So it has to return true or false for the sake
of the onsubmit handler, but why false, just to be clear?
>> So that it doesn't [inaudible].
>> Good. So that the form rather doesn't submit fully.
So it does not initiate an HTTP get or post,
sending the form's data to the server.
We want to stop that because we're not ready to do it.
So we don't want to trouble the server just yet.
Okay. So now we have some branching code here.
So turns out that if conditions else if [inaudible]
in JavaScript pretty much identical in JavaScript to PHP,
you need the curly braces if it's more than one line,
and in general I would encourage always using the curly braces
because of the process called minification.
Which we'll talk about later, but that has to do
with eliminating unnecessary white space
and even shrinking variable names in JavaScript.
So generally braces are a helpful thing.
So, else
if document.forms.registration .password1.value equals equals
something, let me scroll over a little further,
this is a mouthful,
but in English what is this else if doing for me?
Axle?
>> If the first password field is empty as well it's going
to do everything inside the else if.
It's going to alert [inaudible]
and then return false to the submit.
>> Exactly.
So just like before if the user has this field blank,
in this case the field is password1,
and its value is quote unquote,
that is they typed nothing there, then I'm going to yell
at them, "You must provide a password,"
and also return false.
Now realize if the user had not left it completely blank
but they typed in a space bar character,
would this return false at this point?
Yes or no?
Jack?
>> No because it's not [inaudible].
>> Exactly.
Because obviously a space is not equal to quote unquote
with nothing between the quotes.
Its quote space unquote..
This if condition would not catch that
and so we would not declare the user's input as invalid yet.
So already hopefully you should be thinking, well there's ways
of making this better.
Right? If the user hits space or space, space, space, or space,
space, space just to circumvent my form validation I should
certainly be able to detect that too and it turns
out there's functions in JavaScript
or I could write a function in JavaScript
that lets me trim the user's input.
I could trip leading white space,
I could trim trailing white space,
and that just means throw it away so that even
if the user's trying to be difficult or annoying
by just hitting the spacebar to get
through my stupid prompts I can still catch
at least those scenarios.
To be clear though, I'm not doing anything
like checking the length of the password,
I'm not checking whether it has enough alphabetical characters,
numeric characters, punctuation characters.
There's no like security checking here
of the quality of the password.
We're just seeing if the user gave us anything whatsoever.
What about the third branch here.
So else
if document.forms.registration .password1.value !
equals ""document.forms .registration.password2 .value
then yell at the user as well.
And before I spoil the answer,
in English what should the error message probably be?
What have they failed to do properly here?
Yeah?
>> You need to enter the same password twice.
>> Exactly.
We need to yell something like,
"You need to enter the same password twice."
Because the logic I just checked was did password one's value
equal password two's value?
If not, they screwed up again
and they typed the wrong thing twice.
So, if you've ever been on a website that does exactly
that kind of check this is similar to the kind
of code that they're writing.
Theirs is probably a little more compact,
we're doing it the very pedantic way just for now,
but the functionality is the same
as you would find on a typical website.
What's this last block doing?
"You must agree to our terms and conditions."
Why does the code in that --
how does the code in that branch work apparently?
Yeah?
>> Well it looks for a dot checked on agreement,
which is probably the checked box.
>> Good.
>> And the exclamation mark in the beginning of it says
if it's not checked, so then you run the alert.
>> Exactly.
It turns out, and this is where DOM again is useful,
there's different types of nodes, different types
of objects when you parse a big HTML file
and an input type whose --
an input tag whose type is text has things
like a dot value property.
By contrast, something like a checkbox is generally useful
because it has a dot checked property that is true
if it's checked, that's false if it's not.
So by saying if !document.forms .registration.agreement
.checked, by saying that syntax I'm saying if it is not checked,
by inverting the Boolean value then yell
at the user accordingly as well.
But if they pass the first, and the second, and the third,
and the fourth if condition successfully
and we have not yelled nor returned false yet,
what do I do by default?
I return true at the very bottom of the code
because they didn't screw up,
they typed in everything I wanted them to.
Now they didn't necessarily give me a valid email address,
they didn't necessarily give me a password that's anything more
than a spacebar character, but we've at least raised the bar
to just the user rapidly clicking submit
and wasting the server's time.
We could start to make these more sophisticated and we will
but for now that is one
of the easiest mechanisms whereby we can introduce some
JavaScript code to the site
and do something useful for the user's sake.
All right, any questions, syntactically or otherwise?
No? All right, well let's take a quick look at form3.html.
Actually, let's skip form3 that one's kind of boring.
No, we can show it, just not that interesting.
So in form3 it turns out there's this key [inaudible]
in JavaScript which actually isn't used all that often
because there's cleaner ways still to do this.
But realize the [inaudible] keyword simply says assume the
following prefix for any variables in the block
of code that's to follow so that I can just say something
like email.value, password1.value, and so forth.
But again this is not an oft used feature
but it's one step toward making what are right now fairly
ridiculously long expressions a little more manageable.
So just FYI there.
All right, but let's look at form4,
which looks a little something like this.
I seem to have a fundamentally different approach here,
and before we dive in what is different about this function,
this version of validate?
Yeah?
>> It takes the argument that you call f,
which is probably going to be everything before like .command,
.form, and everything.
>> Okay, excellent.
So it looks like this version of validate takes an argument first
of all, and that argument's apparently called f,
because it's in parentheses there.
And I seem to be using f subsequently further
to simplify my syntax and more generally because what I'm going
to do in this version as we'll see after a short break is
that I can pass around even forms themselves as arguments
because a form in a webpage, once it's read
in by the browser, is represented as a node in a tree,
as one of those rectangles
that we might have drawn a couple of lectures ago.
And so I can pass around a reference to that DOM node,
that form node, and indeed this case we'll soon see
that the variable f, the local variable f is going
to be of type node.
It's going to be a form element
that was passed programmatically.
Why don't we go ahead here and take our five minute break
and when we return we'll see exactly how we did this
and what more we can do with objects from DOM's.
All right, so the most recent cliffhanger was how does this
version four actually work.
We're passing this thing called f around, so let's first look
at how this function is being called.
And notice at the bottom of the form
that our html is almost the same
as last time except one attribute's value has changed,
which is obviously what?
Yeah, Axle?
>> Well, the [inaudible] function is
which probably refers back to that particular node is the DOM.
>> Yeah, exactly.
So in a lot of programming languages, for instance PHP,
and Java, and also JavaScript,
there is this special variable called this,
which is rather self-referential,
whereby if you are in the context of an object
or in this case in the context
of an HTML element you can specify this
and that refers to that context.
So the keyword this, in this case, is referring
to the element in which we've mentioned this,
and if I scroll back to the left what is the tag name
in question here?
This is the form tag, open bracket, form, action, method,
and name, and onsubmit, and there's the beginning of this.
So we have this way now in code to refer to the HTML element
that we know eventually will be accessible via
that DOM object, that document object.
All right, so return validate this.
Now let's look at what the implication is
of this calling convention.
So if I scroll back up to the top
where my validate function is defined, recall this is
where we left off a moment ago,
and the validate function takes an argument f,
arbitrarily called f, I could have called it foo, bar, or baz.
But thereafter I can specify f.email.value,
f.password1.value, and so forth.
So one, my syntax has gotten a little simpler, which is nice.
Two, I now have the beginnings of more reusable code.
I now have a validate function
that in theory could validate any form object
that has these particular fields of the email, and password1,
and password2, so I've begun to at least start factoring
out what could be some common functionality.
And three, it really demonstrates, hopefully,
that via the this keyword we now can bridge the gap between HTML,
which is really just markup, and programming code.
And the middleman between those two worlds is this DOM,
because the DOM is the result of having parsed an HTML file
and built up in memory, in RAM, this tree structure,
which JavaScript can then traverse.
All right, so the rest of this code is identical,
but any questions on this or the passing thereof?
All right, so let's take a look at version five here,
which is now starting to give us some more interesting UI.
Let me zoom in on the left portion of this form,
and does anything look new here?
Isaac?
>> Well, there's disabled.
>> Yeah, so disabled is something that's a little new
here and there's a couple of ways of writing this.
The way I've written it looks a little silly these days but was
in vogue when XHTML was being popularized.
Could just say disabled with HTML five,
but disabled equals disabled [inaudible] that this element,
as you might have guessed, should be disabled.
[ Inaudible Speaker ]
So what's the implication
of disabling something like a button?
What is this actually going to do?
Yeah, Axle?
[ Inaudible Speaker ]
Okay, good.
So, when you check this, let me go up to this in a browser now.
So this is now form5, notice that it's a little subtle here,
but notice that now that submit button is a little grayer
than usual.
All right, well maybe that's just a CSS thing, but let's try
to click it and be a difficult user and not fill out anything.
I'm clicking, nothing's actually happening
because that is in fact disabled.
So why is it disabled?
Well, this was just a design decision I made
in this version whereby I only want the user to be able
to submit this form if they have minimally given me what I wanted
or at least minimally checked that box.
So let me go over to that checkbox and see what happens.
Checking now, and notice the difference at bottom left.
Every time I check or uncheck
that box the submit button changes state
and once it is black like this it seems
to let me click it again,
I'm not actually letting the form be submitted
but if I clicked it it would go through.
Thankfully I now have some error checking still in place but more
on that in just a moment.
So how are we actually doing this?
Well, if you were writing the code yourself and you want
to tie that button somehow to the checkbox,
what was the property on the checkbox element that we want
to be checking in order to decide whether
or not the submit button should be enabled or disabled?
Yeah?
>> Dot checked.
So it turns out in addition
to dot checked some elements can have a dot disabled property
which literally says should the browser let the user click it
or not, is it disabled or not, true or false?
So if we go back to version five of this code, let's scroll
up here to the very top, or rather,
let's first look at this.
Notice that on the right hand side here,
I agree to these terms and conditions,
then I have input name equals "agreement" as before,
and now I have another event handler.
So I've done something a little different here.
I'm not using onsubmit because I don't want this form
to change states when I submit the form
because that's too late; I want it to change state
when I click on this checkbox.
So in English, what does onclick equals "toggle ;
mean, or do, do you think?
Yeah, Ben?
[ Inaudible Speaker ]
Exactly, simple as that.
Anytime you click this checkbox call the toggle function.
There's no arguments passed in, but as the name
of the function suggests there should probably toggle the state
of what?
The checkbox or of the submit button?
The submit button hopefully, right?
The checkbox you get for free, you just have to check it,
the browser will do that for you.
So let's scroll up because it sounds
like either there's a built-in toggle function
or it's something I myself wrote
and indeed it's the latter in this case.
Here's my toggle function.
Pretty straightforward, albeit verbose,
if document.forms .registration.button .disabled
then set that same property equal to false,
else if document.forms .registration.button.disabled --
rather, sorry, else set it equal to true.
That was not a condition.
So in other words if it is disabled, make it not disabled,
else make it disabled.
So really I'm just toggling the state of that.
I could actually do this a little more elegantly
if you prefer.
I could just do something like this.
I could say document.forms .registration.button .disabled
equals that.
That's a slightly more elegant way of doing it.
Right? I don't really need the if condition,
but it's also still a little verbose.
But again, we'll clean that up next time.
All right, so that's the toggle function,
simply toggles the state.
What is the validate function doing this time?
Well, it's pretty much identical to the very first version.
There's no fundamental relationship between validation
and the submitting of this form,
all I've added this time is this onclick handle --
handler and implemented the toggle function myself.
So in terms of user experience now,
is this a good enhancement, bad enhancement?
The fact that there's this relationship now
between the checkbox and the ability to submit the form?
Thoughts?
Yeah?
>> I really don't see anything wrong here
but I would alert the user and say you have
to click this box [inaudible] nothing's going to happen.
>> Okay. Good.
So, feels okay in your mind but you should
at least be more explicit with the user
as to you must click this box in order for anything to happen.
And I would agree.
Like I think it's okay to sort of really get in the way
of the user submitting the form, but frankly I can think of a lot
of family friends of mine
who would not know what the heck is going on here
because it's not obvious that there's this linkage
between that checkbox and the submit button.
Right? Frankly it might be reasonable instead
to just let the button always be enabled but allow the user
to click it and then be yelled at, informing them
at that point, you must agree to the terms and conditions,
especially in terms of accessibility,
folks who might have to use screen-readers or the
like for reasons of blindness, like disabling things
on a webpage that a user, whether blind of not blind,
expects to work, is generally not the best practice even
though this is not an uncommon paradigm.
So in short, at least some more explicitness would go a
long way.
Yeah?
>> If you don't even want to enable it can you put some sort
of onclick thing so that if it's disabled
and someone clicks it [inaudible] check off?
>> So absolutely.
We could still listen for clicks.
So that's a good question.
Let's try this because I feel like one
or more browsers might actually disable event handlers
if it's disabled.
But let's see.
Let's try this.
So, let's go ahead in here and add -- I'll zoom in --
onclick equals "alert 'testing 1 2 3';
so let's just add this just to see
if when it's disabled Jack's idea works.
So let me reload the page,
and as ever before anytime you make changes to code now
that involves JavaScript code you obviously need
to reload the page, just like if you make HTML changes you need
to see it.
And also beware especially
when you are including .js files via the script source syntax
that we saw earlier.
Be sure also sometimes to hold down the shift key
and hit reload or even more dramatically clear your
browser's entire cache just because as with CSS,
as with other included files, it tends to get cached
by the browser and so you might make some change on the server
in your JavaScript file, but the browser might not see it
because it doesn't realize it's been changed.
So, in general a hold-shift reload minimally
when reloading files that are included like that.
All right, so now, yeah,
unfortunately I'm clicking right now on the submit button
and it's not even listening.
So it seems to be the case here -- there we go.
So unfortunately Jack's idea does not work,
at least in this version of Chrome,
because when a form element is disabled via its disabled
property or the disabled attribute in HTML,
it doesn't even transmit other event handlers like click.
>> Now while I don't want to go this deeply into it,
could you put it inside a DIV and then have a DIV [inaudible].
>> Yes. Good question.
So those of you quite comfortable with CSS,
you could for instance put that button in a DIV,
or even overlay a DIV [inaudible] absolute positioning
or the like, give it a higher Z index and then listen for that.
I would agree let's not ever go down that road.
That just feels messy.
Yeah?
>> If you don't want to go down that road,
you could also do it all in JavaScript, don't disable it
by doing .disabled, do a check in the validate function
that checks the state of the thing and then alert the user.
>> I agree.
Yeah, let's go that road.
So instead, leave the button enabled but just add a check
to the validate function or some other function that's
at least still checking for that error
and handling however it wants,
but not by just thwarting entire form submission.
As an aside, nothing we do today unfortunately is going
to make your life easier on the server.
And by that I mean just because we are doing client side
validation today with JavaScript
and therefore catching errors client side,
all of these measures are circumventable by a user
or more generally an adversary who's trying to circumvent them.
In other words, we absolutely still have
to do server side form validation, we cannot trust
that the data that's coming from a client just
because it had client side validation
in JavaScript is actually going to be legitimate.
Why is that?
How could I circumvent these kinds of form protections?
Yeah?
>> If you bring up the inspect element thing,
you get the developer [inaudible], you could go
on the console and then you could inject JavaScript,
and then you could essentially just manually submit whatever
you want to the PHP.
>> Exactly.
Anyone who knows how to access more sophisticated tools
like the console here could actually execute JavaScript
manually or I can even do something like this.
If I go into the HTML of this page,
let me zoom in and expand the form.
You know what I can do?
Why don't I just go in here and just disable --
delete this, enter, zoom out, well there you have it.
Now my form button is re-enabled.
Right? So you don't even have to be a good hacker
to circumvent protections like a disabled property,
you can just change it right there in that fashion.
Or frankly, we can be really sophisticated here
and if you really want to be a geek we could do something like,
well, if I want to telnet to the server I can telnet --
rather, if I want to fake a request, recall we can go back
to lecture zero in our HTP request
and mimic them ourselves.
So telnet is a program that allows you to collect
from a client to a server on any TCP port in this case.
I'm going to connect to port 80 of the appliance.
Now notice I've connected to 127.0.0.1,
and indeed that's the loopback address.
However I could do this to Google,
but rather I'm going to do this.
So I'm going to say, rather, POST to --
oh no, we're using get today.
So we're going to use GET /process.php HTTP/1.1.
I'm going to say my host is the appliance.
And then -- woops, notice I already got back my results.
Oh, [inaudible], yep.
So below that, I won't do the whole example here,
what I could continue doing here is the equivalent of passing
in -- well let's do it.
GET /process.php?
email-malan&password1 equals asasas&password2 equals z
HTTP/1.1, so this is definitely the geekier way
of circumventing client side protections.
I goofed somehow.
Client site php, bad request, ampersand.
What did I do wrong?
Password. GET /process.php?email equals malan HTTP/1.1.
I'm doing something wrong.
Okay, anyhow, someone smarter
than me could actually just mimic the HTP request
to send them from a command line client or from a browser client
and actually trick -- oh, that's what it was.
Okay. Wait, I can recover from this.
Okay, telnet,
GET /process.php?email equals malan&password1 equals
asasas&password2 equals z HTTP/1.1, host: appliance,
I forgot that header, enter, enter.
Okay, now I got back a 200 and now look
at what I sent to the server.
So in other words, if your client doesn't even support
JavaScript as my black and white window does not,
well then you can completely circumvent those protections
as well anyway.
All right, so in short, JavaScript good, useful,
but it is not a security mechanism.
It is really about user experience
and decreasing server load at best.
All right, so what other kinds of functionality
and event handlers do we have access to here?
Well, so recall that we had --
whoops, recall that we started here.
It turns out that we can do a little better
in terms of functionality.
So it turns out that like PHP,
JavaScript supports a feature called regular expressions via
an object called RegEx.
So there's some more documentation here,
but this is representative of a type of object
that comes built into JavaScript.
We talked briefly about one already, arrays,
and we'll see others, strings, we've used thus far,
but regular expression as well is a class in JavaScript
or rather an object in JavaScript that allows us
to pattern match on various strings.
So for instance, thus far we've just been assuming
that if you give me anything
for an email address it's an email address,
but case in point, malan is not an email address,
it's missing the @ sign, it's missing a domain name,
it's missing a .tld, top level domain.
It's just syntactically not an email address.
But with a regular expression we could check
for that sort of thing.
And so we'll do that in just a bit.
We'll come back and actually say,
you have to give me not just something for an email,
you have to give me something that looks
like username@domainname.something.
So a regular expression again involves pattern.
So we'll see that in just a moment.
Strings too have actual properties
and methods associated with them and we'll see
that functionality before long.
And just to give you a sense of the global objects that exist
in JavaScript, we have again, arrays, but there's also dates,
functions that we've started to use.
There's actually a math object that has things like rounding
and ceiling and floor
and related functionality that's just generally useful to have.
Numbers and strings themselves are objects.
So in short JavaScript is very much about this paradigm
of objects having properties and methods as we've begun to see.
In terms of objects, what is an object?
An object is just a container for key value pairs.
It really boils down to something as simple as that.
You can think of it as a hash table.
You can think of it as a hash map.
You can think of it as an associate of array.
These all have slight differences in terms
of implementation but the end result is that an object
in JavaScript is a collection of key value pairs;
they're generally separated by colons as we'll see
in just a moment, but that's just a syntactic detail.
So how do you create an object in JavaScript, it's as easy
as creating an array in JavaScript.
In this case I have a variable called obj, to connote object,
and equals, open curly brace, closed curly brace, semicolon.
That gives me an empty collection of key value pairs.
So there's no keys, there's no values yet.
It's like an empty super global;
it's like an empty associative array in PHP.
How do you assign things to an object?
You have two syntaxes available to you.
You can say object.key -
value and that will create a key called key,
and a value of value.
Or you can PHP style notation using square brackets
and quotes whereby you index into the object at that key,
K-E-Y in this arbitrary case, and then assign it a value.
So the upside of the first approach,
object.key, is simplicity.
It's just very readable and we've been using it all day long
so far, document.forms .registration.email1.value.
Been doing that the whole time.
However, we could've used the square bracket notation it just
wouldn't have read as cleanly, and moreover
if you ever have keys that have funky characters in them,
like spaces or the like, using the quoted notation
with square brackets allows you to access those keys.
You can't use the dot notation for more complex looking keys.
In general though it's probably best
to avoid anything complex in terms of a key.
How can you create an object
and assign key value pairs to it all at once?
The very last line here is representative.
So if you know in advance that you want to create an object
and you know in advance what your keys and your values are,
you can simply say, var obj equals brackets
and then brackets key: value bracket;
and if you want multiple key value pairs just put a comma
after the value and do another key: value, key: value,
so it's a way of creating an object on the fly
with multiple properties.
So we'll see why this becomes so useful.
How about event handlers?
We've seen a couple, onclick.
We saw another.
What was the other one?
>> Onsubmit.
>> Onsubmit we've used a whole bunch of times.
It turns out there's a whole bunch of others.
Onchange, onfocus, onkeydown, onkeyup, onload, onmousedown,
onmouseup, onmouseout, onmouseover, and so forth.
Just to infer based on past experiences,
when or why is something like onmouseover generally used?
Even if you've never heard the phrase until today,
when might that be used to detect
when the mouse is over something?
>> When you hover with the mouse over a [inaudible] field.
>> Okay, so when you hover over a mouse
with an input field what do you want to happen?
>> Well, I really wouldn't want anything to happen,
but if you [inaudible] or something you could --
>> So you want to hover over a form field?
Be more concrete here.
We can recover from this.
>> You can -- maybe you want to display some kind of info
on something you have on your site,
like an image, or a file thing.
So if you have say a website that lets people download files
and if they hover over the icon for the file [inaudible]
like the file format and the size and [inaudible].
>> Perfect.
Okay. So in contexts where you want to enable the user to hover
over something like an image or maybe even a text field,
and then you want to provide them
with additional information, or additional functionality,
then you can use the onmouseover even handler
to reveal additional buttons, or to give them the equivalent
of a tool tip, a little DIV or something that suddenly appears
like a cartoon bubble
that explains what it is they're hovering over.
And these are omnipresent on the web.
If you go to YouTube I think you can hover over most
of the HTML5 controls on a player
and see what those symbols represent.
If you go to Netflix you can hover over a movie posters
and then a little window opens
and you can see more details about that movie.
Facebook does this a lot, if you hover
over a friend's name a little popup opens
up where you see some photos of them
or their related friends and whatnot.
So, being able to detect when the mouse is hovering
over something, hugely useful, at least in terms
of user experience these days.
So how do you use that?
Very similar, if you have an element, whether it's an image
or a DIV, or whatnot, that you want to listen
for the user's hovering
over it's just onmouseover equals "something".
And we'll eventually see too, there are ways
of registering event handlers.
That is, telling the browser to call this function
when the user does this, using pure JavaScript syntax.
You don't have to put any JavaScript code in your HTML
in order to achieve this functionality.
For now though, we're just using the HTML attributes
to keep things simple and to make clear the linkage
between HTML and the JavaScript code.
How about onkeydown, or keyup,
or onkeypress, which is yet another?
When might that be useful?
Someone else?
Why might it be useful to listen for key presses?
Whether the key is going down or going up?
Scott?
>> [Inaudible] how many times [inaudible].
>> Okay, good.
So recording how many times the user types something.
Maybe you could use that metric for forms
that have only 100 characters or 140, like a tweet
or something like that.
It might be useful to count how many times the user has typed.
Alternatively you could check string length in the value
of a field, but counting might be reasonable.
What else?
>> I've only ever used it once, but when I used it I had
like input field and when users typed anything
in input field it updated [inaudible].
>> Okay.
>> On the page -- well, yeah, on the [inaudible].
>> Okay, good.
So if you have a form field where you want to give the user
like some kind of automatic preview of it, so they're typing
over here but you want them to see what they're typing
over here because they're filling out, I don't know,
like an e-card or something like that where you want
to see a preview on the fly of what they're typing in,
well you can use this.
Every time they type a character you grab the value
of the text field and then you update some DIV element
elsewhere, and we'll see how you can update some other DIV
or portion of the page using JavaScript as well,
but it's certainly possible
because you've probably seen websites that do this.
Key presses can also be used, for instance,
if you want to prevent the user from typing certain characters.
If you don't want any spaces in a field,
if you want to make sure that they have --
if you don't want them to type in certain characters at all,
or maybe it's a numeric field,
you don't want them typing letters for whatever reason,
you can use onkeydown because what you get
with this particular event, you're not just informed
that the event happened,
you're informed what key the user has typed.
So if you detect, wait a minute, that's the letter A,
but this is a numeric field, you're supposed
to be telling me your account number,
you can just return false effectively and say,
ignore that particular A the user typed in.
So some websites do this too to prevent you from pasting.
For instance, Amtrak.com, absolutely hate their website
because my email address is in my Amtrak profile
and they have this stupid feature where you have
to confirm your email address, once and twice.
And I'm okay with the principle of confirming your email address
because a lot of people, myself included, make mistakes
when typing it, but their damn website prevents you
from hitting command or control-V.
Which means you can't paste your email address into the field,
even if you are absolutely certain that it is correct
from the previous field, and that sort of drives me nuts.
Other objections I have to people's websites include --
actually there's an unnamed website at Harvard
that when you're trying
to buy something they want a 33-digit billing code,
those of you who work at Harvard might know of these things.
It's god-awful; I have never memorized a single 33-digit
billing code.
I copy and paste it.
Their website doesn't let you copy/paste a billing code
so you have to manually type it out,
which I daresay is far more vulnerable to mistakes.
But anyhow, what's the pedagogical value of this rant?
This is how you would implement such annoying features as those.
There are better of uses of this.
Right? If you're a Gmail user you might use some
of the keyboard shortcuts, C for compose,
A for archive, or the like.
How does Google listen for those keystrokes?
Well they're listening for A, they're listening for C,
they're listening for other keystrokes as well,
and they're not rejecting those keystrokes per se,
they're actually doing something useful based on them,
and that's all because the web browser world is very much
event driven.
Stuff happens, you hover, you click, you type,
and you can listen for all of these events,
and this is how you make all the more dynamic
of a website these days.
How about something like onfocus?
What does focus mean in the context of a webpage?
Yeah?
>> Well if you have an input field and you click it
or you tab to it it's going to be focused and that's
when you essentially edit the value of it
or type something into it.
>> Exactly.
So in the context of a webpage only one element ever has a
focus at even given time.
When, by focus you can think of it very concretely
as you've said, like a text area.
When you put your cursor in a text area indeed
in some browsers it kind of gets highlighted in blue
or at least your cursor starts blinking there.
That means that form element has focus.
If you hit the tab key
on a webpage you'll generally see a little blue
or whatnot outline move from element
to element in the webpage.
That means that element has focus
and it's just a visual indicator for accessibility purposes
as to what you're actually hovering over,
because generally you can hit enter or the spacebar
at that point to activate whatever it is you're hovering
over, or rather, whatever it is that has focus.
Blur is the opposite.
So when might you care
that a user has blurred some form element?
In other words, blurring means it's no longer focused,
it doesn't mean it gets blurry or anything like that.
Isaac?
>> Well you can do form validation
after they click another element.
>> Yeah. Exactly.
It might be annoying and it might not be necessary
to check a form for validity with every keystroke, right?
And obviously when I start typing my email address it's not
going to be valid the first few characters, right?
You got to give me some time.
So maybe we could instead wait
until that form field has blurred in order
to check whether or not it's a valid email address.
Or we could wait even longer and wait until onsubmit,
but onblur gives me that capability.
And others, onresize?
Onresize is actually a powerful one.
If you're building a website
that really has some predetermined size and you want
that size to grow when the user changes the webpage around,
potentially you need to listen for onresize
so that you can do some math on your own webpage
and make things wider or taller or shorter.
But generally, you get that functionality for free
in a browser, but not --
that's not the case with various JavaScript widgets.
For instance, if you embed a video player,
it's generally going to have a fixed width and height.
So if you want it to grow over time,
if the user resizes the page,
you have to listen for a resize event.
And then ask the browser, "What's you new height
and width, for instance?"
All right, so in short, a lot of power there and really the fun
in JavaScript client [inaudible] programming tends to derive
from an ability to listen to these things.
What kinds of things can you do with JavaScript?
Well, you can even make CSS manipulations as well.
You don't just have to error check and submit HTTP requests.
We can do some more aesthetic things.
So for instance, in CSS you have things like borders and colors
and underlining and the like.
In JavaScript, you can programmatically change the
style of a webpage even
after your CSS has been downloaded from the server.
So for instance, if you think of --
try to think of a website where you filled out a form
and not only have you gotten some kind of error message
if you filled it out incorrectly,
sometimes the website will highlight in red all
of the form fields that you got wrong, or green all
of the ones that you got right.
That's actually using CSS,
and what that websites JavaScript code is doing,
is if it determines that this form field was inputted
incorrectly, it essentially adds a class --
a CSS class to that input element
that gives it a red border,
or it literally updates the style attribute
of that input element and says,
border colon one pixel red solid, something like that
if you're familiar with CSS.
So we have this ability in CSS to do this,
the one downside is what's in it --
what are some examples of CSS properties
that relate to Aesthetics?
Went right off of you, yeah?
>> Border style.
>> Border style -- border-style.
What else?
That's actually a really good one.
Yeah?
>> Radius [inaudible].
>> Okay, radius for like curves around edges, sure.
Yeah?
>> Color.
>> Color, good.
Give me some multiple word ones, like border style.
Yeah?
>> This doesn't have to do with border, but text decoration.
>> Good, text decoration, font family, line height --
there's a whole bunch of properties in CSS
that have hyphens because they're multiple words.
Well, guess what a hyphen represents
in a programming language like JavaScript?
Yeah?
>> It might be the same thing as doing [inaudible].
>> Not quite the same as the dot,
it's actually more mundane than that.
The -- the hyphen represents subtraction,
like the minus sing.
Like subtract this variable
from this variable, line minus height.
So the whole world gets screwed up now
that no one really thought this through when they invented CSS.
So, the reason for this funky looking URL is
that there is a mapping between CSS properties
and JavaScript properties.
So that, for instance, border -- what would you say --
border style, border-style
in CSS becomes border S style in CSS.
So you eliminate the hyphen and you capitalize,
you camel case the rest of the words in the string.
So this URL has a whole list of those mappings, but again,
the heuristic is as simple as that.
Remove the hyphen and capitalize each of the subsequent,
but not the first words.
So what's the implication of this?
Well, I argue that some of you are too young to remember,
but years ago there was a blink tag in HTML, and the blink tag
in HTML did exactly that.
It was one of the most annoying features of like, HTML 1.0
or 2.0, whatever it was and you put a blink tag around a word,
and it just does this.
Even worse, was the marquee tag, which had text going like this
across your webpage like a movie banner, right.
The web looked awful in the '90s.
And we can bring that functionality back thanks
to JavaScript now and piece these things together.
So, I argue that this function resurrects the blink tag,
which it's actually kind of funny.
The various browser manufacturers like Microsoft
and Mozilla and Apple and the like, like consciously decided
to kill that tag and the marquee tag altogether.
Few tags have been killed, but those have.
But that's okay, we can override their wishes.
So here's a function called blinker that's supposed to go
through a webpage and any element that has a tag
around any text that has a tag
around it called blink will have its CSS
manipulated programmatically.
So we can kind of tie a lot of ideas together here.
So var blinks equals document.getElementsByID
"blink."
So there's a few new pieces of syntax and functionality here
that are representative of very common paradigms.
So var blinks represents a variable called blinks.
The right hand side is document, that's our DOM object.
And recall that I promised earlier
that the objects can have not only properties, but methods,
well here's one such method.
It turns out that in JavaScript,
the document object has a method called get elements by name.
What does it do?
It does that, it gets elements by name, it returns an array
of all of the elements, that is all of the tags in a webpage
that match the arguments -- the quoted argument.
So this will literally return an array of all
of the blink elements in the page.
So what does that mean?
Well again, think back to DOM, when we draw a DOM
on the screen, it looks like a tree with like,
rectangular nodes, even though that's an arbitrary
artist's interpretation.
So, the array you get back is an array of those rectangles.
They represent all of the blink elements in the DOM.
So at this point in the story, blinks is an array of zero
or more of those tags.
What comes next?
Well, we have a variable.
Notice that you can declare variables inside of a for loop,
just like you can in some languages.
So var -- for var i equals zero,
i is less than blinks.length i plus plus.
Well, we have a new feature here of arrays it seems.
Blinks.length obviously represents the length
of the array, but what is length really?
Well, it's a property.
Again, objects have properties and array is an object,
so blinks.length is the length property
of the blinks array object.
All right?
So what comes next inside of this loop?
Well one, I'm iterating over all of the blink tags
in the page, and what do I do?
If blinks [i].style.visibility equals equals visible,
then change it to hidden.
So, this is actually a CSS thing.
If unfamiliar, a element on a webpage can be "visible"
or it can be hidden and those CSS properties do exactly that.
So by default, all elements are visible.
So this is saying, if the ith blink element has a visibility
style of visible, what am I obviously doing to it?
What's --
>> In the if statement?
>> In the if statement.
>> Checking whether it's visible.
>> Okay, so I'm checking if it's visible.
And if it is visible, what do I do?
>> You -- you hit [inaudible] you make not visible.
>> I make it not visible.
I change that same property to hidden.
So, what is this exposing to us?
So it turns out in JavaScript, any time you have an object
that happens to be an HTML element --
and a blink tag is an HTML element,
it has a style property.
That's one of the things you get for free.
So if you're accessing elements in a DOM, like a blink element,
that blink element has automatically a dot
style property.
That dot style property is essentially equivalent
to the style equals "attribute"
that we could have put in the HTML.
So it's the CSS stylization for that element.
We can now say change the visibility attribute
to be hidden instead of visible, else, do the opposite,
that's all we're saying in the else.
So just to be clear here, let me bring
up a little scratchpad for a moment.
Just to be clear, if I had done this in my style sheet
or in my style tag, I might have something like this.
Blink -- this is CSS now, I might say visibility visible,
so that's the default, so it would be kind of silly for me
to put this in a style sheet, but that's what I've just done.
What the if condition is doing is it's changing this
effectively to this -- on off, on off.
So what's the aesthetic effect?
Well, let's take a look.
Let's go back to the browser and let's pull up this one,
which is in a form example, this one here is the blink.HTML
and you can see what it's doing.
Right. Hideous tag, you know, it's not all that annoying here,
but if you see -- actually you can still see remnants of this
on the web, like really crazy looking websites that are trying
to use the blink tag, but it just didn't work.
So let me scroll up here because this is actually kind
of interesting.
Let me zoom in over here and you can see thanks
to Chrome exactly what I'm doing.
>> I have a question.
>> Uh-huh.
>> Is -- are -- on this page,
are you using the same script you had in the PDF?
>> Same -- yes.
>> Because in the PDF, it iterated over the number
of blink elements, which in this case is just one.
So wouldn't that be one -- one iteration, just [inaudible]?
>> Ah, correct.
So, I'm using the same blinker function,
but I'm calling the blinker function a little differently.
So let me open that up.
Let me go into blink.HTML, here's my blink function,
but there's one additional line of code that's necessary here.
What is this very last line of code
in my script tag doing apparently.
Jack?
>> It makes sure that it won't [inaudible] again until,
I guess [inaudible].
>> Good, although let's not put it that way
because it doesn't really make sure that it won't call it,
because it's only going to call it --
it's not going to call it at all based on the code I have here.
>> It makes it call it once in [inaudible].
>> Good. So, window.setInterval is a method
of the window object, which we've not seen before,
but it's another one of these special top level objects.
Just like you have document,
which represents your actual document,
window is a different object that represents like a chrome
on the screen, it lets you do things
like window size redetection and so forth.
So window has nothing to do with the HTML, really has to do
with the browder -- the browser, the --
the rectangle that is your browser window.
So window.setInterval does that.
It sets an interval, which means call the following function
again and again, every some number of milliseconds.
So blinker is the name of my function,
500 means 500 milliseconds or as Jack said, half a second.
So that line is simply saying, set an interval
of 500 milliseconds whereby every time
that interval happens, every 500 milliseconds,
call the function called blinker.
Now notice one key detail.
I have not written blinker as a function call,
I have written it as a function name.
So it let me go here.
This is wrong.
I've just added to parenthesis, open paren and closed paren,
that is wrong, but why?
What's the difference?
Or what would happen in this case here?
Jack?
>> It would try to see if blinker --
it would actually call blinker right there and see
if blinker has a return value
that might be [inaudible] what it wants.
>> Exactly.
So in this case, just like in all
of the examples we've done this far, blinker open paren
and closed paren means call blinker, right.
There's nothing fancy there.
The problem with that is that as [inaudible]
that will effectively call blinker once and that's it.
But what you're trying
to do here is apparently set the interval of 500 milliseconds
to call whatever the first argument is.
Now does blinker return anything?
It actually doesn't return anything at all,
which means you have nothing to call.
When it returns, it's not returning function,
so nothing's actually going to happen on subsequent passes.
So this is actually incorrect.
By contrast, if I just say blinker without the parenthesis,
that means pass in a function pointer, so to speak,
pass in a reference to this function
because what the window.setInterval timer will do
is add the parenthesis effectively itself to call
that function every few seconds.
So we can do something with this.
Here's how you make a really annoying webpage.
But just [inaudible] here, let's hammer this home.
So, let me go ahead and do this.
Let me delete my blinker function and let me do --
create another function, let's call it annoy.
And we're going to have the annoy function say alert hi.
All right, so if I do this here --
500 milliseconds will drive us nuts, so let's actually
to like 2000 milliseconds, so 2000 seconds, let's do annoy --
actually let's do it five, otherwise we'll really go nuts.
All right.
So this is effectively going to do the same thing,
but we'll demonstrate an example this way of another feature
in JavaScript that I alluded to earlier.
So now I'm going to reload this page, the blink's going
to go away because we deleted that.
And here we have hi, okay good.
I'm going to click okay.
Hi, okay. I'm going to click okay.
All right, we don't have to go through this forever,
but this will go on forever, so that's fine.
Actually be careful of doing things like this
because if you do it too fast you have
to like force quit the whole browser
because you can't actually stop.
Anyhow, let's go and rewrite this slightly differently.
So, this -- oh, my God, all right.
So here, we can fix this.
Let's comment this out, let's go back here, reload, okay.
So now we've -- now that should stop.
All right, so what don't I like about this?
Well one, the functionality is kind of annoying, but two,
it's kind of stupid that I defined a function only
so that I could reference it the next line down.
Right. This is kind of a waste of your name space, so to speak.
In other words, if you're only going to write a function once,
and then call it in one place,
it's not really fundamentally necessary
to give it a name, right.
The only reason it has a name at the moment is because I want
to define it up there and then call it down there.
But what if I could do both of those at once,
especially if this is a throw away function that doesn't need
to be called by anyone else or even by me anywhere else?
So what if I instead do this?
And the syntax is going to look a little weird for a moment.
Let me do this.
Instead of defining a function that way, let me get rid
of its name, and let me say var annoy equals
function semi-colon.
So what have I done here fundamentally?
So the functionality now is still identical,
it's just that now rather
than have defined the function called annoy
with the previous syntax, this time I've said,
give me a variable called annoy coincidentally,
and set it equal to a function.
So this is where JavaScript starts to get a little powerful
and a little different from some languages.
You can have what are called anonymous functions whereby you
define a function, but you don't give it a name,
but you can assign that function to a variable
so that you can still call it.
So at the end of the day, this is identical to what I just did,
but the takeaway now is
that JavaScript has a function called function who's return
value is, if you will, a pointer to itself,
is a reference to itself.
More concretely, it's the address in memory of where
that function lives, though that's kind of an overstatement.
But in other words, it's some return value
that will subsequently --
subsequently let you call that function or pass it
around to be later called.
So in other words, variable is still called annoy, but the type
of that variable is not an int, it's not a float,
it's not a string, it's a type function.
So functions are, as they say, first class objects
in JavaScript, which means you can pass them
around in memory just like you could [inaudible] typical
variable like an int, a char, a float, a string and so forth.
So, what's the next step here?
Well, that would work, but this is still kind of silly.
Now I have a variable called annoy that I'm only using once,
feels like I can do better and I can.
Let me adopt this same idea and rewrite setInterval as follows.
I want to define an interval whereby every some number
of seconds, the following function is called.
Done. So this is an incredibly common technique
in JavaScript whereby now I have truly defined an anonymous
function, but that's fine
because I have informed setInterval of the address
of that function, all right.
Because the function function --
sorry that that's a little confusing,
but the function function returns effectively the address
of the function that was just created.
Doesn't have a name, but that doesn't matter
because setInterval doesn't care what its name is, it only cares
about that reference that can be passed around.
Now this is a little cryptic, it would have been nice
if the interval -- if the number came first frankly,
but whatever, someone chose to put the number second.
So I still need the comma,
but notice how I wrote this all on one line.
I don't even have to be that anal,
I can instead put this over here.
I can indent it.
I can then put the curly brace on the previous line,
so this is actually a very common way of seeing a function.
If I really want, I could put this down here,
but it's actually very common in JavaScript
to put the curly braces on the same line as the function.
So this actually looks a little cryptic,
but it's just the natural progression
of the various examples we did leading up to it.
So in English,
window.setInterval takes two arguments,
one is the address of a function.
The other is number of milliseconds.
Doesn't matter how we pass in that alert function,
we can still pass it in -- we can pass it in anonymously.
So what we've just done is used an anonymous function
or something more fancily called a lambda function,
which is simply in this case a function that has no name.
But it will still work, so let's try this.
Let me go back, save this file.
Go back to the browser.
And actually let's do it,
instead of every five seconds, let's do every two.
So the story gets told a little more quickly.
Hi, hi, hi, browsers thankfully have gotten smarter,
so let's ignore this one.
Back in the day, you would've gotten another hi, another hi,
another hi, another hi, another hi,
at which point you realize you should --
really shouldn't have visited that website.
Java -- Chrome at least,
is better about managing duplication,
but that is not necessarily a given.
All right, so any questions on anonymous functions?
No. If you really want your mind to be blown,
let me do one other thing.
This is really just to show off and to get you thinking
about more sophisticated syntax.
Let me go ahead and get rid of the interval
and just do var f gets function
and we'll do the alert thing like this.
So this is similar to before.
I'm not called f yet, but if I wanted to, I could do this --
f open bracket, all right.
So let me go ahead here.
Go to my appliance, reload -- whoops, okay, reload.
Oh, there it is.
It happens immediately this time
because there's no interval, there it is.
Every time I reload, it starts.
Hi, but it just happens once.
So that's interesting.
And if I really want to be fancy here, I can do this,
just so you've seen this syntax because again, you'll see it
in online tutorials perhaps.
If you have a function like this, you can actually wrap it
in parenthesis and then put the trailing parenthesis like this.
So what is this going to do?
And let's change the text just so you believe me
that we're actually making some changes here.
This is crazy looking syntax and this is not representative
of like JavaScript coding.
Don't -- don't take this too much to heart,
but what's this going to do Axle?
>> I think it's going to call itself.
>> Good. Yeah, it will call itself in this sense.
Not so much recursively, it just means that the thing
between the first set of parenthesis from here
to here is a function reference.
The fact that I'm putting parenthesis at the end means
that I'm actually going to call it and indeed, yes,
I did just call that function.
So what's the takeaway?
Again, it's not meant to, [inaudible] sort of overwhelm
with the very syntax, but it's just to suggest
that functions are really no different than any other types
of variable that you can define.
You can pass them around.
You can invoke them by using the parenthesis and this is going
to be incredibly common in various JavaScript libraries
that you'll use whereby you'll need to tell a library like,
jQuery, which is a popular JavaScript library,
what function to call when an event happens, like blinking
or rather like blurring or focus or on mouse over, or the like.
And indeed you can create these functions
on the fly as we just did.
So what other features will we be able to have access to here?
So the blink example was just really meant to give us a sense
of how we can override CSS and nonetheless, navigate a DOM,
but libraries give us a range
of much sexier functionality than the blink tag.
So here just a few of the most popular JavaScript libraries
out there today, jQuery is probably the most JavaScript --
the most popular JavaScript library.
And frankly, most people these days almost [inaudible] the two.
If you are a JavaScript programmer,
you minimally know jQuery, and indeed a lot
of the syntax we use today is sort of date
in that you don't have to type out document.forms.registration.
I mean, even I was getting bored saying [inaudible] phrases
that were that long, so libraries like jQuery
as we'll see will dramatically simplify the type of code
that we need to write.
Bootstrap is a very popular library that Twitter developed
that makes it much easier to do things like icons and tool tips
and buttons and menus, and the like.
I'll pull that up in just a moment,
Ext JS also similarly has widgets and the like, MooTools
and YUI have the same.
So what do I mean by this?
Well, if we go to bootstrap, so let me search for bootstrap CSS.
Go to the first link there from Twitter.
It's incredibly common these days
to not reinvent the wheel yourself
and implement every single little feature of your website.
Implementing buttons is not a very interesting problem.
It might have been once, but not to do it for every darn project
that you write or menus or tooltips,
or these things I rattled off earlier.
So just to give you a sense of what bootstrap comes with,
you get a whole bunch of features.
For instance, in bootstrap simply
by downloading their JavaScript code, which is open source
and available, you can for instance, create a modal.
A modal window is a blocking window that prevents the user
from doing other stuff while it's open.
Let me click demo modal, something like this
where something drops down and then grays out the background.
Notice here that I have a window over it, that's a modal.
Well, I can open a modal in bootstrap literally
by just calling one line of code like this.
We'll see more on this kind of syntax before long,
but dollar sign tends to represent jQuery
and .modal here is a method associated
with a div who's ID is myModal, but more on that to come.
What else can you do with a library like this?
And again, this is representative
of all sorts of things.
Let's scroll down to the next example.
So things like this, little menus
that you might want to hover over.
This is all very doable using a combination
of JavaScript and CSS.
In fact, our simple blink example was a step toward using
code to manipulate CSS and open things like menus and the like,
but all of this can be done with a JavaScript library.
So knowing how to call these functions gives you a whole
bunch of functionality.
Let me scroll down to -- oh, let's see.
Tabs are very common, so let me zoom in here,
implementing something like this is very easy with one
of these JavaScript libraries, you simply have
to configure it using code like this here in red and black.
Let me scroll down further --
tooltips, so I alluded to these earlier, like in Netflix.
Which event is this feature apparently using?
[ Inaudible Speaker ]
Yeah, so this is probably the on mouse over event, right.
Because as soon as I move my mouse
over what's probably span tag or an anchor tag,
something else is popping up on the screen.
So that's possible here.
This is another similar one where I get an even bigger box.
This is even more Netflix style,
where it's a whole window of text.
In this case, it's a little boring,
but it's [inaudible] just black and white, but that's possible.
Alerts, we don't have to use the browser based alert,
indeed the JavaScript alert function,
generally don't use it.
One, it looks different on all different browsers and two,
it usually says something stupid like, "The webpage
at CNN.com says," like it's just not very professional typically
using the built in one, so it's fine for class and debugging
and diagnostics, but something like this is a little --
let's see, is a little more compelling.
Popover -- oh, not popover, alert --
oh, this example is not working.
That button should be clicking --
oh, maybe it's because I already clicked it, no, let's see.
Okay, not working as I expected there, for just a moment.
And then you have these kinds of toggles.
So in short, by understanding how you can manipulate things
like objects and pass functions around and the like,
it gives you access to such a broader range of functionality
so that really your project one
or project two can be all the more engaging as a result
of being able to tie these various widgets together.
All right, any questions on objects
and libraries and the like.
And again, we'll come back to things
like that in the next project.
All right, so then a word on some other features
of JavaScript, especially as you look ahead
to the remaining projects.
So there's this notion programming
of static code analysis, a fancy way of saying,
checking your code for correctness
for some tactic validity and consistency with certain rules.
When it comes time to actually write your own JavaScript code,
realize that -- and the emphasis to be clear of,
project two will be on JavaScript,
realize that you can go to a website like this, jslint.com,
paste in your JavaScript code and it will look
for common mistakes in your actual JavaScript code,
much like the W3C's validator can do the same for HTML.
So do take advantage ultimately of something like that.
But I've eluded to this concept a couple of times
and it's an interesting one when it comes to security.
You've probably gone to a website
and seen crazy looking JavaScript code
that frankly we can't read ourselves tonight,
even though you pretty much have seen the basic syntax
and fundamentals of JavaScript.
Case and point, let's go to Google.com,
let me view the page source here
and what does this now look like?
We pulled this up a few weeks ago now.
This is all JavaScript code, right.
But frankly, you know, I can't really make heads or tails
of most of that code, why?
Well, Google has compressed it or minified it as tends
to be the buzzword, which means they eliminated white space
that doesn't need to be there.
They have shortened variable names from something like foo
to just f. In other words, they trim function names
and a whole bunch of other transformations.
Why? Like why has Google chosen
to make their code so unreadable?
>> Well, the typical user is never going to be looking
into finding out why the Google page works like it does.
And on Google's end, this is less that it has to send
out to every user that [inaudible] page --
>> Good.
>> -- Google [inaudible] site, they need to [inaudible].
>> Yeah, so a couple of reasons.
Like one, like you know, normal humans like us, we don't need
to see this, so it doesn't need to be pretty printed
or well formatted with good variable names.
It needs to be designed well underneath the hood,
but aesthetically doesn't matter
to us what it -- what it looks like.
And then performance, as Jack says, if you think about --
it's kind of remarkable.
If Google gets maybe a billion hits per day on their homepage,
imagine if a programmer simply accidentally hit the spacebar
at the end of the file leaving a single character of white space,
not a big deal, right.
We've all done it.
We all do it quite often probably.
But if a billion people are going
to download index.HTML today
and this programmer hit the spacebar, how many more bytes
of traffic is that for Google to transfer.
Yeah.
>> Gigabyte.
>> It's a gigabyte, right, like a single space character
for someone as big and popular as Google,
it means they're going to have
to transfer an additional gigabyte
of information for no good reason.
My God, what if he hit the spacebar twice,
that's two gigabytes, 10 times, that's 10 gigabytes.
So there's very real world implication,
certainly for the Google's and Facebook's of the world.
But even for your own website,
like why bother wasting bandwidth on things like that
when you can compress it once, still keep an original copy
for your developer so that humans can actually read it
and update it later, but the browser doesn't actually care.
So this is a very common technique for that reason.
And what's a third potential reason for wanting
to make your code look more like this?
Jack?
>> If you want to kind of deter competitors from trying to find
out how and why your code works.
>> Good. So if you want to deter competitors from how
and why their code works,
you can try to make it look a little more
like this, very easily.
Now realize that the smartest of people, the smartest
of adversaries, the smartest of competitors,
they can still figure out what your code is doing.
In fact, there exist tools that do kind
of the opposite of compressing it.
They will make it much more readable.
It can't obviously recover variable names.
If you have changed the variable from foo to f, these --
these decompilers as we might call them, are not going
to be able to resurrect information that's been thrown
away, but we could absolutely with, you know, a few minutes
or in a couple hours time figure out how most
of this is actually working.
So all you're really doing is raising the bar.
But that's probably enough, right.
Because if your -- you're worrying about your competitor,
and your competitor is smart enough
to decompile your minified JavaScript code and figure
out how your code works, frankly the person is probably smart
enough to just go implement it from scratch
without wasting time figuring out how yours works.
So, all your trying to do is raise the bar
to adversarial attacks like this.
So to be clear with something like JavaScript, with something
like CSS, with something like HTML -- you cannot, cannot,
cannot, cannot encrypt it
or prevent other people from seeing it.
That's just not the way the web works.
There exists tools that claim to do this, and there exist tools
that do actually do this.
These are a few that do indeed minify or compress your code,
but they do not fundamentally change anything
because even something like the middle one,
which effectively compresses your --
rather encrypts your code, the thing about encryption is
that if you have a secret key with which to encrypt code,
what do you need to decrypt it?
[ Inaudible Speaker ]
Oh, yeah, well maybe not generally the public key,
but the private key, but if we were using what's called
symmetric -- symmetric key cryptography, the same key.
So how do some of these products that literally can --
or you can find being sold online to encrypt JavaScript.
How do they work?
Yes, they do encrypt your JavaScript code,
but they also include in the encrypted file, guess what?
The key, right.
So it's idiotic, right.
It's not fooling anyone who is sufficiently advanced,
so just realize that the short answer protecting your
intellectual property when it comes to JavaScript, HTML, CSS,
all you can do is raise the bar to people figuring
out what you're doing.
But that should be okay in theory, right.
If the value of your company or your product is
that you have users and you can't just steal those
by viewing source, or you have actual databases and data
and interesting stuff going on server side, that tends to be
where some of the real intellectual property is,
more server side than client side.
So don't be misled into thinking
that these will keep your code safe,
all it will do is save you bytes and raise the bar,
which those of themselves are certainly still valid endeavors.
So let's actually try one of these.
Let me go to this one here.
This is just a smart guy who's put this together.
So these are actually reputable ones, the ones I put up.
If you're trying to be sold any such tool,
I wouldn't pay for it.
Let me go into one of tonight's files so that we can dig up,
let's see -- let's go into tonight --
whoops, let me pull up, let's see, will that work?
All right, let's just try it,
we don't need a whole example, we can do it by hand.
So let's see -- var annoy gets function,
let's see if this works --
alert hello closed brace semicolon, okay.
So here we go.
We're on this packer site, I'm going to click pack.
Okay, so here's what I've just done to minify my code.
You know, it's still quite readable frankly,
we could all probably figure
out what this piece of code now does.
But what did it obviously remove?
[ Inaudible Speaker ]
Okay, so white space is all it removed.
I think this site has a few options here just
to make this a little more interesting.
We can shrink variables, so I've just check the box at right
that says shrink variables.
Let's pack this again.
Now that really didn't do anything this time.
So let's do base62 encode, what does this do?
Okay, so this is what these sites tend to do
when they claim their encrypting your code.
So this is the same thing.
What is that doing?
What does that program do?
[ Inaudible Speaker ]
It prints hello, right.
That's all it does.
Now, all of this though can be reconstructed and frankly,
this just, it's kind of a cute little [inaudible].
So notice this guy has define an anonymous function
with the function keyword that takes six arguments, p, a, c, k,
e, r just because he's being clever with his name.
What is he passing in?
Well, if we actually parse the cell,
one of these arguments is apparently this variable
expression e equals string, the next is this if condition,
one of them is this split here
where clearly this is relevant to the original code.
Again, all we have done is obfuscated the code,
made it look complex, but at the end of the day,
a smart adversary could just execute this function
and see what the result is and piece it back together.
Any questions?
Whoops, sorry.
Questions?
All right, so let's go ahead and wrap there.
Myers here for section, which will dive a bit deeper
into JavaScript, Monday too, we will introduce the server side
of JavaScript, whereby we will actually have the ability
to perform and calls, additional htp requests that will allow us
to get more data from the server
and do all the fancier things while still using the same
client side technique to actually update
and not just reverse the DOM and the local webpage.
So more on that to come.
I'll stick around for one on one questions.