[ Silence ]
>> All right.
Welcome back to Computer Science S-75.
This is Lecture 7, Ajax.
I'm enjoying this process of asking what we did last time
since it's a hard question apparently.
What did we do last time?
Axle, you're the only one looking at me.
>> Yeah. We went through --
well, we had an introduction to JavaScript --
>> Okay.
>> -- which is a client-side interpretative language --
>> Good.
>> -- that stuff you can do with it.
For example, it's validate the fields before they're actually
sent to the server --
>> Okay.
>> -- to reduce circuit load and revive annoying HTML text
>> Okay, good.
Those are the two purposes of JavaScript.
So, yeah, we talked
about JavaScript client-side programming language.
It's executed within the confines of the browser.
We played with a couple of different applications,
the first of which was form validation.
Very common, very useful.
Less useful was the resurrection of the blink tag,
but that exercise, bigger picture hopefully,
give you a sense of how we can control CSS,
we can control the DOM itself and do something simple
or silly, yes, like resurrect the blink tag.
But more generally exercise control over the layout
of the page even after it's downloaded.
Jack.
>> We had this had roaming with the fact that we can't --
we can't use a JavaScript to do certain things
that we might want to do, like I wanted
to make a Submit Button have JavaScript even when it was off.
>> Okay. Have -- okay, can you push it a little?
>> So there are limits to what JavaScript can
and can't do based on what the browser interprets.
>> Okay. So there are limits of JavaScript.
And one example of this was?
>> That we know form
or something is disabled you can't run JavaScript off of it.
>> Ah, okay.
So, okay. So, that's fair.
I wouldn't highlight that as one of the main takeaways,
that JavaScript has these limitations.
But in the particular case we had disabled a form field,
and in this case Chrome, therefore,
decided to no longer trigger the events
that we were hoping to receive.
For instance, on Click or on Submit or the like.
But I would propose that's sort of a corner case
and you shouldn't read too much into that inability.
Yeah.
>> We also went through different ways
to find functions.
>> Okay.
>> One of them being that you can define functions
anonymously --
>> Okay, good.
>> -- without giving them a name.
So calling them directly from inside whatever triggers it.
>> Okay, good.
So we looked at anonymous functions, otherwise known
as lambda functions, and these are functions
that are exactly that.
They don't have names but they still take in arguments,
they can still return values.
And when is it useful or compelling to use a function
with no name and to define an anonymous function?
Yeah.
>> Well --
>> Isaac.
>> -- it didn't seem to blink example,
but I know that jQuery uses them all the time.
>> Okay. So we did it in the blink example
as one of the iterations.
jQuery does it all the time and, indeed, JavaScript, in general,
when you're doing browser-side programming
and even server-side programming as we'll discuss briefly
in the context of JavaScript,
anonymous functions are just quite useful
because they allow you to pass around functions really much
like they are themselves variables or values.
And so the fancy way of saying that is
that in JavaScript functions are first class objects
which means pretty much what we've experienced ourselves
where you can pass them around and create them on the fly.
All right.
So, a couple of administrative announcements.
So grades and feedback
on Project Zero should now be available.
You can go to the course's website and go --
or rather go to apps.cs75.net and see both comments
under the Submit button.
What you'll see is that after you submitted your own work
and were able to browse it
and see it's all syntax highlighted online,
your TFs have put up little Post-It notes style sticky notes
that have comments on various parts of your codes,
so you can browse their context-sensitive comments,
and then if you go to the grade book link,
you can view what the actual scores were and recall
that the axes on which we evaluate are scope correctness,
design, and style.
And if you have any questions, certainly reply directly
to your teaching fellow via email to ask questions or try it
in person or if you have questions
or concerns also feel free to reach out to me as well.
All right.
So, today we dive a bit deeper into JavaScript,
specifically using a technology or it's a bit
of an overstatement, a technique called Ajax.
What is Ajax in your current understanding if any?
Jack.
>> Some sort of JavaScript that can run
after the page is already loaded
and can load things from elsewhere.
>> Good. So it refers to the ability to run JavaScript code,
and specifically make HTTP requests in JavaScript code
after a webpage has initially loaded
so that you can grab more data.
And in what kinds of applications or websites
that you're familiar with is this useful?
>> Well, if you're making a website
that has Chat, for example --
>> Okay.
>> -- on Facebook, they can need to push new content
into the Chat window as people type things.
>> Perfect.
So if you're launching a chat room, right.
Back in the day the way
to implement an interactive chat room is literally
to reload the whole page or reload a frame within a page
that shows you the more recent instant messages
that someone's posted.
Nowadays you can just insert more div tags or span tags
into your DOM as we'll see today
so that you can see it dynamically updating itself.
Jack.
>> Google uses it all the time
like in their suggested searches --
>> Good.
>> -- or it may-- got instant load running,
and then they also have it in Google Maps to look
at certain parts of the world and things like that.
>> Perfect.
So Google does it with instant search and auto-complete
so that you're fetching some data from a server
and showing it to the user
without reloading the whole page.
Google Maps is another great example.
Yeah.
>> Connecting to Project One stock websites
like real stock trading websites would have
to do it otherwise you would have --
you would actually buy stocks that have an old price.
You have to upload --
>> Okay, good.
>> -- all the time to keep the user
or the broker [inaudible] part of the price.
>> Exactly.
I think it actually is finance.yahoo.com
or maybe it's Google Finance
that updates the stock price every minute or so.
So it's not perfectly real time,
but if you leave a web page open all day long,
hopefully by the end of the day you'll see the closing price
as opposed to the price that you originally saw
when you pulled up the page.
Excellent.
So a quick look back at a paradigm that we'll need to keep
in mind now that we're diving in deeper to JavaScript.
So, DOM. DOM was Document Object Model, and that was a fancy way
of saying what exactly?
And I realize there's a bug.
Pardon my lack of a closed body tag.
There should be one there.
Not a fair question, I think.
>> Well, it's
like a representation of the structure --
>> Good.
>> -- of a webpage.
>> Yeah. So it's a representation
of the structure of a webpage.
This looks sort of visually hierarchical whereby there's
some root to this structure, namely the HTML element.
And so what DOM similarly captures that kind of hierarchy.
>> Yeah. I was going to say
that we have a representation called Tree or --
>> Good.
>> -- B-Tree.
>> B-Tree.
So B-Tree, not in this case.
That's more of a database thing.
>> Oh, yeah.
>> Or, at least, we've seen it in the context of the databases.
But Tree, yes.
>> Yes.
>> Okay.
>> In the Tree you have nodes
and nodes have childs [inaudible].
>> Exactly.
So we have this tree here.
And the actual root of this tree we generically call the document
node, and that's so that you can hang different things off of it
like comments, for instance, or the HTML element in this case.
But in this case, beneath the HTML element notice
that we have the head element,
the title elements, body, and so forth.
And all of those show hierarchically what this page
looks like.
Once a browser has parsed it, that is, read it top to bottom,
left to right, into some in memory, in RAM representation.
So the neat thing about JavaScript starting today is
that not only can we traverse the DOM as we did last Wednesday
by actually accessing the username field
or the password field to do validation,
we can also mutate the DOM.
In other words, delete nodes, add nodes.
So, in the case of Facebook Chat,
what's really happening is there is some kind of tree structure
for the Facebook Chat window
and what they keep doing is appending more and more
and more children to one of the elements so that immediately
in JavaScript, once you've added a new node, a new rectangle,
in this case to the tree, the browser is supposed
to display that new content.
So we'll do it today, albeit with a stock example,
but in a way that's representative
of how you can insert yet more information into a page.
So Ajax more properly flows as follows.
So on the left- and the right-hand side here we have a
client and a server, respectively.
And we have five different steps
that describe how Ajax itself works.
So in Step One, we have some JavaScript called.
So, actually, let's roll back.
So you just visited at Facebook.com or Google.com
or C75.net, whatever website it is
that has some JavaScript code that's using Ajax involved.
Then you do something
that triggers the getting of more information.
You click a button or maybe it just happens every minute
on its own, and now we're in Step One.
So there's a JavaScript called where it instantiates,
so to speak, an object
in JavaScript called an XML HttpRequest object.
This is sort of a fancy object similar in spirit
to the document object of the Window object
that you already have access to in JavaScript.
But this one's all about Ajax.
That object is allowed in Step Three
to make an additional HTTP request
without the user reloading the whole page.
So it's a function call related to that object.
In Step Four, the web server realizes, oh,
I've got a request for more data.
Maybe it's for some chat messages;
maybe it's for some stock prices, whatever it is.
Maybe the web server in Step Four has to talk
to its own database which might be the case
in the Facebook Chat model
if you're storing those messages persistently.
And, eventually, the web server responds at the end
of Step Four with, in this case, some XML content.
So XML we talked about early on.
You're using in for Project Zero.
And it's a very common format for moving data from one server
to another in a way that's easy to parse after the fact.
Semantically tagged, much like your pizza menu.
So in Step Five, finally, the browser has received
that XML data and it turns
out in JavaScript you can parse XML much like you can in PHP.
And so what Step Five is proposing is
that upon receiving this XML data, which contains, again,
some instant messages or some stock prices, whatever it is,
that XML is converted by JavaScript code that you wrote
to HTML and/or CSS, and plugged into the current web page.
So we'll see all this in real terms
in an example in just a moment.
But, in short, browser requests more data using this fancy
object called XML HttpRequest.
The server receives that request,
figures out what it wants, responds with some XML.
The JavaScript code on the client then reads that XML,
converts it to HTML or CSS, much like you guys did
for Project Zero but in PHP.
And then the user sees the end results.
And, of course, this all happens [finger snap] pretty darn fast.
So there's one sort of dated aspect here.
Ajax, once upon a time, stood for Asynchronous JavaScript
and XML because when it first came
into vogue XML was the transport mechanism.
It was how data was sent from server to client.
These days a different data format is much more popular.
Yeah?
>> This is a guess -- by JSon?
>> JSon, yes, exactly.
JavaScript Object Notation.
J-S-O-N is much more popular these days, daresay, than XML,
in large part because it's less verbose.
In other words, XML has open tags,
closed tags, a lot of redundancy.
It's very readable but it's also very bloated
and that was partly by design.
It was meant to be very human-readable,
but it's perhaps excessively so.
So, in JSon, as we'll see,
you have a much simpler data format and, in fact,
JSon notation is identical to object notation
that we saw last time when we just looked
at JavaScript objects.
Indeed, that's what JSon means -- JavaScript Object Notation.
So this format is very simple.
It's much less verbose but it's also relatively easy
to read and understand.
You don't quite have the same notion
of attributes and child elements.
But you have the notion of children through hierarchy.
So we'll see in just a moment what JSon looks like,
and that is probably a much more compelling route
to go these days for transmitting your data.
And, in fact, that's why some people, as I did here,
write Ajax in lower case now
because it's not necessarily an acronym anymore.
So let's focus on this special object for a moment.
So there is a feature in modern browsers called the XML
HttpRequest object.
Again, it's similar in spirit to special global objects
like a date object, a string object, a window object,
a document object, and so forth,
that exists in the context of a page.
This particular object has a bunch
of functionality that's built into it.
At the end of the day it all has to do
with getting HTTP-based data.
How is that implemented?
Well, for instance, there's an open method inside
of this object, and the open method can be called
in a few different ways.
It has a few different signatures.
You can call it with two arguments, three,
or even four arguments.
But at the end of the day open simply opens an HTTP connection
from the browser to some remote server.
There is a Send method which can be called with
or without an argument, but it does as the name suggests.
It actually sends data over an open connection
from the client to the server.
So it's a two-step process minimally to actually get data
from a server via Ajax.
You open a connection.
Then you send your request.
You send your Get request or your Post request,
and you're going to hopefully get back a response.
When you do, you can call something like GetResponseHeader
or GetAllResponseHeaders to actually get the HTTP headers
that the server returned.
I would propose that that's not terribly common for you to need
to call that method directly.
There are simpler ways of reading the response.
And we'll see in just a moment how you access the response.
But there's an Abort method
which means stop this connection.
For instance, if the user clicks Cancel and you want
to abort an open Ajax request if it's being slow.
That's possible as well.
So an XML HttpRequest object now has a bunch of properties.
So recall that objects
in object-oriented programming have methods
and they have properties or data members.
So the properties for this object are as follows --
onreadystatechange, which we'll come back to,
readyState, this is easier.
This is just a number.
So there is a property inside of an XML HttpRequest object
that tells you what state the object is in.
Is it in state zero, uninitialized?
You've created the object
but you haven't done anything with it.
You haven't requested any data from a server.
Step One, or State One, open.
Have you opened a connection before having sent anything?
State Two.
Have you sent information?
State Three.
Are you currently receiving information?
And, finally, State Four, loaded.
Are you all set?
So the reality is that when you make an Ajax request you go
from State Zero to Two pretty darn fast -- Zero, One, Two.
And then you've sent your request.
So it's not that interesting looking at all
of these individual state changes.
In fact, what most people do is only look at State Four.
In other words, you keep an eye on this object
after you've sent a request.
And only once the object state has changed
to Four, do you care.
It's rare that you need to care about Zero, One, Two, or Three.
Four means it actually worked and you had back some data.
So responseBody, responseText, and responseXML.
You kind of see some of the legacy features here
or rather the original design intents here.
But responseText literally contains the browser's response.
Sorry, the server's response.
If the server has returned HTML, if the server has returned XML,
if the server has returned JSon, it's in responseText.
It's exactly what the browser returned.
It's what you, the human,
would see if you manually visited the URL in question
with your own browser.
ResponseBody is generally used for something like HTML.
So if you actually want to get back more
than just the raw text, but some representation of it.
ResponseXML -- if the response was XML,
responseXML hands you a DOM.
It hands you the root of the tree that the browser built
up upon reading that XML.
So, in other words, if you want raw text,
you go with responseText.
If you want a DOM that's been pre-parsed
for you, you use responseXML.
So, in short, if you're expecting XML,
you should actually access the return value via a responseXML,
otherwise responseText generally suffices.
Notice there's no response JSon.
Response JSon is transmitted just as pure text
and there's generally an additional step we ourselves
have to implement in order to convert JSon,
which is just going to be text, to an in-memory representation
of a JavaScript object.
So we'll see that in just a moment.
Lastly of interest, status.
So these you can probably infer what status is.
Whereas readyState refers to this internal notion of state
for the XML HttpRequest object.
Status clearly refers to what exactly?
What does status refer to?
Yeah. Excellent.
>> It's what the server you're requesting things
from sends back.
>> Exactly.
So this is one of the first things
that are sent in the headers.
Is it 200, which is okay.
That's a good thing.
If it's 404, it means you might have made an Ajax request
but you screwed up.
You visited a URL that just doesn't exist.
Five hundred means something bad really happened.
There's 401, 403, all of the usual ones.
So, in general with Ajax, what a programmer will check
for is am I in readyState Four, and was the status 200?
If so, life is good and I can proceed
to do something with the response.
Otherwise something bad happened.
So that's the general failure case.
All right.
So that's the high-level setup.
Let's go ahead and take a look at an example.
So in today's lecture examples we have a whole bunch
of files -- Ajax1 and on upward, a JIF, and some PHP files.
So let's go ahead and implement a very small web-based
application that allows me to check stock prices.
So let me go first to Ajax1.html.
And this is a very simple user interface.
And I'm going to go ahead and type in GOOG --
G-O-O-G, as the stock symbol for Google.
I'm going to click Get Quo.
Okay. So this is pretty much something we could have done
last week in terms of the alerting.
But notice what didn't happen.
There was no whole page reload.
And, in fact, as you've been working on Project One,
cs75 finance, odds are when you click the Submit button
on your quote page you're led to another page in order
to see the response from the server.
But I haven't done that here.
I've used this quick and dirty approach
of calling the JavaScript Alert function.
But notice that my URL has not changed.
And that's the key takeaway for now.
I am not visiting a new page all of a sudden.
I have somehow retrieved data dynamically from the server
and then shown it to the user without refreshing the page.
So let me go ahead and open up Ajax1.html.
I'm going to use a text editor called Vim, but you can do this
in most any text editor.
And let me zoom in on first the HTML at the bottom.
So at the very bottom we have a form element.
We have quote1.php as the action
which we'll see is a very simple file
that I essentially ported over from last week.
Method equals get.
On Submit equals quote no argument semi-colon;
and then you can kind of infer --
this is an interesting little thought exercise.
What does it likely say after quote semi-colon?
Re -- what's that?
Isaac?
>> Return quote?
Or --
>> Return -- no, not return quote
because we already called quote.
>> Although the --
>> Quick.
>> Response maybe?
>> No. Quick.
Oh, come on.
>> False?
>> Okay, false.
So why is this?
So this was a reasonable question,
I thought, to ask, right?
Because what's the intended behavior here?
Do you want this form to be submitted?
>> No. Yeah.
Obviously not.
>> Good save.
So, obviously not.
So you don't want the form to be submitted
because if it did get submitted you would have been led
to another webpage as is the case.
And that webpage in this case would have been quote1.php,
so that sort of HTML 1.0 style form interactions.
So in this case I didn't want the form
to actually get submitted, but I wanted to use a form
to get user input, right?
I wanted to enable someone like me to type in G-O-O-G,
and hit a Submit button.
But I want to, in JavaScript code today,
override the default form handling behavior,
much like I did last Wednesday when doing form validation.
But this time I want to not only intercept the form submission,
I want to do the HttpRequest myself
and then show the user the response.
So I still want to use the input mechanism of a form,
but I want to implement the backend functionality myself,
the handling of that form submission.
So let's see what I've done here.
I've only asked the user for a symbol, and I've noticed
that I've given the symbol a name of symbol.
But I've also given it an ID of symbol.
A little redundant but it turns
out this makes my life a little easier
in just a moment in code as we'll see.
The type is text.
A couple of line breaks and a Submit button, and that's it.
So in terms of HTML there's nothing fancy here.
The only thing of interest is apparently this event handler
on Submit.
So just to be clear,
what function obviously is getting called
when I click Submit now?
>> Quote.
>> Quote. So let's scroll up now
and see this supposed quote function.
So if I scroll up to the top, notice that in the head
of my page I have a script tag, much like I had last week.
And now notice I have a variable up there called xhr
which is just shorthand notation,
totally arbitrary, for XML HttpRequest.
Could have called it fubar baz.
It doesn't matter.
But notice that I've initialized it to null for now just
so that I know what its initial value is.
Now notice down below I have a quote function.
So if I scroll down below the break here,
notice that I'm doing a few lines of code.
I am trying to instantiate an XML HttpRequest object.
And if that fails because an exception is thrown,
I'm going to instead try to instantiate an ActiveX object.
So what's going on here?
This is somewhat dated.
This is really here now just for backwards compatibility.
But take a guess as to why or why we're doing this
or what we're doing here.
Axle?
>> I mean, the XML HttpRequest,
that's what you're first trying to create.
>> Good.
>> And if that doesn't work you're probably using some older
version or another version that works on public systems.
>> Good. And what system might that be in this case?
>> All the Microsoft systems.
>> In IE, yeah.
So this is the result
of the browser manufacturers not cooperating years ago
when whereas most of the world was going in the direction
of supporting an XML HttpRequest object,
IE was not so accommodating at the time.
So this what you might see underneath the hood of something
like JQuery or JavaScript Library
that we'll see tonight will actually simplify a lot
of the code that we're writing right now.
In fact, this is deliberately verbose.
This is deliberately low-level
so that you can see how the underlying code should be
implemented even if you're abstracting away ultimately a
lot of these details with more user-friendly libraries
like JQuery.
In fact, we'll see by the last Ajax example tonight,
we're going to simplify all of this code
to something that's much, much cleaner,
but still just as functional.
So in short, this is actually kind of an abusive try/catch.
In general you shouldn't be using try
and catch for a logic flow.
In other words, you shouldn't be using it
as though it's kind of like an if/else.
But the reality is this is the way to do it here
because the XML HttpRequest object will trigger an exception
if it doesn't exist because you're using IE6
or something like that.
Okay. Well, let's assume by then we have something
in this variable xhr.
If not, it's going to be null.
In which case we're going to yell
at the user saying Ajax is not supported by your browser.
So not a terribly common concern these days.
But if the user's using an older browser,
maybe certain Blackberry devices, or older devices
that didn't have full-fledge JavaScript support,
you might run into this.
So, in general, we're just doing some good error checking here.
But suppose that xhr is not null and we actually have a reference
to one of these objects.
Let's see how you can make an Ajax call.
It's actually pretty simple.
So, first, I'm going
to construct a variable called URL whose value is quote 1.php
question mark symbol equals something.
All right.
Why is that?
Well, I want to make an HttpRequest to quote l.php.
It's in the same directory as the current HTML file,
so I don't need any slashes or I don't need any HTTP.
I can just use a relative URL.
And just as you did, or are doing in Project One,
creating URLs sort of on the fly with --
or for Project Zero with question mark symbol equals,
what's this next line?
Well, plus means concatenate.
And if we scroll over to the right here,
document dot get element by ID symbol dot value,
just in English, what is that expression doing for us?
Document dot get element by ID symbol dot value.
Yeah, Ben.
>> Just getting what you typed in.
>> Yeah. Exactly.
Just getting what the user typed in.
Specifically it's using the document object.
Recall, that's the special global object you have access
to in JavaScript.
Get element by ID we haven't seen yet but this is a function
that exists inside of that document object
that does exactly what it says.
It gets an element in a webpage by its ID.
Notice that it's not by name.
If I had used -- or rather by tag name.
Tag name actually I think we did use last time
where I searched the DOM for all of the blink tags.
In this case I want one specific tag,
the one to whom I assigned an ID of symbol.
So that's why I gave it an ID.
Dot value means get the actual textual value of that node.
So in short, I've constructed a URL right now that's quote 1.php
question mark symbol equals what?
>> GOOG.
>> GOOG, G-O-O-G.
So that's it.
I have a string now in memory and a variable called URL
that I now pass as follows --
xhr dot onreadystatechange equals handler.
Let's again ignore that for just a moment.
Line two -- xhr open quote unquote get url true.
This is actually a little more verbose than it needs to be,
but this is clearly preparing to send an HTTP Get request,
the sort of easy one that's all URL-based.
The URL is the destination True just means asynchronous
which is the default.
But I put it there to be explicit.
And we'll contrast this with synchronous in just a bit.
xhr dot send null just means send the request.
All right.
So, in short, what's happening?
The open line opens an HTTP connection
to the server via a Get.
The second line, Send, actually sends the request.
And that's it.
And it's null because all of the data
to this request is embodied where?
>> In the letter.
>> In the -- well, in the URL specifically,
because we have the question mark.
Because we're using Get we don't need to send additional data.
So to be clear, if we were using Post,
the means by which you send post data via Ajax,
is to actually pass in an argument to the Send function
which we are not doing in this case.
Just Get suffices.
All right.
So that's it.
We send it.
But nowhere is there code apparently
that actually handles the server's response.
Recall that in our picture,
Step Five was client gets back a response from the server.
And it has to create some HTML or CSS
or in this case a JavaScript alert out of it.
So where can we find, even though we've not seen it,
the JavaScript code that's going
to actually handle the server's response?
What's that function called do you think?
Axle?
>> Maybe request headers.
>> Request header.
Okay, no. This would be a function I wrote,
not that comes with the object.
>> Oh, okay.
Handle response?
>> Okay. How about handler?
[ Inaudible Speaker ]
So in this case it's purely up to me.
And so we finally have an opportunity to spell out what
on ready state change is.
So this, too.
It's sort of an annoyingly long-named property,
but it does exactly that.
Anytime this xhr object changes state, zero to one,
one to two, one to three.
I'm sorry.
Zero to one, one to two, two to three, three to four --
that function is going to get called.
What function?
Well, xhr.onreadystatechange equals handler is telling it
to call a function that's apparently called handler.
And, again, this is a bit
of a tricky question seen out of context.
But sure enough, if I scroll down,
there's my handler function.
So, in other words, everytime this object changes state,
the following code is going to get executed.
If xhr.readystate equals equals four
and xhrstatus equals equals 200, what do you want to do?
Well, there's our magic.
Alert xhr.responsetext.
Otherwise we yell at the user with an error.
But that didn't happen when we played just a moment ago.
So, to be clear, why am I checking for readyState 4?
What does that mean?
Yeah.
>> That means that the data has been received --
>> Good.
>> -- by them.
>> So that is the final state in an Ajax request.
It's really the only one we care about.
In fact, even though this function will get called
for readyState zero to one, one to two, two to three,
the only one we're going to care about is when it becomes 4.
Otherwise that if condition won't even evaluate to true
in all those other cases.
So if it's indeed in State 4,
which is that data has been received and is ready
to be parsed, then we check, wait a minute, let's make sure
that not only we got a response from the server
but it was a okay response, a 200 response, and not a 404
or 401 or something else.
And if that's the case, then we can trust
that in the response text property
of this object is what the server sent back.
So that's it.
To recap, we click Submit on the form.
Our on submit handler get invoked
which calls our quote function.
The quote function, it creates this XML HttpRequest object.
It then creates this URL dynamically
to create a Get request
with question mark symbol equals GOOG, in this case.
It opens a connection to the server.
Sends the request.
And then finally the handler function gets called and as soon
as the state is 4 and the response is 200, voila.
We have our Ajax response.
And then we can play this game all over again
by just submitting the form again
with something besides Goog.
So, in fact, if we go back to our example and into Chrome
and type in, let's say, MSFT, get quote.
We now have Microsoft's stock price,
which is $29 give or take.
As an aside, notice that even though we tend to think
in dollars and cents, as you've probably noticed
for Project One, Yahoo Finance does return slightly longer
prices to the hundredths place or thousandths place or beyond.
So do keep that in mind
when storing prices and costs and such.
All right.
So the file we haven't looked at is Quote1.php.
It turns out this is pretty simple and pretty much stolen
from last week whereby I need to write a little program here
that gets the stock price from Yahoo somehow.
So how do I do that?
Well, I use fopen and I use the same URL
that you're probably using in Project One
that we played with last week.
I'm checking if the handle is not equal to false in this case.
As an aside, if you've seen me write it in lower case
in the past, php unfortunately is case insensitive sometimes,
so false in capitals is the same as false in lower case.
Just be consistent within your files.
Data equals fgetcsvhandle.
What does that do in English when you call fgetcsv
on an open file handle?
Axle.
>> I think it parses the csv.
>> Good. It parses the first row of the csv
and it returns to what?
This should be familiar from Project One.
It returns an array
where bracket zero is the first column,
bracket one is the second, and so forth.
So what am I checking for here?
I just have a little sanity check.
If the row is not equal to false;
that is if fgetcsv returned a natural row
and the first element is not applicable --
rather is not -- sorry.
[Inaudible] and data is there equals equals NA.
Oh, that was incorrect logic.
Right idea, wrong implementation.
So you can check for NA if -- NA is among the values returned
when you've looked up a bogus symbol.
I did not mean to check here for NA.
I meant to check here for not NA.
So it turns out that the csv file is always putting NA
in bracket zero, which is why this is working.
So, in short, ignore this little error checking.
I goofed slightly and I'll fix it before I re-upload it
to the server.
But the point ultimately is
that we are using this PHP script to query Yahoo.
We get back a csv.
We parse the first row.
We grab the stock price,
much like you're presumably doing for Project One.
And then what are we doing once we have that stock price?
Just printing it out.
So all quote1.php is doing is spitting out some raw text.
And we can actually see that.
Let me go to the appliance and go not to Ajax1.html,
but go to quote1.php question mark symbol equals msft enter.
And indeed, what I get back in the body
of my response is just the price.
If I view the page source, that's all that's there.
Nothing else.
So, in short, our HTML file talks to the PHP file
which in turn returns a response
that gets embedded into the former.
Any questions?
>> I have a question.
>> Yeah.
>> So for the project we have the flexibility
to do it just the PHP way and kind of go from one,
submitting the form --
the symbol on one form and getting it on the other?
Does that get CSV?
>> Yes.
>> [Inaudible] or is that the requirements
of doing the Ajax --
>> Correct.
No Ajax requirements for Project One.
It is totally acceptable and expected
to do it the last-week way
where you moved the user to another page.
Correct. All right.
So, what's not so good about this?
Well, this is hardly as sexy as Facebook or Google
or really any site that actually uses Ajax
to create a more dynamic interface.
All I'm doing is calling this annoying JavaScript alert
function, which is hardly what I'd call compelling.
So how can we take this one stop closer to something
that we're more familiar with?
Well, let me open up Ajax 2.html, and this time scroll
down to the HTML just to see the following.
I've added something to this page's HTML
which is what apparently?
Axle.
>> A price input.
And notice I got rid of the name attributes altogether
because I'm not actually submitting this form
to the server.
Really, all I need is a unique identifier.
And for that an ID is, by design, meant to be unique.
So I have an ID of symbol and an ID of price,
which means programmatically in JavaScript I should be able
to access each of these elements directly using document.element
by ID, just like I did before.
So this is kind of a step towards something better.
It's not as good.
But if I want to request from the server a stock price
and then show it to the user, my goal now is get rid
of the stupid alert function.
Instead I want to embed the result in a webpage.
Now one way I know of doing this is if I have a blinking prompt
for instance in a field called Price,
maybe I can use JavaScript to update the value
of that blank input field.
So, in other words, if I go to my browser and I type
in for Version 2, the same symbol like GOOG,
notice now that the response is not going to come back
as an alert, and notice there's nothing in here right now.
But I click Get Quote and now it gets populated there.
Now this isn't the best approach because I can delete that
and that doesn't feel quite right that I should be able
to delete the server's response.
It feels a little weird that I can type whatever I want
in there only to have it disappear.
But at least it's better, I would argue,
than the alert function.
So how are we doing this?
Well, you can perhaps guess what the code's got to look like.
But the top of this file is identical.
My quote function, and we won't go through it line by line
because it's indeed identical, is the same as before.
So the handler function is apparently what's changed
and how is it changed?
Well, notice my handler function,
in addition to checking for readyState 4 and status 200,
this time it's doing document.getelementby
IDofprice.value equals -- and it's cut off at the moment.
But what must be to the right?
What's the rest of this expression?
>> xhr.responseText.
>> Exactly.
xhr.responseText which is the price that we got back
from the server which was spit out by quote1.php.
So, again, not perfect.
But I'm kind of learning as I go here.
And I know that I can access the current value
of an input via this dot value property.
So it stands to reason that I can change the value
of an input element by just using code like this.
So this is not good though for a couple
of reasons which we've seen.
How can we do a little better?
Well, let me open up the third variant of this.
Scroll down to my HTML.
And what's fundamentally different here?
Louis?
>> It's in a span instead of a input?
>> Yeah. So this time I'm using a span tag instead of an input.
A span tag is an inline HTML element.
It doesn't create any visual effect unless you're using CSS
to stylize it somehow.
But it's a way of saying this chunk
of HTML should be uniquely identifiable by an ID of price.
In other words, if I didn't have that ID,
it wouldn't be as useful.
I could find this element but the fact
that I'm giving the span an ID means it's going to be
so much easier in JavaScript code to dive right
into that part of the DOM and mutate its value.
But we're going to have to do it a little differently.
And just to be super clear as to what's happening,
notice that that span currently has some HTML in it.
It has bold-faced words, "to be determined."
So what does this look like on the webpage?
Well, hopefully, I'll see in bold
"to be determined" in Version 3.
So let's take a look.
And, indeed, there it is.
Couldn't be more explicit.
This is not editable.
Notice I can hit the keyboard all I want.
It's not changing because it's just a span tag as we've seen.
But now I type in GOOG and hit "Get Quote."
And now we have something that's a little closer to Facebook
and Google and these websites that actually update the website
in line without using these hacks
like an alert box or a text field.
So what must be happening here?
Well, let's scroll up to my handler function here,
and notice the one difference now is
that I'm still getting the element by ID of price.
But what property am I mutating?
Axle.
>> InnerHTML?
>> Yeah. So in this case it's a little different.
Whereas, an input element has a value property
which is literally its value, in HTML elements like a span
or a div or a bunch of others,
instead has an InnerHTML property.
This isn't necessarily the best way of doing this,
but it does work and it's the quickest and simplest.
So we'll start with this approach here.
So InnerHTML is exactly that.
I can cram into the child --
I can cram into the price span whatever I put to the right
of the equal sign there.
And in this case, again, it's xhr.responseText.
Now I did lose the bold facing,
so let's actually see this in action again.
If I go back to my browser, reload.
Let me go ahead and open up Chrome's Inspector.
Whoops. Open up Chrome's Inspector here.
Oh, my god.
Why is it doing this?
Chew-chew-chew.
We want tools.
Okay. Developer tools.
Okay. So in this window let me go ahead
and open the form and go down to price.
And there's the span.
So in the bottom left notice that's what our HTML looks
like at the moment.
As soon as I type in GOOG and hit Get Quote, watch the HTML
on the bottom left-hand corner even though it's a little small.
Okay. So it changed.
And it changed to this, literally 616.82.
And what went away?
The bold face tags because I told the inner HTML of the span
to take on xhr.Response text.
So suppose I wanted to cram those bold tags back in there.
Well, I can do this in a few ways.
This is probably not the best way, but I could do it this way.
If I really want those tags
in there I could do something quite literal
like open bracket B plus, and then I can do close B over here.
Close -- whoops.
Close bracket.
Save this.
Go back over here.
Reload. And now type in GOOG.
Get Quote.
So now it's still bold.
And if we look at the HTML down here,
notice I get my bold tags back.
But there are better ways of doing this, right?
What might be a cleaner way rather
than reconstructing these bold tags again and again?
Isaac.
>> You could put the bold tags around the span.
>> Okay. So one approach, put the bold tags around the span.
Another approach?
>> Give the bold tags the ID price and update the --
>> Good.
[ Inaudible Speaker ]
So there's nothing stopping me
from actually giving the bold tag an ID of price and homing
in on its inner HTML instead.
And, frankly, that would pretty much obviate the need
for the span tag whatsoever.
What's another approach to preserve the boldness?
Frankly b-tags are kind of frowned upon these days
because you're comingling data with aesthetics.
>> I mean, you could just do a JavaScript
that sets all the text of this current class
or an ID of 2 bold.
>> Okay. So we could JavaScript
to set some class to make this bold.
But it would be even simpler.
We don't need JavaScript for this.
What do we need?
How do we make this whole element bold not matter what its
contents are?
Jack?
>> You could put the bold type outside the span?
>> Ah, that was Isaac's idea.
>> Oh, sorry.
>> Workable, but we can do this a little more cleanly.
Axle?
>> It feels like we're just guessing now.
But style inside the --
>> Good.
>> -- inside the span and then maybe you can do a
CSS [inaudible].
>> Right. We just CSS.
So the JavaScript idea would work but it's totally overkill.
We can just put a style attribute there.
Style equals font weight bold.
We could put this into a separate CSS file elsewhere.
In other words, we can do the stylization
without resorting to the bold tag.
So this is really just here for clarity, but we can factor
that out and put our stylization is CSS as usual.
All right.
So all possibilities.
What more can we now do?
Well, let me go ahead and open up a fourth variance of this,
and this going to look uglier so it's going
to be a step back for just a moment.
Where does it appear?
I'm going to be spitting out the server's response of this time.
Yeah, Louis.
>> In a text area?
>> In a text area which is perhaps even uglier
than the input field we saw before.
But it's compelling for the moment because now I'm going
to start experimenting with returning multiple lines
of output from the server.
In fact, I don't want just the price now.
I want this to be a little sexier.
I want the day's high and the day's low in addition
to the most recent price.
So I have three values that I want to come back,
and I need a text area for the moment just
so I can see everything coming back from the server.
But notice I pruned the form further.
Notice that my form no longer has a method attribute.
It no longer has an action attribute.
Why is that okay?
Axle.
>> You're never using them.
>> Exactly.
I was never using them anyway,
even if I might have mentioned quote1.dotphp is the action
in some previous version.
I don't need it anyway because all I'm doing is intercepting
this form submission and then I'm doing that process
of the HTTP request myself in JavaScript code.
So I've pruned this a bit further.
Now let's take a look at the end results here.
Let me go back to the web browser.
Let me go to version 4 here.
Enter. This is pretty hideous.
But it feels like I now have room for more stuff
to come back from the server.
There's one other difference here.
If I scroll up to my quote function,
what URL am I constructing this time?
[ Inaudible Speaker ]
Yeah?
>> Quote2.php.stepquote1?
>> Exactly.
And now I'm using quote2.php which is almost the same.
But what is its output apparently going to look like?
Yeah.
>> Who?
>> Axle.
>> It prints spell Price, and then a new line, and the High,
and then a new line, and then Low, then nothing.
>> Exactly.
So a little hackish at the moment.
But this time I'm going to print
out three values -- Price, Colon, Number.
New line. High and the Low.
Same deal.
So it's not very elegant and this pretty much means
that I'm going to have just plop all of this text in one place,
the same place in the webpage.
I can't put the Price up here, the High over here,
the Low down here, or whatever.
Can't integrate it like into Yahoo Finance UI very well.
This all has to go together became I'm returning it all
at once.
But at least we'll be one step closer.
So let me go ahead and type in GOOG here.
Click Get Quote.
And sure enough, now I get back these values.
Now I could kind of hack something together, right?
I could use JavaScript and figure out where the colon is
and somehow extract the numbers that I've returned
so that I could put them in three different places.
But what would be a cleaner approach here?
If I want to somehow get back more than one value --
I don't want Price alone.
I want Price and High and Low.
How can I go about returning something more useful
from the server?
Axle.
>> I don't know if this would work, but you could
in the PHP print an array or return an array somehow.
>> Okay. Good.
So what if we actually return not just some arbitrary random
like David style of new line, new line, new line.
Why don't we actually use something standard
like an array?
For instance could we create an array in PHP
and then somehow print it out maybe using Print R.
But that might be a little hard to parse in JavaScript.
But somehow return the actual object.
Well, I can do this pretty easily in code.
Let me go over here to quote2.php, and let me do this.
Let me go in here and let me try a suboptimal way first.
Let's delete these three.
Actually, first let's do this.
Let me go to quote2.php in a separate tab just for clarity.
So this is quote2.php question mark symbol equals --
whoops -- symbol equals GOOG.
Enter. So that's what's coming back right now from the server.
Let's make it a little more machine-friendly.
Let me delete, delete, delete.
How about this?
Print r data, where data is the row
that I got back from the server.
Now let's reload.
Okay. So this is a little better but not quite perfect.
Why? Well, because if I'm getting back literally this
string of text, if this is the contents of response text,
how do I go about parsing this in order to extract the Price
and the Low and the High?
I have to literally parse this mess.
Like I need to write a JavaScript function
that somehow reads this thing, top to bottom, left to right,
figuring out what the various prices are.
So we need it to be a little cleaner.
So what would be a better way of representing an array
of values here, an object of values?
What else could we do here?
Well, let's do a quick little spoiler.
Instead of printing this, let me instead print the results
of calling JSon and code, a new function tonight,
that quite simply is going to output something
that looks a little more like this.
And what does this syntax remind you of?
Yeah.
>> It looks very much like a non-associative array.
>> Exactly.
This is a non-associative array in JavaScript.
It's using the square bracket notation
which is how you can infer as much.
This is one of the key features of JavaScript
that we looked at Wednesday.
Now it's not ideal in that there's no metadata
like Price, High, and Low.
I'm going to have to remember that bracket 1 in Price,
bracket 2 is High, I think, bracket 3 is something else.
There's the escaping issue here which is kind of interesting
in that the forward slash is apparently a potentially
worrisome character, but that's actually not such a big deal.
But here we have the beginnings of JavaScript object notation,
the returning from the server of something that's compatible
with JavaScript even though it was generated by PHP.
And that's going to be the power that we're going
to start harnessing to make the UI all the more dynamic.
But why don't we pause on that cliffhanger.
Why don't we take our five-minute break here
and come back with some sexier examples.
All right.
So this is pretty bad, resorting to this HTML text area.
So we can do one step better than this.
Just like we introduced the span as an alternative
to an input field,
we can instead replace this text area with, say, a div, right?
A div at least allows for multi-line text.
So not ideal yet, but at least we can go one step closer.
So let's try this.
So in version 5, I proposed to have this placeholder.
So, again, resorting to my ugly boldface placeholder.
But that's going to be overwritten in just a moment
because this time when I go ahead and type in G-O-O-G
and click Get Quote, I now get this.
And what's the outputted HTML look like?
Well, if I look at down here, notice that I have div this time
that simply has some br tags in the middle.
So how do I make -- what changes are necessary
to make this possible?
One, I need to remove the text area from my HTML
and replace it with what obviously?
>> Div with an id quote?
>> Good. A div with an id of quote/unquote/quote.
All right.
So, that needs to be there so I can uniquely identify this spot.
And what else is in here?
I have br tags.
So what else needs to change?
Because what was the server spitting out previously?
Yeah.
>> Well, the server was spitting out just the text
about anything in-between, so now we're sending it
with JSon instead, parsing it, and then printing the first key
of the array, and then a br for the second key.
>> Oh, good.
Okay. So, actually, let me take a step back.
So the cliffhanger of taking the JSon approach,
not quite there yet.
So, instead, consider where the quote function was before I
manually updated it right before the break.
Previously we were outputting new lines.
In this case we clearly need to be outputting br's.
But now things -- and this will be an argument in favor further
of using JSon because notice that this example here,
version 5, is using quote3.php,
and quote 3.php really takes this suboptimal approach
if spitting out br tags.
And this, too; now this is a very slippery slope because now,
not only are we spitting out on the server data,
we're also now spitting out mark-up.
So this really is not ideal.
Better is going to be to something
like a JavaScript array or maybe a JavaScript object.
And then we can take care of doing the stylization
and formatting on the server itself.
So let's take a look then at this 6th variant
where we get a little closer to that.
But, first, let's resolve one other detail.
In Ajax6.html, I again have this div placeholder.
I, again, am going to search for GOOG.
But notice what happens this time.
It's kind of sexy, right?
I have a bit of a progress bar
of sorts here before I actually see the value.
So it looks like the server was kind of slow which is great
because I had the sexy little looking up quote dot-dot-dot.
Looking up price, dot-dot-dot.
And then the price appear.
So how do we go about implementing that?
Axle?
>> Well, I think state 3 of the Ajax request was --
it's loading but it hasn't finished receiving everything.
>> Okay.
>> So you would set the text of that span or that div
to loading [inaudible].
>> Okay, good.
So we can take advantage of the ready state property
and display a message based on the state we're in.
To be honest, I think we can even simplify it further.
Rather than doing it when the state changes,
why not just do it when the user --
>> Clicks the button.
>> -- clicks the button, right?
Then I don't even have
to remember what the various states are.
Four is the only one I've cared about thus far.
And it's frankly the only one you really need
to care about functionally.
But I can in my quote function change the contents of that div
and then, fine, I'll just change them again once my handler
function gets called.
So we don't have to mutate the DOM just once.
We can do it as many times as we want.
So, sure enough, in Ajax 6 here,
notice that I have the following code in my quote function.
After constructing the URL,
but before I actually make my Ajax request, what am I doing?
I'm informing the user by updating the inner HTML
of that quote div to be quote/unquote looking
up symbol, dot-dot-dot.
And that's it.
Now, if I scroll down to the handler function,
I'm doing something very similar,
identical to what I did before.
In this case I'm just re-updating
that quote element inner HTML with the response text.
Now it was not quite a coincidence
that this time the server took a while to respond.
In order to simulate this effective,
notice the little trick I did in quote5.php.
That's why you got to see the dot, dot, dot for five seconds.
But, more generally, if you don't need --
this is not a good thing to do in an actual production system
since you're just wasting people's time otherwise.
So this is meant just to simulate a slow connection
so we could actually see it.
Otherwise it would be pretty instantaneous.
But you don't typically just see something like looking
up symbol dot-dot-dot.
What do you generally see in a website instead
when you're waiting for an Ajax response?
Ben.
>> So you like [inaudible] like spin [inaudible].
>> Yeah. So you see some kind of spinning wheel
or progress bar or the like.
So we can actually do that.
Let me go ahead and open up, let's say, version 7 here.
And let me open that up in the browser as well.
And let's see what this version looks like.
It's deliberately hideous ,
but it's at least sexier than just text.
Now we have this.
[ Inaudible Conversations ]
It's pretty bad.
Give it five or so seconds.
Voila. All right.
So now let's try to reverse-engineer this, right?
We know how we can update text.
How do we go about displaying a sexy progress bar like that?
Yeah, Axle.
>> Is that a gif 5?
>> Maybe.
[ Laughter ]
>> It would have a gif.
I think it's the timex image still.
>> Okay. Image tag, sure.
>> And then you would do a hidden or a stylus way none,
and you would talk about it based on the statement.
>> Good. So that hideous blink example we did last week recall
was interesting not because it fixed the blink tag
but rather it was manipulating CSS.
And, really, here that's an option, right?
If I come up with the animation somehow,
and frankly the easiest way is indeed
with an animated gif, right?
There's not complexity there.
I just frankly downloaded that one off the Internet,
and we'll see a site where you can download all sorts
of these kinds of things.
It's just an animated gif which means it's a single gif file
that happens to be animated like this.
Well, that's perfect because all I need to do
to show progress is either turn that image on or turn it off.
In other words, show it or hide it.
And we can do showing and hiding via CSS.
Recall that we had the visibility property of CSS
where you can either show or hide something.
There's an alternative which is the display property
which actually behaves a little bit differently
as we'll see in just a moment.
So let me go ahead and see how this is actually implemented.
Let me go to the source code in Ajax 7.
Scroll down to the HTML.
And now notice -- what's the secret here?
In addition to having my form and my divs and so forth,
what do I also have in there apparently?
Yeah?
>> Well then a div has a style attribute
that says display none.
>> Exactly.
So I have a div here called progress whose display
for the moment is done - rather is none, and that just means
by default it's not going to appear on the screen.
So this is actually kind of an important detail
because you wouldn't want it to be there be default
and then use JavaScript to change display to none
because you could see the progress bar
for a split second before the JavaScript actually hides it.
So doing it this way ensures that it's not going
to be displayed at all, and I have some alt text there
and the source happens to be 19 dash zero dot gif
which is the name from the site that I downloaded it from.
And then the div for the quote is just
as simple as it was before.
No actual content, but it did replace the text area
that we used a couple of examples before.
So now what has to change?
I somehow need
to programmatically change the display property
of the progress div, but we saw how to do that last week.
If I scroll up here and go into my quote function,
notice that this time to show progress,
rather than update some elements in our HTML,
notice that I instead get the div called progress,
then I do dot style dot display.
Last week we did style dot visibility.
Here I do style dot display, and I change it to block which,
for some silly reason, is the opposite of none.
Block is the opposite of none; none is the opposite of block.
Although there are some other variance possible as well.
So what am I probably doing
in my handler function once the price comes back?
What do I need to do in my handler function?
Because otherwise I have this big, ugly,
red icon spinning around.
So how do I turn that off?
Well, Axle.
>> You set it to [inaudible].
>> Yeah. Just do the opposite.
So pretty much the same code but a different value.
I change the display back to none.
Now, just as with the blink tag, we could see the DOM changing
in real time thanks to Chrome's Developer Toolbar.
We can see the same here.
So let me open up the same example again.
Let me make the Developer Toolbar a little bigger.
Go to our elements tag.
Go in here.
And now notice here in the DOM it's display none.
Now let me go up here and quickly type in GOOG.
Get quote.
Now down here -- oops.
Down here notice that it's display block
and in just a couple of seconds back to none.
So the same behavior that we saw while playing
with the blink element.
Now we're just updating things a little more precisely.
So for those quite savvy with CSS,
why am I using display today and not visibility?
What's the difference, Axle?
>> Well, this is not going to do with [inaudible].
This is just a guess.
It feels like -- no, no, no.
>> Don't want to go there?
>> No.
>> All right.
So let me see if I can do it by example.
Let me go down to my actual HTML.
Oops. Let me go into this.
I'm going to change display none to visibility hidden,
and let me reload the page.
And, hopefully -- no progress bar.
Okay. So that's good.
No progress bar there.
But what do you notice is slightly different already?
>> It still takes up the space.
So that's the difference.
Whereas the visibility property in CSS hides something.
If you say it's a hidden, it still takes
up the exact same amount of space as it would
if it were not hidden.
So that might be fine.
And, in fact, sometimes that is the behavior you want.
You don't want your webpage moving up and down, up and down,
as will be the case here.
But I just decided that this looks atrocious.
So, instead, I decided it's going to be better
if things actually moved down in this particular case,
showing the image and then disappearing
when it's done showing progress.
Even better, frankly, would be
to use an image that's a lot more subtle, maybe small.
You align it with the text field instead
so that you see a progress bar, but nothing has to move.
But that's the key difference between display
and the visibility property of CSS.
All right.
So that's getting a little better.
As an aside, if you want to download this
in other fun progress bars,
a good silly website is ajaxload.info.
It's the only dot info site I know of on the Internet.
And you can choose some really hideous icons here.
They got that.
So this one's, you know, at least typical.
This is just strange [laughter].
So we look forward to very hideous project tools.
So that's the biggest one I could find here.
But notice, these are all just animated gifs.
So the fact that they appear
to be showing progress is really just an illusion, and it --
where the sort of spinney thing is, where the darker icon is,
it's totally a function of when you reveal it
and when you hide it.
It has nothing to do with starting at one point
and going to another point.
You can't stop the animation of the gif.
All you can do is hide it.
And there are a couple of more down here.
Yeah, so there's all sorts of crazy things.
And -- okay, that's kind of funny.
But then you can choose like your background color here.
So we could do -- let's see.
If I do this up here.
Okay [inaudible].
Okay, we did -- choose this guy.
And now generate it.
There it is.
Okay. That's all I wanted to do.
All right.
So there's your potential progress bar if you're familiar.
From the lack of laughter,
some of you don't even know what Pa-Man is.
That's kind of sad.
Oh, well. Game from yesteryear.
All right.
So, not bad.
But we can do a little differently here.
Let's take a look at this example now.
It's going to be a little more work.
But now let's notice how I've restructured the page.
Finally we're getting back
to the cliffhanger from before break.
So what am I obviously fundamentally doing here that's
different from all previous examples?
Louis?
>> By separating [inaudible] to zero spans?
>> Yeah, exactly.
So now I have three different spans,
each of which is semantically tagged with some keyword.
In this case, Price, Low, and High.
So that can uniquely identify these spans.
And so, finally, I'm starting to actualize my vision here
so that I can update a specific part of the DOM without having
to just plop in a huge bunch of text from the server.
So to do this, I'm going to need the server to return
to me some uniquely identifiable values.
And this far I've returned price,
colon and then some number.
I tried doing price, colon, some number, backslash n, then low,
and then high, and so forth.
Then I resorted to some br tags.
But we really need to clean this up.
So I can take the JSon approach,
and I can actually construct an array on the server
and I can spit out an array.
But an array is not necessarily the best representation
for these pieces of data.
Why? Why is a array with square brackets not necessarily the
best way of sending this data from server to browser?
Mm-hmm?
>> This is one thing you get
since it's a non-associative array you don't know
if it's the price low or high in the array.
You have to remember though the row numbers, but --
>> Yeah.
>> -- I think that it.
>> Okay. No.
That's a pretty reasonable criticism.
I mean, granted, there's not much data we're sending back,
and the array we did right before break whereby I sent back
a four-element array using square bracket notations,
so it's indeed a numerically indexed array.
You know, the burden is on me to remember
that bracket one is Price, bracket two is High or Low.
I already forgot which is High or Low.
So that's potentially a problem.
Moreover, if I ever change what the server's spitting
out then my client's side code is going to break.
And this is in stark contrast to XML, for instance,
whereby one of the design features of XML, recall,
was its extensibility whereby you should be able to spit
out a person's middle initial and their address,
additional XML elements, without breaking code
that expects first name and last name and other
such things to be there.
If you think way back to that purchase order example
for the Amazon book, we introduced more elements.
Same deal here.
If I suddenly introduce some field besides High, Low,
and Price, it would be nice
if it doesn't break existing implementations.
And, frankly, if I want to reorder Price, High,
and Low for whatever arbitrary reasons, it would be nice
if client code doesn't break as well.
So what's the alternative to a numerically-indexed array
that we could spit back that JavaScript could understand?
Axle.
>> Associative array?
>> Yeah. So an associative array.
And JavaScript doesn't technically have
associative arrays.
However, you can -- at the end
of the day they're pretty much functionally the same.
So what do we have to convert a PHP associative array
to in order for JavaScript to understand it?
JavaScript really has two data structures of interest,
at least right now -- the array and the other one
which is the fairly generic --
>> String.
>> String's good, but we needed some structure.
>> A variable bar?
>> A variable's just a variable, not a data structure.
Object.
>> You said [inaudible].
>> An object is right.
Okay. I was hoping someone would pluck that out.
So just an object, right?
Recall the curly brace notation.
An object in JavaScript is just an arbitrary collection
of key value pairs whereby you can have a word like Price colon
and then a number comma, high colon and a number comma,
low colon and a number.
In other words we can still send back three values
that we care about, but we can tag them with keywords,
literally keys in the object, so that I can directly access any
of them, and the order in the object does not matter.
So let's see how we might go about doing this.
Let me open up, in this case, quote5.php,
which is a slight enhancement of what we did earlier.
Ah. Okay, wait.
I told the story in the wrong order.
Let me go to -- here's 9.
Let me just double-check.
Aha, I've got that.
Ah, HI. Okay.
We will do a -- let's see.
If quote9, quote5, quote4.
Okay. So let's fix this.
We'll use quote4.php, which currently is spitting
out this mess which is comingling Price and High
and Low with some HTML.
So previously I used JSon in code.
So let's at least start there.
Let me go back up here and in quote4 let me go ahead
and do print and then json encode data,
because data's already an array.
Let me delete this mess here.
And now let me go back to my browser and open up appliance,
and then quote4.php question mark symbol equals GOOG.
Oops, sorry.
Let's do this again -- quote4.
Quote4.php question mark symbol equals GOOG enter.
Why is it waiting?
Okay, there we -- oh, stupid 5-second delay.
All right.
Okay, goodbye.
All right.
That's why it was so slow.
Okay. So this is where we left off before break.
Not bad, but we can do better.
So we somehow have to retain the keys here.
But we don't have keys yet so we're going
to have to do this ourselves.
So one way I could do this is as follows.
In my PHP code it's apparently not sufficient just
to JSon encode data because the data variable, recall,
is returned by f gets csv,
and recall that f gets csv just returns a
numerically-indexed array.
So we can't change that behavior besides changing PHP itself.
But we could do something like this.
We could say array -- let's say, let's call this objectget --
I don't want to conflate --
let's just say results get array.
And now I'm going to prepare an array with some key values.
In PHP I can do this as follows.
Price and then equal sign arrow data, which is price.
It's one. And now I need two other such fields -- whoops --
two other such fields.
So high and low 3 and 2.
So now I have a new array.
And what if I print out this results array?
So now notice I'm pretty much still just returning bracket 1,
bracket 2, bracket 3.
But I'm adding to it some keys so that
when this object is serialized it actually has those key value
pair associations.
So let me go back to my browser and reload
without the delay this time.
And voila, now we have this.
So it's a little verbose in that everything is quoted.
But that's what JSon encode is doing
for us just for safety's sake.
But this is a JavaScript object, right?
It might be written without much white space but there is a key
of Price and a value of 615.51.
There's a second key of High and a third key of low,
and each of these have their respective prices.
So why is this useful?
Because now it's going to be so much easier to actually dive in
and get individual values from this JSon data, all right?
So let's go ahead and take a look at one approach here.
Let me go back in here [inaudible].
Let me go ahead an open up Ajax10.html
which has this embodied.
I'm cheating slightly here.
Okay. So let's do this.
So this line of code here now is new.
At the very top we have the eval function.
In general, in most languages,
using the eval function bad tends to be the means
by which various programs are exploited.
For instance, I think WordPress, a popular blogging software,
has a habit of using eval all over the place which is one
of the primary reasons it gets hacked quite a bit.
Eval takes a string of code and executes it for you which means
if you can somehow trick the computer into evaling a string
that you, a bad guy, have inputted,
you can trick the server into executing any code you want.
However, for JSon, it's actually necessary in JavaScript.
And notice what we're doing here.
So in JSon when -- or rather, in JavaScript,
when you get back an xhr response text value that happens
to be JavaScript object notation.
In other words, the stuff we are spitting out at the moment.
You have to somehow convert that text
to an actual JavaScript object.
Unfortunately, there's no simple function of doing this,
so the way you do this is with the eval function.
So the eval function in this case is expecting a string.
And the fact that I'm putting
that string in-between parentheses means that I'm going
to converting this to an object, all right?
This is just -- I'm not going to be at risk
for executing a JavaScript function here in this case.
So by taking response text, prepending
and appending a parenthesis to both sides,
and then calling eval stores in the quote variable an object.
And how do you access keys in JavaScript objects?
If the object is called quote,
how do I get the price property of the quote object?
>> Quote and then a hard bracket and then price and harder.
>> Exactly.
So let me go back and do this.
Let me go in here and let's go into --
let's see, this is quote4.
That's good.
Let's go into Ajax9.html.
Let's see, quote4 not 9.
Where were we?
Seven. Not sevens.
Okay. So version 8 here.
So I want this connecting to quote5.xml.
Let's see.
[Inaudible] program.
So I want to connect to version 4, which I've just updated,
and I want to go ahead
and change the behavior here in Price.
So let me first temporarily delete some stuff here,
and let's do this.
Parse JSon.
So let me zoom in and I'm going to say var quote gets eval
of quote/unquote xhr.response text.
Okay. And now I need to insert Price, High, Low, into DOM.
How can I do this?
Well, I can do document.getElementById
of quote/unquote Price.
And then how do I update its contents?
Dot Value or?
Recall --
>> What is it?
What's the price?
Also --
>> It's a span.
>> Either in your HTML or text content [inaudible].
>> Okay. Good.
So let's go with enter HTML here.
Let me scroll down to where we were.
So here we have document dot get [inaudible] id.price.innerHTML
equals -- and then, as Axle proposed, quote bracket price.
So let's see if this actually works.
So this is version 8.
Let's go back to my browser.
Go over here.
Version 8.
It's Goog.
Get quote.
Whoo, it worked.
Okay. Why is High and Low not working?
>> You didn't code them.
>> Correct.
I didn't write it.
So, good. A little sanity check.
Copy, paste in help here,
at least with this particular example.
So let's now change this to High.
Let's change this to Low.
Let's change this to Low; this to High.
So now I'm updating at three different places,
and maybe we can do this with an array and somehow clean
up this code a little bit.
But for now, it's just three.
So that's not too unreasonable.
Let's reload.
Type in GOOG again.
Get quote.
And voila.
Now we have those three separate values.
And what more can we do here?
This is a little verbose.
In fact, I can simplify this,
and I don't strictly need the square bracket notation.
I can instead do just that which is even nicer syntax perhaps.
So the quote is an object.
Objects' properties can be accessed
with dot notation unless they have funky characters in them
like spaces and the like.
So, in this case, I'd argue this is a bit more readable.
And if I go back to Ajax 8, type in GOOG, get quote,
I get the exact same behavior as I did before.
So, much nicer, right?
So, this is JavaScript object notation
and it's the JSon behind Ajax these days.
And it's a very, very common data format
for exchanging information between systems because it's
so relatively simple to generate,
as we did with just a couple of lines of PHP code,
and it's also simple to parse
because all you do is the equivalent of this eval call,
and then you have right then and there a JavaScript object.
So, by contrast, let's actually take a quick look
at how you would have done this if you'd used the x in Ajax,
an XML-based approach.
So let me go back to these files here and let me open
up example 8 as it currently is and demonstrate the following.
So, in example 8, recall that we have these three spans
for Price, High, and Low.
And suppose that we instead use quote5.php to spit
out the following results.
Let me go up to quote5.php and hit enter.
And this is what I propose quote5.php should output.
It's using XML.
So what's the advantage here or what are some
of the advantages here, if any?
What do you like about this representation
of the exact same results?
Ben.
>> It's more obvious to the reader what's being shown.
>> Good. It's more obvious
to the reader what's being shown, right?
It's much more straightforward.
There's the Price; there's the High; there's the Low.
There's the symbol just as a reminder to myself, perhaps,
of what I searched for, and it's all very nice
and user-friendly in this sense.
But what's a downside here?
Yeah.
>> Well, you're sending a lot more data
since you have open tag [inaudible]
and then closed tag [inaudible] which is really not necessary --
>> Yeah.
>> -- so much as the [inaudible].
>> Good. So, it's just -- it's kind of unnecessarily verbose,
whereas the JSon version says the word Price once
and High once and Low once.
This time this version's literally saying those words
twice, and it's adding the Quote element,
and it's reminding you of the symbol GOOG.
And that is -- we could have still added the symbol GOOG
to the JSon data but it's just arguably unnecessary.
If you've requested GOOG, you're going to get back GOOG
in this case, so that's just wasting some space.
But it's not bad.
This is not a bad way of exchanging data.
It's a little verbose but, frankly, most browsers
and servers compress information
with a tool called gzip automatically.
And so this is not such a big deal,
the bandwidth savings here.
But what is, I think, more compelling
about the JSon approach is when you look
at how you implement the XML.
So let's look at here our handler function this time
for the XML-based version.
And here's how you can go about parsing XML.
And I tried to do this as pretty straightforwardly as I could.
So I'm getting the XML.
This time I'm getting response.xml instead
of responseText.
What was the key difference between responseText
and response.xml if the server's indeed spitting out XML?
>> Well, the responseText only gets the actual text that's
in the webpage.
The XML gets the actual XML structure, the --
>> Okay, good.
So whereas responseText literally contains text.
It might look like XML, but then it would be up to me to parse
that and figure out what's the open tag, what's the close tag,
what's the attribute, what's the value.
Response.xml is the result of taking responseText
and building a DOM out of it, building a tree out of it.
That's much nicer because now I can just navigate a tree
that someone else built for me.
The catch is that now they're getting DOM using DOM functions
as they're called is not the easiest task in the world.
Here, for instance, is how we could go
about updating the price.
First, I have to search through the XML looking
for the price elements.
I didn't have a unique identifier in this case.
I just had a price element which is kind
of the right way to do it in XML.
So I call a get elements by tag name.
We used that function last week for the blink example.
The catch here is, that returns an array.
So I have to have minimally a check
like if price is dot length equals equals 1,
that means I have a price element in this DOM.
If I now do have a price element in this DOM, what do I do?
Well, I first go into price is bracket zero.
So give me the zeroth price element in the array
that happens to be of size one,
because there's only one price element, hopefully.
Then I call first child.
Then I call node value.
Now why is this?
Well, if you look back at the XML,
how many children does the price element have in terms
of the hierarchy depicted here?
How many children does the price element have?
Isaac.
>> None.
>> That's, I think, a reasonable takeaway,
but it's not quite true.
>> Any -- the actual content
within it would be a child, right?
So, one.
>> It does have one child.
So the catch is, and if you think way back
to when we first looked at DOM
and we actually showed the white space characters backslash n,
backslash t, and so forth, the reality is in DOM
that there's more hierarchy
than you really see here with your eyes.
The quote element is the root.
The quote element has at least three children --
Price, High, and Low.
But the price element has a child.
The child happens to be of type text.
It's a text node so to speak.
But it is in fact a child.
So if we were to draw this tree you would have the quote
element, you would have a price element,
and you would have the text node as a child of the latter.
And that node, the text node itself has a value.
So when you actually translate that mental model
to actual code, the catch is
that you can't just get at the price element.
You have to get at the price element's first child --
it happens to be its only child -- dot node value.
That is how you actually get that text.
Then we can go about updating the inner HTML.
As for the rest of this file, it's pretty much identical.
The code is the same for Low, the same for High,
and one of the reasons that XML never quite became
as popular these days as JSon.
It's just way too many hoops to jump through, right?
It's so much easier to say price dot -- rather quote dot price,
quote dot high, quote dot low, and you're done.
There's none of this crazy DOM manipulation.
So it's a well-designed API in that everything's very clean
and there's a nice model for children and parents
and ancestors and so forth.
But it means you have to jump
through more hoops programmatically
to actually get at the data.
Plus it's more verbose.
So, in short, JSon has very much come into vogue
as really the preferred transport mechanism for Ajax
because it's just a little simpler all around.
Any questions on the XML or the JSon variants?
All right.
So let's take things a little further here.
Let me open up this example
and show really the true JavaScript way to do this.
So, for now, let's look first at the HTML.
Notice I have a symbol
and notice now I have a Submit button.
But what do I not have --
or what do I have now at the bottom?
A div id of quotes at the very bottom.
So somehow I want to put in my Price, or my High,
or my Low into that development as before.
So earlier I said that the inner HTML property work.
It's nice and simple but it's not really the right way
to do things.
If you really want to use JavaScript
to create new DOM nodes the right way you have to jump
through a few more hoops.
And those hoops look as follows.
Let me scroll up to my quote function,
and notice that this quote function is pretty much --
whoops, is pretty much the same as my very first version.
But I'm going to make a couple of changes here.
One, notice what I'm doing with onreadystatechange?
What am I doing this time that I didn't do in previous examples?
Axle?
>> Well, you have an anonymous function [inaudible] what
actually happens when you change the state is that I'm saying --
is that I'm calling function.
>> Yeah, exactly.
Rather than saying onreadystatechange equals
handler and then defining handler elsewhere,
this time I'm just assigning onreadystatechange
to an anonymous function, anonymous in the sense
that there's clearly no name for this function given.
I just say function open paren, close paren.
Now why is this a reasonable if not compelling thing to do?
Why make the handler function anonymous function as opposed
to giving it a name like handler?
[Inaudible].
>> Because you didn't want to --
you wanted to avoid calling handler
and you have to [inaudible].
>> Yeah. No, it's just cleaner design
because in all previous examples I have this function called
handler, but I'm never calling it directly.
In fact, all I'm doing is assigning its name as the value
of onreadystatechange.
And the only reason handler exists is so that guy,
the onreadystatechange property, can have a value.
So in this sense it's just better design arguably
to eliminate the name of the function altogether so, one,
you don't accidentally call it, and that's maybe unlikely.
But there's just no need to have an additional name like handler
if you can just assign it directly
to the property as follows.
And the white space I've put here is meaningless.
In fact, a very common paradigm is
to do this all in the same line.
So if I scroll back to this properties initialization doing
something like this is quite common as well,
where you just do that all on one line.
And then even sometimes putting the open curly brace, whoops,
the open curly brace on that line as well.
So scrolling down now, these are actual other DOM functions.
So if instead of just plugging stuff into inner HTML I want
to truly update the DOM.
And by that I mean create a new node for the Price.
Create a new child for the Price's value.
We have to do things as follows.
One, once I'm sure that readystate is 4
and status is 200, I'm going to go ahead and create a div,
literally create a div by way
of document.createElement quote/unquote div.
So what is this doing?
This is creating in memory one
of those rectangles we keep drawing as pictures,
and it's of type -- it's an element of type div,
but it's not in my Dom yet.
It just exists somewhere in RAM and I have access
to it via a variable called div.
So it's just creating one of those rectangles we keep drawing
in RAM, and it's a div.
One am I next doing?
I'm creating a text node whose value is apparently --
and let me go over -- scroll over to the right a bit more.
A little hackish at the moment, but the value
of this text node is going
to be symbol plus colon plus response text.
So it's just a concatenation of strings.
So we'll see what that looks like in just a moment.
But create text node takes an argument.
A text node doesn't have a name like an element has a name.
An example name for an element is div.
But text nodes are just text so they do have values.
So the argument
to a CreateTextNode function call is what value do you want
to give that text node.
All right.
So now what do I do in my third line?
Well, now I have a div in memory.
I also have a text node in memory.
I need to start creating some hierarchy so I'm going
to call div.appendchildtext.
So if this is my div element,
this is my text node, what am I doing?
How should I move my hands to represent this?
Axle?
>> Well, the text becomes a child of the div.
>> Exactly.
So we're taking two separate nodes which exist
as separate variables, separately in RAM right now,
a div and a text node, and I'm connecting them effectively
like this.
Now I have a tree of sorts, a tree with two nodes.
But where do I want to put this mini little tree
that I've just constructed?
I want to cram it into the actual DOM of the page.
So my last call there, document.getElementById,
of quotes -- that's the div that had nothing in it.
I call appendChild.
Now that div at the moment has no children.
Recall that it was open div.
ID equals quotes, close div.
There is nothing in-between it.
So what appendChild is doing here is it's cramming inside
of that open div tag and the close div tag this new div
that has a text element.
So let's see this in the browser
and then see this in the debugger.
Let's go to Ajax9 here.
Type in GOOG, enter.
And sure enough, I get this arbitrary string down here.
It's not elegant.
We've kind of taken a step backwards in terms
of formatting, but that's fine.
I just wanted to plug in some value there.
Let me now open up the inspector and go to the DOM view.
And let me scroll down to this guy here.
So notice that's what that looks like at the moment.
It has no children.
So if I go up here and submit this form and click Get Quote,
now notice what just appeared in the debugger here.
A little arrow which suggests now it does have children.
Open it up and there's the div we just created.
Axle.
>> Question.
If quotes is already in div, why would you need to append text
to a div instead of appending text directly to the quotes.
>> Good question.
Why do -- if quotes is already a div, why do I need
to put a div in a div?
Absolutely no reason at all.
I simply wanted my code example to create a mini hierarchy first
and then plug it in somewhere.
So to do that I just created a div placeholder.
I could have technically -- notice what the DOM looks like.
Let me zoom in on this.
Notice that technically if I really wanted
to be fancy I could omit that placeholder,
the div with an ID of quotes altogether.
And I could just remove this altogether,
and then I could just use --
in JavaScript I could get the body element
and then append a new child to the body
so that it would similarly end up all the way
at the bottom of the page.
All right.
So, if I somehow access document.body,
appended it to the body, it would end
up in the same location.
So if you think about now a chat client for Facebook or the like,
generally the chat messages show up at the bottom of the screen.
You get another [inaudible] at the bottom,
at the bottom, at the bottom.
This is exactly what's going on.
The Facebook JavaScript code is essentially adding
to whatever your little chat window looks
like to the very end of the document another node,
another node, another node, and that's what's putting all
of the various chats in the screen.
So if you are a Facebook user or a Google G-chat or anything
like that, you can actually watch this.
Like tonight, the next time you're chatting with someone,
or right now if you're chatting with someone in class, go ahead
and open up Chrome's Inspector or whatever browser you're using
and watch the DOM actually get updated everytime a friend sends
you an instant message.
You'll likely see that new spans or new divs
or new somethings are being added and added and added
to the DOM based on code quite like this.
So the biggest downside here, arguably,
is the fact that this is a lot of code to be writing, right?
In version 9 we've just kind
of made our lives even more difficult by having
to introduce all of these DOM functions.
So let's actually take a look at a slightly cleaner version.
Oh, as an aside, we did things out of order.
The JSon examples that we introduced a moment ago
when I was doing it on the fly,
there are canonical examples in Ajax 10 and 11.
So, if you want to actually see clean code versions
that we didn't do on the fly, in 10 and 11.
But in 12 I offer something that's even sexier.
So down here I again have some HTML that looks like this.
What's nice about this HTML is
that I have three separate placeholders
for Price, for High, and Low.
So this is, at least in design,
probably the best approach we've taken thus far.
The HTML is ugly.
It looks like a black and white window.
But at least we have deliberate placeholders for this text.
But now what's going to be different is my JavaScript.
All of that code we've been writing, the quote function,
the handler function, the try, the catch, all of that stuff,
I propose we can simplify down to this.
So this is an example of a library called JQuery.
You might have used this already for various projects,
but what this particular function is doing,
in this case the Ajax function, is simplifying a lot
of the stuff we just wrote and taking away all
of the common code, all of the try, the catch,
the Microsoft stuff, and just hiding that from you
so that you can focus really
on doing the interesting part of the coding.
So let's see if we can't tease apart what's going on here.
So in JQuery a very common paradigm is the dollar sign.
Does anyone know what the dollar sign is or represents?
So it's kind of -- whereas PHP,
the dollar sign has special meaning.
It's used at the beginning of variables.
In JavaScript the dollar sign is a perfect valid symbol
for a variable.
So it turns out in the JQuery library, which lives at URLs
like this -- code.JQuery.com or Google hosts it also,
and it's available for download, for free, elsewhere,
there exists an object called JQuery.
So there is essentially the equivalent of this,
of var JQuery gets this,
and someone has implemented the dot-dot-dot.
The JQuery object is a big library with lots
of functionality and the variable is typically
called JQuery.
All someone has done in the JQuery library is this --
var dollar sign gets JQuery,
thereby making an alias called dollar sign for JQuery.
So even though the dollar sign in JQuery code looks
like of syntactically new, it's just the word JQuery.
So it's as though you have --
let's see if I can do this properly
without breaking everything.
Do this. JQuery.
Okay. So this is really what we're doing.
There is a JQuery function that someone wrote that is --
that's the dot-dot-dot.
And you're just calling JQuery all over the place.
But the dollar sign, they just look sexier.
That's why.
Other libraries -- there's a JavaScript library called
underscore where all of the functions are prefixed
with an underscore character.
So they've laid claim to that one.
All right.
So what is going on here?
Well, in JQuery you have the ability
to wrap certain standard JavaScript objects
to give them more functionality.
So, for instance, dollar sign open paren document close paren
is clearly passing the document, global object,
into the JQuery function.
And what's that doing?
Well, it's returning to a special JQuery object
that has additional functionality.
We've seen some functionality
like document .getGetElementById,
document.getElement ByTagName, and so forth.
This is just returning to me a document object
with more functionality.
For instance, one piece
of functionality is apparently a new method called ready.
The ready method is an event handler that comes with JQuery
that allows you to specify a chunk of code
that should be called as soon as your DOM is ready.
In other words, as soon as your very big HTML page has been
loaded top to bottom, left to right,
and the entire thing has been parsed,
and your DOM is therefore ready.
Why is this relevant?
Well, recall that you can put script tags in the head
of what -- your webpage, right.
We're doing so here, in fact.
You can put script tags in the head of your webpage.
The problem is that HTML files are read top to bottom
which means when the browser encounters a script tag
and it mentions a JavaScript file or a JavaScript function,
it's going to execute right then and there.
However, in the head of your webpage what does not yet exist
in memory when the HTML file is being read top to bottom?
>> Well, the body.
So if you reference say an element with an id,
it's not going to exist yet.
>> Exactly, because webpages are read and parsed
and the Dom is built top to bottom,
if you execute JavaScript code in your head
and that JavaScript code assumes that your DOM has a body, well,
you've screwed up because at that point in time,
by nature of chronology, the body might not yet exist.
So you might try touching or changing
or accessing body elements -- divs, spans, whatever --
that haven't yet been constructed in memory.
So a very common paradigm when writing JavaScript code
in general, if you've embedded it in your webpage
in particular, is to do something like this.
Calling document.ready.
Then passing an anonymous function and then
in that anonymous function writing the code that you want
to execute once the whole DOM has been loaded.
So the alternative to this to be clear would be
to just dive right in and kind of blindly say like la-la-la,
let's start calling this code right now.
But this is bad because if this code assumes
that you have a DOM already for the body,
it might be an incorrect assumption.
So, in short, these two lines --
this first line specifies
when the document is ready, do the following.
Well, what do we do first?
Even if you don't know JQuery, what does the second line
of code here appear to be doing?
Dollar sign form.submitfunction.
What's this doing?
Yeah.
>> Well, it adds an event handler
for submit to the fourth.
And you showed us also the form
that you had deleted all the actions and all the on submit --
>> Good.
>> -- forms.
JQuery does that for you.
So when you submit the form you have another anonymous function.
>> Exactly.
So recall in every previous example we took the sort
of quick and dirty approach of having an on submit attribute
on my form and we said on submit equals quote/unquote the
quote function.
Quote, open paren, close paren, return false.
So that's fine.
It's clearly worked for all of these examples.
But it's kind of bad design because it would be better
if our HTML is our HTML, our markup.
And all of our programming logic is in a JavaScript file,
or at least separated from our data.
So, again, there's this principal
of separating your data from your logic,
your data from your logic and from your presentation.
Think back to NVC, is very similar in spirit there.
So this second line, where we say dollar sign form.submit.
This is a way of saying attach to the element in my HTML
that has an ID of form the following on submit handler.
So it's a way of adding after the fact
to your DOM even listeners to various HTML elements
without having to resort to the messier approach
of on submit equals quote/unquote
and then some JavaScript code.
This approach allows us to keep our HTML beautifully pristine
with no JavaScript code comingled.
It's just HTML markup.
Couldn't be more uninteresting.
But, nonetheless, because I've given this form an ID,
arbitrarily of form, it means
that I can access it programmatically up top here
by saying dollar sign quote/unquote hash form.
So those of you who are comfortable with CSS know
that this hash symbols is actually quite common.
The has symbol in front
of a word means give me the element whose ID is form.
In CSS, if you have a period,
that means give me the element whose class is foo,
if it's dot foo, and so forth.
So, the same idea there.
Okay. So what's happened?
To recap. Line one says when the document is ready,
do the following.
Line two says, when that form is submitted, do the following.
So anonymous functions are helping us express
that programmatically.
Do the following means call the following function.
It doesn't need a name because I just need it done once.
But call the following function.
Now this one syntactically is a little different,
but dollar sign dot Ajax is apparently doing what?
This is calling a method called Ajax on an object called what?
Dollar sign dot Ajax.
This is really just calling --
>> Well, the object is called nothing
because Ajax doesn't need an object.
That kind of just [inaudible].
>> Not quite.
So, again, remember this dollar sign is just a synonym.
It's really calling an object called JQueries Ajax method.
So if we think of it -- foo.
It doesn't matter what the object is called.
But this is, in fact, an object.
So one of the learning curve aspects of JQuery initially is
that it looks like we're introducing a whole new syntax
here -- dollar signs and dots and whatnot.
None of this is new.
It's just the JQuery folks thought it would look cool,
and it kind of does, to just say dollar sign everywhere instead
of a more verbose J-Q-U-E-R-Y, and so forth.
So this is just a method call.
Call a method called Ajax on the JQuery object.
or more loosely.
call the Ajax method in the JQuery library, passing in what?
What type of argument does the Ajax function apparently take?
Or rather, how many arguments does it take?
Yeah?
>> Three?
>> It apparently take three.
And what are they?
>> URL, data, and -- oh -- oh, yeah.
URL, data, and success.
>> Okay. Close.
To the technical response is not right,
but you're on the right track.
Jack.
>> One.
>> It takes one.
Why does the Ajax method take one argument?
>> It's taking one array
that includes the URL, data, and success.
>> Oh, so close.
Not taking an array.
It's taking an?
>> Object?
>> Okay. Yeah, it's an object.
So how do we know this?
Again, it's just an irrigation.
The fact that it's dollar sign dot Ajax open paren curly brace,
means here comes an object, that's all.
If it were square brackets that would mean here comes an array.
Now, we could call it an associative array
but JavaScript programmers just don't.
It's an object, even though in PHP it's functionally equivalent
to an associative array.
So now what are the keys in this object?
Can someone rattle off what the several keys are?
Axle, you had this answer before.
What are the three keys?
>> Yeah. URL, data, and success.
>> Exactly.
Now --
>> [Inaudible] is not a key because it's been in data.
>> Exactly.
In fact, this -- I just pretty printed this.
It's very common to write JSon code in this way where you ever
so slightly indent and you put your curly braces
on different lines like this.
But I could clean this up just
to make it a little more readable.
Now it's perhaps more clear that the object that's being passed
to the Ajax method contains, indeed, three keys.
So the first is URL.
You can probably guess what this does.
Open an Ajax request to this URL.
What's the next one?
Data. So, data is a way of sending key value pairs.
So with the JQuery library,
rather than take the somewhat hackish approach
of doing the question mark and then symbol equals --
that felt a little unclean.
You can, instead, make it lot cleaner in the following way.
Data is literally the HTTP parameters
that you want to pass in.
Data itself is an object.
The key value pairs are going
to be the HTTP key value pairs that you pass in.
Foo equals bar; baz equals crux, and so forth.
Or, in this case, symbol equals -- now this string.
So this is slightly new syntax.
But just because we're using this library, so symbol is going
to be the name of the parameter that we pass in.
So that's right here.
Dollar sign quote/unquote hash symbol.
Can someone translate this part to English?
What is this doing here?
Isaac.
>> Well, you're getting the idea of symbol.
>> Good. Getting the idea of symbol.
>> And then you're finding its value.
>> Okay, good, so.
Or more specifically get the element whose idea is symbol,
and specifically get its value.
So notice what we don't have to care about here is,
is it an input element, where is it in the DOM?
So dollar sign paren quote/unquote hash symbol is the
equivalent of document.getElementById.
It's just a lot more concise to express.
So that's all.
It's identical functionally.
Dot val is equivalent to dot value.
So, arguably, this is not really a savings,
but at least it's a function that allows us
to generalize away from hard-coded properties.
So now, thirdly, success.
What do you think success is here?
What does it represent?
It's the third key in this object.
>> Maybe a state four.
And --
>> State four, yeah.
That's -- actually that's it.
So it represents a function that should be called
when ready state is four, and one other detail.
>> Oh, 200.
>> And status is 200.
So, remember the if conditions we previously had
manually hardcoded?
If ready state equals equals four, and state equals equals -
rather status equals equals 200, success is a property inside
of this object whose value is apparently of what data type?
What's the value of the success key?
String, int, float.
>> It could be int.
>> What's that?
>> It could be int.
>> Not int here.
So notice we have three keys here -- URL, data, success.
The value of URL is a string.
The value of data is an object as implied by the curly braces.
So the value of success is?
>> A function?
>> It's a function.
So, again, we have a use for an anonymous function here.
A slightly new feature here.
Anonymous functions can take arguments even though I think
up until now we've not seen an anonymous function
that takes arguments.
But, totally legitimate.
The only thing you sacrifice
with an anonymous function is its name.
That's it.
So what is success?
Success is a key whose value is the function
that should be called when the Ajax request is successful.
So this is similar in spirit to our on ready state change.
But it's more specifically the function that should get called
when ready state, as Axle says, is four and status is 200.
So what code should I execute?
Well, when my Ajax request is successful,
I want to call dollar sign quote/unquote hash price.
Isaac, what does it mean to say that, the hash price code?
>> Well, it's looking for an element whose ID is price.
>> Perfect.
Looking for an element whose ID is price.
Dot HTML is pretty much equivalent to dot inner HTML.
But this is a function call.
The upside of calling the HTML function is --
recall our brief discussion s thus far
of security and escaping.
Remember PHP has HTML special chars and all of that.
Here the HTML function will handle
that kind of mess for you.
If it's got open-angle brackets or ampersands and the like,
the HTML function will take care of that messiness
for you, which is nice.
So rather than do it manually with dot inner HTML,
this function call is a little cleaner.
So data.price?
Well, data is apparently similar to what in our manual examples?
Yeah.
>> It's probably the array that JQuery parsed automatically
for you with a JSon that it received.
>> Exactly.
So, recall that in our sort of homemade examples,
there was xhr.responsetext.
But if that was JSon, we first had to pass that to a val
in order to get back an actual object in memory.
Data, the argument that's passed
to the success handler function is already the in-memory
structure that was returned by the server.
So JQuery handles for you all
of the stuff involving the eval function,
the response text function.
You never have to touch that again.
You are just handed on a platter, so to speak,
data which -- or you can call it fubar bad.
It doesn't matter what you call the argument,
but you're handed an argument that contains all
of the data from the server.
And at this point we can say data.price, data.high,
data.low so long as the server is indeed returning JSon data.
It turns out you can have many other keys.
In fact, if we look up the documentation
for JQuery's Ajax function,
you'll see a little something like this.
Let me pull up a browser and go to JQuery Ajax.
This is representative of JQuery's manual.
It's somewhat easy to read.
Not quite as straightforward as PHP's, but you'll see here
that Ajax, the function, could be called
in a couple of different ways.
And notice they're being explicit.
JQuery.ajax, JQuery.ajax,
they're not even using the dollar sign
in their documentation.
That's just a common convention.
So notice Settings is a set of key value pairs
that configure the Ajax request, and it turns
out there's a huge number of keys --
accepts, Async, before send, cache, complete, contents,
content type, context.
So I've really just plucked out the useful ones
and among those are -- let's scroll down to the bottom --
URL, so we've used that one.
What was another key that we passed in?
Success. So there's this one here.
And, in fact, notice that the success handler can actually
take in three arguments.
I've left two of them off.
I've only used the data one.
But you can actually get back even more details
about the Ajax request if you want, by including a second
and third argument called text status and JQ XHR,
or really whatever you want.
But data was the one of interest.
And what was the last field?
The last key?
It was URL, success, and --
>> Data.
>> -- data.
Exactly. So if I scroll up in the documentation to data,
data to be sent to the server.
So it handles the process of converting your object
to foo equals bar ampersand; baz equals quarks ampersand.
All of that gets take care of for you.
So, in short, JQuery thankfully has kind
of become the de facto library of choice
for JavaScript programmers, among some others.
But most people these days, daresay, think of JQuery
as JavaScript because it just simplifies a whole lot.
Now at the same time, we went through the exercise
of these various examples so that you see what's going
on underneath the hood.
You understand how Ajax is working from the ground up.
But, in reality, I would strongly encourage you,
when it comes time for Project Two
which we'll discuss briefly tonight, to take the approach
of using JQuery or some similar library
so that you're not writing 40 lines of code like we had been.
You can instead do it in just 10 or so lines of code.
And it's a lot more readable arguably
when there aren't the distractions of all
of the error checking we ourselves implemented again
and again and again.
So using something like JQuery is totally fine for Project Two.
Why do you think this function is returning false
at the very end?
Why is my anonymous function returning false?
Ben?
>> I think earlier [inaudible] we had, you know,
return function that had -- most of them actually [inaudible].
>> Exactly.
Yeah. So we still want
to short-circuit the form submission
after the user has clicked the button.
So this return false, if you kind of line
up all the parentheses, actually is the last line in which
of my anonymous functions here?
>> The submit.
>> The submit handler.
So if you kind of line up the indentation,
that return false lines up with the anonymous function
that I'm passing to the submit handler.
And the fact that I'm returning false means do not submit this
form ever because I just hijacked its functionality
and implemented it myself using Ajax.
So in the end, this example does the exact same thing.
And the only thing you have to do in order to have access
to this kind of syntax and functionality is including a URL
like this one to get the latest version in this case of JQuery.
So wonderfully useful even though there is a bit
of a learning curve.
But realize again that even though this looks like sort
of a new language that we've just started using today,
it's syntactically a little different,
but only because we're taking advantage of some tricks
like using a dollar sign as the variable name
which is totally legitimate,
and calling JQuery specific functions.
Quite handy ultimately.
Any questions on Ajax itself or JQuery syntax or functionality?
All right.
So where does that leave us?
so there's one thing that's worthy of note here
when it comes to the return types from the server.
So we've done a few different return types.
We've spit out just text in some
of our earliest examples involving the stock prices.
We've spit out some HTML.
Recall when I inserted those br tags into the output.
We spit out XML certainly.
And we also spit out some JSon ultimately.
So it turns out there's this feature of web servers whereby,
when it returns a file,
it includes a header called content hyphen type.
So we've seen other HTTP headers like location colon,
set cookie colon, and so forth.
Well, the set content header actually specifies what data
type is this file?
And this doesn't always matter,
but realize that everytime we have pulled up a website
that uses Ajax and it's making subsequent HTTP requests,
you should generally ensure that your web server is spitting
out the right content type.
In other words, if you're spitting out HTML,
that's actually the default in PHP.
A PHP file always spits
out a content-type header of Text slash HTML.
However, if you want to spit out XML,
you need to manually override that.
So let me actually go into my example here earlier
where in my example I had in quote 5 --
recall when we spit this out?
Price elements, High elements, low elements and so forth?
And then we had a Quote element up top.
Notice one thing I did up top
with the header is I used the PHP's header function
to send a header of content-type colon text xml.
So why is that useful?
We'll open this in a browser here, and this quote5.php.
Let me open this again.
And, first, let me remove this header.
So let me comment out that line of code and reload here.
So, if you don't specify a MIME type that's correct,
if you don't specify text XML, this is what I see
when I download this XML file.
Now this is clearly like weird-looking, right?
This is actually three prices
but it doesn't look that way to me.
But if I view the source of this page --
let me go up and open up, let's say, view source.
There is XML in there.
So it is XML, but the browser doesn't show it as XML because,
if I open up the developer toolbar -- let's do that now.
Tools, developer tools, network tab, reload.
Now let me get the response here and look at the headers.
What content-type was sent back from the server in this case?
Yeah. Oh, Ben.
>> HTML?
>> Yeah, so text HTML.
And, again, that's the default.
All these weeks, when you've been writing PHP code,
you've never once had to spit out a content-type header
because the default in PHP is HTML
which is generally perfect for a PHP file.
But in this case, if we actually want to spit out XML,
you need to tell the browser as much.
Now the reality is this is not a big deal.
I am a human.
I don't really care about this XML.
But the fact that adding this header changes the browser's
interpretation of it can be important because you'll find
that certain libraries,
especially ones involving Ajax --
if they are expecting JSon to come from the server
and the server's response does not contain the right MIME type,
it might not parse correctly.
And, in fact, this was necessary here for my XML example
because recall that we used XH.responseXML and recall
that that was a property
that hands you a DOM that's already been preparsed
and loaded into memory as a tree.
If I had not included that text SML header,
the browser would not have known it is even XML.
It might look like XML,
but it wasn't told explicitly that it's XML.
So response XML might not have been accessible to me.
I couldn't actually navigate that DOM.
So MIME types, as they're called, these content types,
are generally important.
And the one that you would typically use for JSon data is
to spit out a header of Application slash JSon.
Or Text slash JavaScript generally works.
But the right one is Applications slash JSon,
and you can spit it out with code just
like the header function call we had a moment ago.
So, as for JSon itself, this is meant
to be a deliberately unreadable list.
JSon support is huge.
So this is a list from JSon.org, one of the evangelist sites
for this mechanism called JSon.
Support for it exists in all sorts of libraries.
IOS for mobile IOS development,
and it finally has good JSon support.
Android and, in this case, OCaml, matlab, C Sharp,
C-Plus Plus, C and the like, as well as JavaScript PHP,
Python, Ruby, and the like.
All of your favorite languages these days have really good
support either built in or through libraries for JSon.
So it's become a de factor standard
for exchanging information between browsers and servers.
In PHP, we saw a couple of things here.
In PHP, we have a JSon encode function.
It turns out you can actually go the other way.
There is a JSon decode function sot
that even a PHP script could retrieve JSon data
from a server.
For instance, if Yahoo made their data available
in JSon format instead of CSC, PHP could parse that as well.
Eval, of course, is the function we looked at in JavaScript
that takes a string that happens to be JSon
and actually parses it and loads it into memory as an object.
So there's a key takeaway though, here, to keep in mind.
In all of our examples involving those stock prices,
realize that we had a proxy of sorts in play.
My JavaScript code talked to Quote1.php or Quote2.php.
And each of, excuse me, those files in turn talked
to download.yahoo.com.
Then the response came back to my PHP file.
Then my PHP file responded to the browser.
It feels like this is an unnecessary middleman.
Why not just have my browser
in my JavaScript code make an Ajax request directly to Yahoo
and get that CSV file?
>> I don't know if this is correct.
But I've tried that actually for the project.
And it turned out that they didn't allow --
especially with Yahoo --
they don't allow users to get their JSon as JSon [inaudible].
>> True. Yahoo does not allow you to get their CSV as JSon.
But suppose I was willing in JavaScript to parse CSV,
which isn't that hard.
A little annoying, but not hard.
I still could not make that request.
So it turns out that browsers are governed
by something called the Same Origin Policy whereby you are
generally not allowed in JavaScript to load content
from another domain name into the current DOM of the webpage.
In other words, it's find if I want to fetch content
from JavaScript from Quote1.php
because on what server does Quote1.php live?
>> Yours.
>> Mine, right.
Same origin.
It's in my appliance, my web server, same origin.
However, if I wrote JavaScript code to make an Ajax request
to Yahoo.com, I could get the response
but I could not do anything with it.
I could not embed it into my existing DOM
because that violates this constraint known
as the Same Origin Policy.
This is generally a good thing
because it means you can't accidentally be tricked
into like doing a denial of service attack
on someone else's server
and integrating data you're not supposed to in the current DOM.
But it's also kind of a headache for reasons like this.
I now need a whole frikking web server plus PHP support just
to implement my Quote1.php, which is like 10 lines of code
to talk to Yahoo as a proxy.
So it turns out there's ways around this.
One, the web server like Yahoo can support something called
CORS, C-O-R-S, which essentially means their web server spits
out some HTTP headers that says it's okay if you want
to integrate our data into your DOM.
So that's one thing.
But not many web servers support that, Yahoo among them.
Or you can use something like YQL, well, Yahoo Query Language,
which is actually a neat service that you can Google,
if of interest, that acts as a proxy server for you.
It will fetch CSV, for instance, from Yahoo.
And it will even convert it for you
to something like JSon or XML.
So, YQL, Yahoo Query Language,
is a nice third-party free service that can help with this.
But, in general, this is not something that's possible.
Hence, our PHP examples.
So we already looked at a couple of progress bars.
We looked at the Ajax function.
So, lastly, Project Two.
So in Project Two you'll have the opportunity
to implement a mash-up of sorts,
whereby you take your new-found JavaScript skills
and build a dynamic website, largely in JavaScript and HTML
and CSS that allows users to navigate the map
and the schedule of the BART.
This is the subway system and train system of San Francisco.
So it's very big.
It's a very well-known public transit system.
And what's really nice about San Francisco is that they make all
of their data available via various
machine-readable formats.
So you'll see in the PDF of Project Two,
which is already online, that you have the ability
to download, for instance a zip file containing all
of their various schedules and routes,
or you can access an RSS feed, an XML feed,
and access real time arrival and departure information.
In short, you can access via various text files and URLs all
of the data that you need to build your own system
for navigating a transit system like the BART.
And so what you'll do in this project is use Google Maps,
version 3 of their API, which will allow you
to embed a Google Map in your own website.
You'll use Google's JavaScript API to draw lines on your map
that represent the various routes
for the various train lines.
So you'll get nice pretty lines drawn literally on top
of a San Francisco map.
And you'll enable a user to click around and see
when is the next train arriving at this location?
And where can I get go from this location to another?
So you'll see ultimately this is an opportunity
to synthesize some of the ideas that we've played
with with Project Zero, Project One, getting XML and/or CSV data
from some third party source,
building your own interactive websites
that uses now JavaScript syntax and Ajax functionality
to get more and more data from the server as needed
to report things like the next train schedule or the GPS
of the coordinates
of the various pieces of the train line.
So that will be one of the topics
that Elan [assumed spelling] covers in tonight's walkthrough
in section of Project Two.
But you'll find that this is, hopefully, a nice culmination
that moves away from MySQL,
so there's no MySQL component to this.
There's not necessarily a PHP aspect
but it will be an opportunity to really dabble client-side
with some dynamic code in Ajax.
Any questions about what awaits or where we've been?
All right.
So there's not that much ahead.
We'll focus in the remaining lectures of the class
on scalability, on security, trying to tie together some
of the ideas and the teasers we've had
over the past few weeks on what you should do,
what you shouldn't do, and also thinking
about how you can scale your website from just you
on a laptop or you on a desktop computer to you for hundreds
of people or for thousands of people, and the kinds
of design decisions you might want to make
for your next real-world project so that you don't paint yourself
into a corner with an amazing website that supports 100 people
when you could really, with some smarter decision-making
up front, make it support 1000 or 10,000 right out of the gate.
So why don't we call it a night here.
I'll stick around for one-on-one questions.
And Elan will be up shortly with Project Two in Ajax.