|
|
|
Implementing a Calendar Control in the Yahoo User Interface (YUI)
The Yahoo User Interface (YUI) Calendar control, allows you to easily create a variety of attractive and highly functional calendar interfaces which can allow your visitors to quickly and easily select single dates, or range of dates. There is also a range of different formats of Calendar that we can create; there's the basic, single-select, and one-page calendar control which displays one month at a time, or there's a larger, multi-page calendar which allows multiple months to be displayed at once. Multi-select calendars can come in either single or multiple month display formats. In this article by Dan Wellman, we will see how to implement a calendar control in the YUI. The Basic Calendar ClassThe most basic type of calendar is the single-panel Calendar which is created with the YAHOO.widget.Calendar class. To display a calendar, an HTML element is required to act as a container for the calendar. The screenshot shows a basic Calendar control:
The constructor can then be called specifying, at the very least the id of the container element as an argument. You can also specify the id of the Calendar object as an argument, as well as an optional third argument that can accept a literal object containing various configuration properties. The configuration object is defined within curly braces within the class constructor. It contains a range of configuration properties and keys that can be used to control different Calendar attributes such as its title, a comma-delimited range of pre-selected dates, or a close button shown on the calendar. There are a large number of methods defined in the basic Calendar class; some of these are private methods that are used internally by the Calendar object to do certain things and which you normally wouldn't need to use yourself. Some of the more useful public methods include:
As you can see, there are many methods that you can call to take advantage of the advanced features of the calendar control. The CalendarGroup ClassIn addition to the basic calendar, you can also create a grouped calendar that displays two or more month panels at once using the YAHOO.widget.CalendarGroup class. The control automatically adjusts the Calendar's UI so that the navigation arrows are only displayed on the first and last calendar panels, and so that each panel has its own heading indicating which month it refers to. The CalendarGroup class contains additional built-in functionality for updating the calendar panels on display, automatically. If you have a two-panel calendar displaying, for example, January and February, clicking the right navigation arrow will move February to the left of the panel so that March will display as the right-hand panel. All of this is automatic and nothing needs to be configured by you. There are fewer methods in this class; some of those found in the basic Calendar class can also be found here, such as the navigation methods, selection methods, and some of the render methods. Native methods found only in the CalendarGroup class include:
This article has been extracted from: Learning the Yahoo! User Interface library
Implementing a CalendarTo complete this example, the only tool other than the Yahoo User Interface (YUI) that you'll need is a basic text editor. Native support for the YUI is provided by some web authoring software packages, most notably Aptana, an open-source application that has been dubbed 'Dreamweaver Killer'. However, I always find that writing code manually while learning something is much more beneficial. It is very quick and easy to add the calendar, as the basic default implementations require very little configuration. It can be especially useful in forms where the visitor must enter a date. Checking that a date has been entered correctly and in the correct format takes valuable processing time, but using the YUI calendar means that dates are always exactly as you expect them to be. So far we've spent most of this article looking at a lot of the theoretical issues surrounding the library; I don't know about you, but I think it's definitely time to get on with some actual coding!The Initial HTML PageOur first example page contains a simple text field and an image, which once clicked will display the Calendar control on the page, thereby allowing for a date to be selected and added to the input. Begin with the following basic HTML page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" We begin with a valid DOCTYPE declaration, a must in any web page. For validity, we can also add the lang attribute to the opening <html> tag and for good measure, enforce the utf-8 character set. Nothing so far is YUI-specific, but coding in this way every time is a good habit. We link to the stylesheet used to control the appearance of the calendar control, which is handled in this example by the sam skin within the <link> tag. Accordingly, we also need to add the appropriate class name to the <body> tag. Following this, we link to the required library files with <script> tags; the calendar control is relatively simple and requires just the YAHOO, Document Object Model (DOM), and Event components (using the aggregated yahoo-dom-event.js file for efficiency), as well as the underlying source file calendar-min.js. A brief <style> tag finishes the <head> section of the page with some CSS relevant to this particular example, and the <body> of the page at this stage contains just two <div> elements: the first holds a <label>, text field, and a calendar icon (which can be used to launch the control), while the second holds the calendar control. When viewed in a browser, the page at this point should appear like this:
The calendar icon used in this example was taken, with gratitude from Mark Carson at http://markcarson.com. Beginning the ScriptingWe want the calendar to appear when the icon next to the text field is clicked, rather than it being displayed on the page-load, so the first thing we need to do is to set a listener for the click event on the image. Directly before closing </body> tag, add the following code: <script type="text/javascript"> Let's look at each line of the above code. We first use the .namespace() method of the YAHOO utility to set up the namespace object used for this example. Next we define the anonymous launchCal function, which will hold all of the code that generates the calendar control. Then we use the .onDOMReady() method of the Event utility to execute the launchCal function when the DOM is in an usable state. We'll be looking at the DOM utility in much greater detail later in the book. Now we can add the extremely brief code that's required to actually produce the Calendar. Within the braces of our anonymous function, add the following code: //create the calendar object, specifying the container This is all that we need to create the Calendar; we simply define myCal as a new Calendar object, specifying the underlying container HTML element as an argument of the constructor. Once we have a Calendar object, we can call the .render() method on it to create the calendar and display it on the page. No arguments are required for this method. Since we want the calendar to be displayed when its icon is clicked, we hide the calendar from view straight away. To display the calendar when the icon for it is clicked, we'll need one more anonymous function. Add the following code beneath the .hide() method: //define the showCal function which shows the calendar Now we can attach a listener which detects the click event on the calendar icon: //attach listener for click event on calendar icon Save the file that we've just created as calendar.html or similar in your yuisite directory. If you view it in your browser now and click the Calendar icon, you should see this:
The calendar is automatically configured to display the current date, although this is something that can be changed using the configuration object mentioned earlier. If you use a DOM explorer to view the current DOM of a page with an open calendar on it, you'll see that a basic Calendar control is rendered as a table with eight rows and seven columns. The first row contains the images used to navigate between previous or forthcoming months and the title of the current month and year. The next row holds the two-letter representations of each of the different days of the week, and the rest of the rows hold the squares representing the individual days of the current month. The screenshot on the next page show some of the DOM representation of the Calendar control used in our example page:
Now that we can call up the Calendar control by clicking on our Calendar icon, we need to customize it slightly. Unless the person completing the form is very young, they will need to navigate through a large number of calendar pages in order to find their date of birth. This is where the Calendar Navigator interface comes into play. We can easily enable this feature using a configuration object passed into the Calendar constructor. Alter your code so that it appears as follows: //create the calendar object, using container & config object Clicking on the Month or Year label will now open an interface which allows your visitors to navigate directly to any given month and year:
The configuration object can be used to set a range of calendar configuration properties including the original month and year displayed by the Calendar, the minimum and maximum dates available to the calendar, a title for the calendar, a close button, and various other properties. This article has been extracted from: Learning the Yahoo! User Interface library
Let's update our Calendar instance so that it features a title and a close button. Add the following properties to the literal object in our constructor: //create the calendar object, specifying the container and a literal This is what our Calendar should now look like:
Configuration properties like those we have just set, can also be set outside of the constructor using the .queueProperty() and .fireQueue() methods, or by using the .setProperty() method. Let's use these to alter our Calendar so that the first column header is set to Monday instead of Sunday. Add the following code directly before the call to the .render() method: //configure the calendar to begin on Monday When the calendar is displayed now, Monday will be the first day instead of Sunday:
Finally, we need to add some additional code that will allow the date that is selected to be inserted into the text field. We can do this using some of the custom events defined by the calendar classes. Highly EventfulBoth the Calendar and CalendarGroup classes have a series of custom events defined for them which allow for easily listening and reacting to interesting moments during any calendar or calendar group interaction. The two classes both have the same set of events defined for them, including:
This rich event system allows you to easily watch for cells being selected or deselected, month panel changes, render events, or even the reset method being called, and add code to deal with these key moments effectively. As you can see, most of the events form pairs of before and after events, which allows you to easily cancel or abort an operation before it has any visual impact. Let's now take a look at how these custom Calendar events can be used. First define the function that will handle the select event; add the following code directly after the showCall() function: //attach listener for click event on calendar icon The type and args objects are automatically created by the control; the args object is what we are interested in here, because it gives us easy access to an array of information about our Calendar. Now, within the curly braces of the ripDate() function set the following variables: //get the date components The first item in the args array is an array of selected dates, so we first save this to the variable dates. As this is a single-select calendar, only the first item of the dates array will contain data, so this is also saved to a variable: the date variable. Each date is itself an array, with the first item corresponding to the year, the second item equaling the month, and the third item mapped to the individual date. All of these values are saved into variables. Var theDate = theMonth + "/" + theDay + "/" + theYear; This part of the function uses standard concatenation techniques to build a string containing the individual date components in the format in which we want to present them (so that, for example, it would be extremely easy to express dates in UK format, where the date appears before the month): //get a reference to the text field Finally, we use the very handy DOM utility's .get() method to grab a reference to the text field, set the value of the text field to our date string, and then hide the calendar once more. Save the file once more and view it again in your browser of choice. After clicking the Calendar icon and choosing a date, it should be displayed in the text field:
At this point, we can take a brief look at how we can override the default styling of the calendar. I think we should change the calendar's close button and make it look a little more like a traditional close button. This can be done with the following simple CSS rule, which should be inserted into the <style> tag in the <head> of our document: .yui-skin-sam .yui-calcontainer .calclose {Because we're using the default sam skin, we should begin the selector with this class name and then target the name of the container and close elements. Other elements of the calendar, such as the navigation arrows, can easily be styled in this way. Using a DOM explorer to expose the names of other parts of the calendar is also an easy way to change other elements of the calendar. Our Close button should now appear like this:
The DateMath ClassIn addition to the two classes catering for two different types of calendar, a class, YAHOO.widget.DateMath, defines a series of utilities for performing simple mathematical calculations or comparisons on dates. It has only a small number of static properties and a small set of methods. There are no events defined in this class and no configuration attributes. All of its methods return either a Boolean value indicating whether the comparison was true or false, or a modified date object. Some of them will be used very frequently, while others will be used only rarely (but are still very useful). Our date of birth calendar isn't really appropriate for seeing how the DateMath calls can be used. In order to examine some of the available methods, we should create a new calendar. In a blank page of your text editor, begin with the following HTML: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" This very simple page will form the basis of our example. Next, add the following <script> tag to the <body> tag of the page, directly below the results <div> tag: <script type="text/javascript"> We create the same namespace object for this page and initially generate the calendar using the .onDOMReady() method and an anonymous function inexactly the same way as we did before. Next, add the following code to the YAHOO.yuibook.calendar.initCal() function: //create the calendar object, specifying the container We create the calendar in the same way as in the previous example and render it on the page. This time, we don't need to worry about hiding it again as it will be a permanent fixture of the page. Before we start looking at the DateMath methods, let's get a reference to the current date. Add the following code directly below the .render() method call: //get and display today's date It is easy to obtain today's date in UTC format using the today property of the Calendar class. Once we have this, we can get references to the date and month numerical representations and from these we can get the full day name and month name using Locale.WEEKDAYS_LONG[dayNum] and Locale.MONTHS_LONG[monthNum]. The Locale object is automatically created by the control and contains localized day and month names. It is primarily used to add new locales and specify alternative day and month names, but because it defaults to English, we can simply read the properties and pull out what we want. This article has been extracted from: Learning the Yahoo! User Interface library
Once we have the information we need, it is simple enough to create a new <div> element, populate it with our formatted date string and then attach it to our results <div> element. Your page should look similar to the following screenshot:
Now we can have some fun with a few of the DateMath methods. First, add the following directly beneath our last block of code: //work out date in 10 days time We can use the .add() method of the YAHOO.widget.DateMath class to add a specified amount of time to a date object. In this example, the date object is obtained using the myCal.today property once more (as we can't use the date variable that already exists as this is a number not a full date object), but any date object could be used. The .add() method takes three arguments. The first is the date object on which the addition should be carried out, the second is one of the built-in field constants representing the unit to be added (which could be days, weeks, months, years), and the final argument is the actual amount to be added. For the purposes of this example, I have left the futureDate field in full UTC format, but we could easily extract just the parts of the date that we want, just as we did to get the today date. Let's now look at the almost identical .subtract() method. Add the following code: //work out date two months ago You can see how easy the DateMath class makes addition and subtraction of date objects. The class has other useful methods such as the .getDayOffset() and .getWeekNumber() methods. We can expose the functionality of these two methods with the following code: //work out day and week numbers of current date Save the file as datemath.html and view it in your browser of choice:
SummaryIn this article, we had a look at the basic Calendar class and the GroupCalendar class. Further, we had a look at the various custom events defined for the Calendar and CalendarGroup classes, which allow for listening and reacting to interesting moments during calendar or calendar group interaction. Next, we implemented a Calendar control in the YUI and also worked with one of its supporting classes: the DateMath class. This example has shown us how easy it is to implement YUI components.About the AuthorDan Wellman lives with his wife and three children in his home town of Southampton on the south coast of England. By day his mild-mannered alter-ego works for a small yet accomplished e-commerce production agency. By night he battles the forces of darkness and fights for truth, justice, and less intrusive JavaScript. He has been writing computer-related articles, tutorials, and reviews for around five years and is rarely very far from a keyboard of some description. Books from Packt | Want to know more about Packt's Article Network? Interested in contributing your article ideas? Please visit our FAQ for more information. See More BROWSE
All Titles WordPress Web Services SOA BPEL Web Graphics & Video Web Development RAW Portugues, Espanol, Italiano PHP/MySQL Oracle Open Source Networking & Telephony Moodle Microsoft & .NET Linux Servers Joomla! JBoss Java e-Commerce Drupal CRM Content Management Beginner Guides Architecture and Analysis AJAX Future Titles Recently Published Titles
|
| ||||||||