[ 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. 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. 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.