Transcript — Jenny Donnelly: “Hacking with YUI”
Jenny Donnelly: "Hacking with YUI" @ Yahoo! Video
Transcript:
Hi everybody, welcome to Hacking with YUI. I’m Jenny Donnelly, and I’m an engineer on the YUI team, and today I want to give you a whirlwind tour of the YUI Library, and give you some ideas of how to use YUI for your hacks, or your rapid prototyping, and leave you with some sample code that you can actually copy and paste right into your page to get started really fast as well.
So let’s just get started. The approach I’m going to take today is to break down YUI into different ways that you might want work with it for your hacks. The YUI library itself is actually a pretty comprehensive framework of utilities and widgets, that’s meant to help you guys, the developers, build rich, interactive web applications. And the way you do that, you can think of it as four different building blocks — to send and receive data; to build actual user interfaces on your page; to display data in a meaningful and interactive way; and to edit data in a roundtrip fashion, from the end user back to your server.
So to start, we’ll talk about how you might use YUI to send and receive data. The Connection Manager’s kind of a flagship utility that enables in-page Ajax types of data transactions, using the XMLHttpRequest. The great thing about that, of course, is you no longer have to take your user off of a web page to send and receive your data, and it enables a really rich, interactive transaction model, where you have a full application on a web page, and your user can interact with your server application without actually leaving that page.
Now, the Get Utility will dynamically load script nodes onto a page, and also will pull CSS resources as well. And it can do this at runtime, again, without having the end user leave your webpage. You can now go and get these resources at runtime. And the nice thing about the Get Utility is that it kind of bypasses the built-in browser security restrictions, so now you can actually go get resources from third party or external URLs that are not on your domain. So keep that in mind.
And the Data Source Utility is a layer that sits on top of the Connection Manager, or the Get Utility, and it is a value added feature set that can enable caching and pulling of your data requests. And it also provides a widget normalization layer, so you can use the data source to interact with widgets like AutoComplete, DataTable, and Charts, to go and fetch data from a known place, and have all of those widgets interact with a single data source, so maybe share a cache, for instance.
So here’s the YQL console —I don’t know if you guys have had a chance to check it out yet, but this makes it so easy, now, to go and access data, and all kinds of data, from the Yahoo! Network, as well as off the network now, as well. But what I’ve done here is just to give you a sense of how quick and easy it is to go ahead and access this data now. So in that first box, what I’ve done is set up a SQL-like query to go and get some data —this is getting a forecast from the weather feed for a particular zip code. And notice that I can choose to format that data as XML, or JSON, so I’m just going to stick with JSON. And notice that callback function —it’s called “cdFunc” —and that’s the default that you can use, that the console gives me. Keep your eye on that later —that’s the hook through which we’re now going to access the data on our page.
So I’ve set up my query, and this is the data that I’m going to go look for. It’s really easy that you can browse all the different tables of data that YQL has to offer. And up in the top right, there, those are actually pre-canned queries to give you a sense of different types of queries that you can perform now. But the real no-brainer part happens in the rest query, the URL there. That’s the part of the console where you can just copy and paste that part of the URL now, and go and get that data and work with it on your web page. So the idea is, you click the copy URL button, and now you can paste it right into a call to the Get Utilities. So we’re going to call this static method Script and just paste that URL right in there. So now what the Get Utilities going to do is dynamically load a script node pointing to that data —and all we have to do, as developers, is define this callback function. And so you can call that function whatever you want —you can go back to the console and re-name it, if you want, but this is the default so we’ll just go with that for now. So the idea is you can define that function to work with that data payload however you want, and that data payload is passed to you as the O argument there.
So going back to the console, I can see the TreeView version of the data —this is the live data snapshot of what’s going to come back to me —and I can drill down and figure out what parts of the data that I want to use, and figure out how to locate that in my JSON now. So you can see there is an item node, and under there there’s are links, or descriptions —so we can pull out different pieces of data that we want to work with, and given that kind of TreeView structure we can now drill down into the JSON and actually start working with it.
So now I’m going to define the callback function, and drill down into the O —Object. The first thing I do is just a quick sanity check to make sure the data is formatted in the way that I’m expecting—if not, you might want to have some sort of exception case to throw a data error message, or something like that. But so if it passes that sniff test, I can go ahead and drill down into “query.results.channel”—different data tables will have different formats of course—and output that data into a DIV live at runtime on the page. So I’ll just populate the innerHTML of the DIV, and call “data.description” and “data.item.description”—these are little pieces of the weather data feed now, that’s going to come back for my URL that I’ve put in. And all of a sudden you’ve got this really real-time weather forecast module on your page.
And that’s how easy it is, with the Get Utility, to make that cross domain request now, and work with that data on your page. YQL makes that super easy now—you don’t even have to dig around for the data in random places, it’s all in one place. The nice thing, also, of course with YQL, is that you can access the data super easily, but also pull it together—different data tables—and manipulate them within that console. And it’ll spit out that rack URL for you to populate the Get Scripts method.
So now I’m going to dive into how you can use YUI to help build user interfaces. We’ve got a whole bunch of widgets that will help make displaying data beautiful and elegant for you, but let’s start with the CSS foundation. I’m not really a CSS expert, so I rely on these pieces a lot, actually, to shortcut me into having a beautiful page with very little effort on my part. Reset CSS will remove the unpredictable CSS that a browser has built in, to help you out. The problem is, of course, that each browser has kind of tackled the problem a different way. So what Reset will do is level the playing field, and just remove all built in browser styles, to give you a clean slate to work from. And then on top of that, you can add Base, which puts back some intuitive styles, to help make list items have bullets, or headings have bold font—things that you would expect for your application. But it does it in a cross browser compatible kind of way.
And then Fonts CSS will implement a relatively sized font system, which is great so that users can stay in control of their font dimensions, they can zoom their fonts bigger or smaller depending on their needs. When you have a pixel based font system, you take that ability away from the user—so to implement something like Fonts actually makes certain that you preserve that functionality for the end user, while giving a certain default look and feel. And these are UED approved styles, so by default a P-tag will implement Arial font at the UED specified size, as well. So it’s just a nice shortcut to throw that in there, and you’ll have a nice font system to work from and build on top of.
So now Grids is a little bit more robust system, to give you multi-column layouts. And the Grids system itself is actually very robust; it’s got thousands of templates that you can choose from. And so this is for when you’re laying out a bunch of content on a page—you’ll want to hook into the Grids system to do that in a way that’s source code independent, and CSS based, so that you can keep your markup semantic and clean, but then use CSS to start moving the modules of content around in a beautiful layout.
But all the widgets that come with the YUI library have a pre-packaged look and feel called Sam Skin—and so that’s kind of like the baseline way to enable a really nice looking UI for all of our widgets, is just to class the DOM elements with “yui-skin-sam”. So when you’re hacking away, or doing a rapid prototype, a good rule of thumb is just to stick that class in the body tag, and that way all the widgets you pull into your page will automatically have that look and feel. Now, of course, the way we’ve built it, you can customize specific styles, and add your own enhancements to that Sam Skin—or you can decide to come up with your own skin altogether. But it’s a really fast and easy way to get an elegant polish to your page, without a whole lot of work—so it’s definitely a good way to shortcut yourself and bootstrap in a good look and feel. So that’s the CSS foundation.
Let’s move on to actually diving in to some code, with our widgets. So I’m going to start off with a dialog, and a dialog is such a quick and easy way to show a message to your end user—I just wanted to run through a couple of lines of code to show you how quick and easy it is to get started with that. Now this is a syntax that you’ll see again and again with our library. We’re going to create a new simple dialog on our page by calling the constructor, and we’re going to pass it the ID of a DOM element—and that’s where the dialog is going to get created. So that’s a DOM element that you supply in the markup, and then you pass in that string into the constructor. The next thing we do is just pass in a couple of configurations to tell the dialog how we want it to behave. And the first one is “fixedcenter”—this tells the dialog we want it to stay centred in the V-port. Now we’ll define a couple buttons for the dialogue, and so some standard buttons you might find are “OK” and “Cancel”, but you can see here that you can actually customize that text to be whatever you want.
And then we’ll define a “handler”. This is the function that will execute when that button is clicked. So you’ll see that paradigm a lot in the library, as well—we have a lot of event driven widgets, so there’s a lot of opportunities for you guys to define functions that service handlers. So in this case, when that button is clicked, your function will run—it’s very simple here, it just hides itself. But you might want to hook in to that to built some more complex functionality. And then we define another button in the same way, but that one we’re going to set as the default—so that means that when the button is shown, the user can click the “enter” button, and that’s the button that will be enabled by default.
So we’re going to customize a couple more things. We can set the header, and that’s going to be displayed in the title bar at the top of the dialogue. And then we can set the actual message, by calling “setbody”—notice here we’ve got HTML, so this is the string of markup that’s going to be rendered into innerHTML, so you can put anything you want in there that would be valid markup, like a form, or a list element. And then the last thing to do is to call “render”, and this is what causes the dialog to get populated in the DOM, and it’ll get painted to the screen at that time. So with these lines of code, what you end up with is this dialog, and you can see here that it’s got a little bit of a look and feel to it; that’s the default Sam Skin that I was talking about earlier. And all of the code that we’re going to run through today is also going to be made available to you, so you can copy and paste that code and use it, later on your own stuff.
So now let’s take that dialog and tweak it a little bit. We can turn it into a modal dialog, which means that we’re going to show a mask underneath the dialog. And let’s also make it so that we don’t have any buttons, there’s no user interaction with the dialog; we’re going to determine programmatically when to show it, and when to hide it. So that means that we can start with the code from the last dialog, and set “modal” to true—that’s going to draw a mask under the dialog which prevents the user from interacting with anything else on the page. Setting “close” to false will remove that close button—so we’re going to take that away from the user. And we’re going to start with “visible: false”, which means that by default, when we create the widget, it’s not going to be shown to the user; we’re going to decide when to show it, and we’re going to decide when to hide it. So now we’re going to set a different message in this particular dialog—we’re not going to bother setting the title. And when we render it, it gets appended to the DOM, but remember “visible” is false, so it’s still not shown to the end user. So we’re going to have to call my document “myDlg.show” to actually show this dialog—and then whenever we’re ready, we can call “myDlg.hide”. And for this simple example, I’m just going to show it right away, and then I have a simple set time-up that hides it after three seconds—but for your real world example, you might want to show the dialog when you’re about to load some data, and then maybe hide it when that data finishes loading. And in that way, you can have something that gives the user some visual feedback of what’s going on, so that they’re not left hanging. So that’s what that dialog looks like. Fundamentally, it’s built off of the same widget, but you can see that we’ve removed the buttons and removed the title bar as well.
So TabView is another way of organizing your content on a page. It’s a really nice way of displaying content without taking up a whole lot of real estate. And so each tab might show a different version of the content, or different content altogether. This is highly interactive in that it’s built off of our Custom Event model, so you can define functions that will execute when the user clicks the different tabs. So you can respond to the user interacting with your page. Now one very good idea to take advantage of that feature, would be to load the content when the user clicks the tab, so that your initial page load isn’t quite so heavy. When you have the initial tab content loaded, you don’t have to bother with loading content for the hidden tabs, and just wait until the user clicks that tab to go ahead and load that content. So that’s one thing to keep in mind, is different ways you can reduce your initial page load, and bring data in at runtime as it’s needed.
The other thing about a widget like this, is we take two different approaches in terms of insantiation. It’s called ‘from markup’, or ‘from Javascript’ scripts, you’ll see it a lot in our examples. And so the ‘from markup’ approach is otherwise known as progressive enhancement—you start with semantically correct markup on the page, that is pretty bare-boned, nothing super fancy, no Javascript for instance, no Ajax calls. It’s plain Jane, but it’s accessible, and it’s available for users who don’t have Javascript, who might be on an older browser, scenarios like that. And then you feed the widget that markup in the constructor, and it builts functionality on top of that bare-bones markup, which is to say that it layers in functionality progressively. So ultimately, for users who don’t have a very functional browser, or Javascript enabled on their browser, they still have access to all the content that you want them to see, without the fancy interactive widgety enhancements. So that’s one thing to keep in mind. The other approach, of course, is ‘from script’, which is to say nothing will work for your end users if they have Javascript disabled. But in a rapid prototyping environment, this might be exactly what you want to do, just to get up and running quickly.
So just to give you a sense of how to get a TabView on your page, we’ll just take a look at some code for that. And we’ve got a similar constructor here, we’re calling “Yahoo.widget.TabView” with the new keyword, and we’re going to programmatically add the content to that instance. So we’ll call “addTab”. And we’re going to feed… each of those tabs are going to be new instances that we give to our TabView—so you’ll see again, the call to new “Yahoo.widget.Tab”. And we can, using Javascript, give all the information that it needs to get a TabView up and running—which is to say, we’re going to give it the label, which is the text that’s going to display on the tab itself, and then we’re going to feed it the content, which is a string of markup. Like we’ve seen before, you can feed it a form, or a list item—an unordered list of items, for instance—to just feed it the information that it needs to instantiate quickly on the page. And in this case, we’re going to set that first tab “active: true”, which means when the widget loads, that’s the one that’s going to be activated. And we can just go and keep adding tabs until we have all the things that we need. And then for TabView we’re going to call the function “appendTo”, and that’s the function that’s going to now paint the DOM with our content. So, any questions so far? I’m just going to give you a sense of all the different types of paradigms that we’re using across our library, to get up and running. So the code for that example will actually output in a TabView that looks like that.
Menus are also a very helpful way of organizing content. You can see here, we’ve got a menu at the top there, that serves as a navigational structure for your website. But you can also instantiate a subclass of menu that will look more like an application on a desktop. And in the green box there, we’ve actually got a context menu subclass, so that you can right click and have a set of options appear. And Menu also supports nested and hierarchical data—and the nice thing that we’ve done for you, so that you don’t have to reinvent the wheel, is to figure out all the details around how users really interact with menus, the timings, and when to hide a menu when the user’s done with it, and to cut the corner there, we’re not going to hide the menu, we’re going to give it a little bit of affordance, just in case the mouse has left the box unintentionally. And all these menus are, of course, keyboard navigable, and screen reader accessible—so these are the things that are built in for you, so you don’t have to figure out how to do it yourself.
The Layout Manager is actually a pretty robust widget that helps you lay out your content in a single page, type of application. Each of these panels are collapsible, and resizable, so you don’t have to figure out how to get complex layouts like this working across A-grade browsers. And again—check out the examples, and check out the API documentation, there’s a Custom Event model associated with Layout Manager so that you can start interacting with user clicks, and with resizes and whatnot, so there is actually a lot of elbow grease that has gone into a widget like this, that you actually don’t have to figure out anymore, as well.
So the next section, we’re going to talk about how you might use YUI to display your data in a meaningful and interactive way—one thing is to go and get the data, but we have a couple widgets that really help you display that data. They say a picture is worth a thousand words, and so YUI Charts is built on Flash, but has a Javascript component to it so you can use Javascript to configure it and tweak the behavior. And it uses a familiar paradigm that all of our APIs have, so that you can take advantage of the Flash of the YUI Charts, but do things like customize the labels, for instance, to make it part of your own application, and make it do exactly what you need it to do. And the look and feel, the colors and whatnot, are also customizable.
Now the Charts component is actually built on top of the data source—so once you kind of grock the data source / widget relationship, you can use the same data source in Charts. You can also import that data source over to something else, like a DataTable, or an AutoComplete. So, once you start diving in and get familiar with the language, the next widget will get easier, and the next widget will get easier, and so forth.
TreeView is the best way to display a hierarchical relationship, such as a file directory structure. And once again, you can respond to user clicks to react, have your application react to what the user is doing. You can also do things like customize the icons, and adapt it to your own look and feel. And back to the idea of bringing data in at runtime—you can actually listen for the clicks on a particular node, and bring in information about its children, lazily. So you don’t have to load an entire data structure, or field directory, file director structure, at load time—you can wait, and just pull in the top level of information, and wait to load the children as needed.
Now, Calendars are such an easy way of displaying date data. This is actually one of our more popular components, just because there is no better way to show dates. The nice thing about Calendar is how configurable it is—we can support multiple calendars in a single interface, we have a really robust internationalization scheme, as you can see, and the way that Calendar is architected, it makes it really easy to build your own application on top of it. So you can see there, we’ve got a very specialized input field for modifying or inputing dates, there. And, again, we’ve got a very rich Custom Event model, where you can respond to user clicks, and the user interacting with the calendar, to have your application then respond in an interactive way.
So I wanted to touch on DataTable a little bit. It can actually get to be one of the more complex widgets. But the thing I wanted to just draw to your attention is a nice way of using DataTable in a rapid prototyping type of environment—and that is to say that DataTable is, again, once of those widgets that supports progressive enhancement, so if you can get your server to output table markup in a known format, you can take that markup and using that to create your DataTable. And it will enhance that plain Jane markup into a more robust widget. So the things I wanted to point out to your are—have your table markup wrapped in a DIV element, with a known ID, and also put a known ID on your table itself. And then just make sure you’ve got a “tHead” element for your column headers, and wrap your table rows in a “tBody”. And once you do that, you can feed this structure into the data table, and get all sorts of additional functionality like sorting, and pagination, and the list goes on and on. So we can take something like this, which is not going to be very functional or pretty, and pop it into a DataTable widget constructor, and end up with something like this, that gives you the built in Sam Skin, for instance, with the zebra striping, sortability, hiding and showing columns, resizability—all that.
So to get to that widget instance is a three step process. We’ll first start with defining a data source. And in this example, we’re going to feed that data source, the reference to the actual table and markup —so that’s the ID of the table element that we have there. And then we’re going to tell the table source what kind of data that table element holds—and we do that by defining the fields in a schema. And we’re going to identify them as the four columns, we’re going to call them ‘Name’, ‘Quiz’, ‘Test’, and ‘Paper’. And ‘Name’ is the person’s name, but the other three are actually numbers, so we’re going to identify that with a parser, and what that means is it’s going to start with the HTML string value of the number, and convert it into a Javascript number under the hood for you. And what that fixes is sorting. So if you’ve got numbers as strings, they’re going to sort incorrectly, but if we’ve got them as numbers, they will end up sorting correctly for you. Then the next step is to define the columns that we want our widget to display—so you can see here, we’re just going to show the same columns that we started with, and you’ll notice that the keys for the columns match exactly to the keys in the field, and so that’s how they’re going to end up being matched under the hood for you. And then we just create a new instance of DataTable with that thin layer constructor now, and we’re going to pass it the ID of the DOM element that’s going to hold the DataTable, and then we’re going to pass it the columns that we’ve defined, and the data source—and that’s how we end up with that pretty looking widget.
And to add the functionality that I was talking about earlier, we’re going to define those in the columns. And so “sortable” will give us sortable columns—and if you wanted every single column to be sortable, you’d want to set “sortable: true” for each of those. We can have columns be hideable, or showable, and if we set “hidden: true” in the column definition, when the widget gets created it will start out initialized with that hidden column—with that column as hidden. We can set “resizable: true” on different columns—that’s going to key off of Dragon Drops, so make sure you’ve got DragonDrop on the page if you want to have that functionality. But if you do, it’s really easy to now have columns that resize with a DragonDrop feature. And then, if you noticed before, we have percentages here that start out as numbers, and we’re just going to add a percent character after the number—we can do that by defining a formatting function to do that. And that’s actually really easy as well—we can accept some data, and add a string to it, and populate innerHTML. We have a number of built in formatter functions, but it’s actually really easy to go ahead and expand, and develop your own formatter functions as well.
So here’s the code that we just looked at—and that’s the output. We’ve got a sortable column there, and you’ll notice one of the columns is gone, it’s because it’s actually hidden, and then the percentage signs are there for the formatted numbers. And the sample code that will be made available to you actually has the actual code running, so you can feel free to copy and paste that for your reference, as well. Any questions so far?
Audience member: Can you show the code again?
Jenny: Yeah. I actually don’t have the…
Audience member: [inaudible]
Jenny: This one?
Audience member: Does the column [inaudible] —is that filter on the schema? So if that was like, I don’t know, homework scores as a schema, [inaudible]?
Jenny: The column definitions are actually independent of the field definitions. So you can theoretically have fields that are defined, that are not shown in the DataTable, by not having the matching column defined. And vice versa—you can actually have more columns than there are fields, and define custom formatters that determine what should go into those columns, that aren’t represented in the underlying data.
Audience member: Can you ever re-name table headers?
Jenny: You can name table or column headers whatever you want, by actually identifying a label property in the column. So by default, if you don’t have a label, it’s whatever the key is—but you can also specify a label property to have it be whatever you want, independent of the key.
Audience member: So in the response key of the [inaudible] for each field, is that a function?
Jenny: Yeah, this is actually in the response schema, the parser property is actually a pointer to a function. So we have a number of built in parsers, so that string number is actually a shortcut to that built in parser. But you could define a custom function that will route to your own function—so you could say, define a function “myParser”, and then in the parser property, have that be “myParser”, and so now as the data’s being sucked in by the DataTable, it will be routed to your custom function to do the conversion in a custom way.
Audience member: So basically nothing prevents me from saying something like: “key paper parser function”, and then the body of the [inaudible]?
Jenny: Yes, correct. You could define that function inline, in that field, in the field object directly.
Audience member: So what other data sources do you have, other than [inaudible] tables?
Jenny: We do have a number of different data sources that you could use. Local data source is meant for in-memory, or in-page data structures, so HTML elements—sorry, HTML table elements—in this example, but also in memory Javascript arrays, or in memory Javascript objects. But we also have XHR data source that lies on top of Connection Manager, to go and make a request to an external data source, like a server. And you might want to access your SQL database that way. And we also have script node data source, that is built on top of the Get Utility. And so if you wanted to use the YQL console as your data storer, you can go to the YQL console and figure out what that rest URL needs to be. You can then create a script node data source on top of that, and have any of those DataTables populate this widget.
So as this last section, we’re going to talk about the kind of round trip model of having end users provide inputs, and modify your data back to the server. So let’s revisit Connection Manager for a moment. The nice thing about Connection Manager is that it’s got this built in function to handle form post—and to get that up and running, all you have to do is get a reference to your form, and call “setForm” against it. And what that does is it takes the input of your form, and initializes a post request body with that form input. And so now you can call “asyncRequest” against Connection Manager, and it will automatically use that form’s data to send the post. And in this case, we’re going to call a PHP script called “submitHandler”—and the idea here is that for Connection Manager requests, there are going to be same domain requests. So either my script lives on the same domain, or I need to access a proxy that’s on my domain to then go ahead and make a connection to a remote server. So keep that in mind whenever you’re working with Connection Manager. This is a nice built in feature to help you submit your forms without having to take the user off the page—so now you have an in-page submission of your form data.
When you call “asyncRequest”, this object literal as the last argument is your callback, and so you’ll see this over and over again in our library—we’re defining functions that execute at certain moments in time. So for a connection manager, we’re defining a success handler that will execute when that request returns successfully, the asynchronous request. And then we’re also defining a failure function to handle error conditions, in case something goes wrong in the communication with the server.
So the dialog widget also has a built in feature that does a very similar thing—you can have a form within a dialog, as the content body, and a built in… well, either take advantage of the action you’ve supplied, and submit the form for you that way, or use the underlying Connection Manager feature to submit that form asynchronously—again, within the same page. So that’s something else to keep in mind as well.
DataTable also has editability features—so, it has built in inline editing, so that users can modify data on a cell by cell basis. And we do have a number of built in cell editors for you to take advantage of. But if you desired, you could certainly extend that class, or create your own subclass to have very, very custom editability of functionalities. But it certainly is easy to get it up and running with the built in cell editing features.
So Rich Text Editor is kind of like a text area field on steroids. It gives you the ability to take text and format it in a really rich way, adding styling, formatting as list items, pulling in images, and it does it all within this in-page user module. And again, this is, from a developer’s standpoint, very extensible, very customizable, and it allows you to pull in more buttons to create your own extension, your own behavior—it takes you so much further than what the built in browser gives you, and it does it in a truly cross browser, A-grade supported way.
So I wanted to revisit Calendar, just to show you how you can use the Calendar widget to now accept data—date data—from your end user. We’re going to instantiate a new calendar with the new constructor, and the “myContainer” here is, again, is an ID to DOM element that’s already on your page, and that’s the element into which the container will be created. And this next bit of magic, here, is subscribing to the selective end of the Calendar widget, which allows you to now define a function that will execute when the user selects the date. And so the syntax with that looks like “myCalendar.selectEvent.subscribe”, and now we’re going to define the function in that method.
So our function is going to take a couple of arguments—”type” just defines the custom type that has been fired, so in this case, we would get back a string called “selectEvent”. And then “args” holds the actual, pertinent data, relevant to the event that has just fired. So it’s going to hold date information. And for our sample function here, we’re just going to display an alert dialog that shows back the date that has been selected. And so the “args” that has past to your custom function is actually formatted as an array—so you need to take care to look at the API documentation to figure out which array elements holds which piece of data, for instance. But I’ve extracted that all out for you, and we can see the year, the month, and the date, that has been selected, and display that back to the end user. Now, once I’ve defined this function within the subscribe call, I still need to call the render method that will actually paint the calendar into the DOM. So until that’s called, the end user won’t actually see your calendar. But what we’re doing here, setting up the event, to the event handler, to react to a select event when it does happen to fire. So the code that we just saw will execute in this fashion. And again, you’ll have that available to you to copy and paste for your own application.
So I wanted to leave you with some links that I think will help save you some time as you get up and running. The first place for you to remember is our http://developer.yahoo.com/yui site —this is like home base for all of our documentation. We’ve got hundreds and hundreds of live working examples for you to actually check out, and copy and paste that code. We’ve also got our API documentation, and each component has its own user guide, which is pretty lengthy verbiage on all the different configurations that you can play with to customize that behavior.
I also wanted to point out our Dependancy Configurator—this is going to save you a ton of time. All you need to do is go to this URL, and figure out what widgets, or what utilities you’re interested in using, and it will generate the links that you need to embed in your page to have access to those build files now. And Yahoo! hosts all of our build files for public access, open to anyone that’s interested in using YUI. What this Dependency Configurator does is point you to the combo handle URL, so all the build files are accessed with a single HTTP request, which is a huge performance boon. It comes minified, but you can also unflag the minification—so if you wanted to use it in a debug environment, you can certainly access the debug build. But by default it’s combo handled and minified for you. And it also gives you the CSS link as well—so just copy and paste these two lines, and you’re ready to start using YUI in your page.
Grids Builder is another huge time saver—if you’re interested in using CSS grids for your layout, I highly recommend starting here. You can just fill out this form, and decide how many columns you want, and how wide you want your page to be, click the ‘show code’ button and it hands you the markup that you need on a silver platter, so you don’t have to be in there tweaking class names on your DIV containers. This makes it really easy to get set up, and then to also maybe change your layout if you change your mind—if you want four columns instead of three.
Thanks for joining me on this whirlwind tour.

