mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Calendar: Add calendar widget
Add calendar widget by copying and renaming datepicker widget files. Remove datepicker functionality, options and methods from Calendar. Remove calendar functionality, options and methods from Datepicker. Adjust tests due to split and changed specification. Remove duplicated demo files and fix some demos. Simplify calendar generation, use CSS instead of inline styles. Fix destroy method. Make use of uniqueId method. Fix focus highlighting when month is changed. Add version property. Add common unit tests. Fix input keyboard handling.
This commit is contained in:
parent
35b52a0dfc
commit
510ba08cff
@ -28,6 +28,7 @@ var
|
||||
"core",
|
||||
"accordion",
|
||||
"autocomplete",
|
||||
"calendar",
|
||||
"button",
|
||||
"datepicker",
|
||||
"dialog",
|
||||
|
@ -13,6 +13,7 @@ var versions = {
|
||||
"Accordion": "accordion/accordion.html",
|
||||
"Autocomplete": "autocomplete/autocomplete.html",
|
||||
"Button": "button/button.html",
|
||||
"Calendar": "calendar/calendar.html",
|
||||
"Core": "core/core.html",
|
||||
"Datepicker": "datepicker/datepicker.html",
|
||||
"Dialog": "dialog/dialog.html",
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Display button bar</title>
|
||||
<title>jQuery UI Calendar - Display button bar</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,12 +11,12 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
$( "#calendar" ).calendar({
|
||||
showButtonPanel: true
|
||||
});
|
||||
});
|
||||
@ -24,7 +24,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Display a button for selecting Today's date and a Done button for closing the calendar with the boolean <code>showButtonPanel</code> option. Each button is enabled by default when the bar is displayed, but can be turned off with additional options. Button text is customizable.</p>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Display inline</title>
|
||||
<title>jQuery UI Calendar - Default functionality</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,21 +11,21 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker();
|
||||
$( "#calendar" ).calendar();
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Date: <div id="datepicker"></div>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Display the datepicker embedded in the page instead of in an overlay. Simply call .datepicker() on a div instead of an input.</p>
|
||||
<p>The calendar is a widget for selecting a date using a visual calendar representation.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Display month & year menus</title>
|
||||
<title>jQuery UI Calendar - Display month & year menus</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,12 +11,12 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
$( "#calendar" ).calendar({
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
});
|
||||
@ -25,7 +25,7 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Show month and year dropdowns in place of the static month/year header to facilitate navigation through large timeframes. Add the boolean <code>changeMonth</code> and <code>changeYear</code> options.</p>
|
22
demos/calendar/index.html
Normal file
22
demos/calendar/index.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>jQuery UI Calendar Demos</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul>
|
||||
<li><a href="default.html">Default functionality</a></li>
|
||||
<li><a href="buttonbar.html">Display button bar</a></li>
|
||||
<li><a href="dropdown-month-year.html">Display month & year menus</a></li>
|
||||
<li><a href="localization.html">Localize calendar</a></li>
|
||||
<li><a href="min-max.html">Restrict date range</a></li>
|
||||
<li><a href="multiple-months.html">Display multiple months</a></li>
|
||||
<li><a href="other-months.html">Dates in other months</a></li>
|
||||
<li><a href="show-week.html">Show week of the year</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
41
demos/calendar/localization.html
Normal file
41
demos/calendar/localization.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Calendar - Localize calendar</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
<script src="../../external/date.js"></script>
|
||||
<script src="../../external/localization.js"></script>
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
var calendar = $( "#calendar" ).calendar(),
|
||||
date = calendar.calendar( "valueAsDate" );
|
||||
|
||||
$( "#locale" ).change( function() {
|
||||
Globalize.locale( $( this ).val() );
|
||||
calendar.calendar( "valueAsDate", date );
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="calendar"></div>
|
||||
<select id="locale">
|
||||
<option value="de-DE" selected>German (Deutsch)</option>
|
||||
<option value="en">English</option>
|
||||
</select>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Localize the calendar calendar language and format (English / Western formatting is the default). The calendar includes built-in support for languages that read right-to-left, such as Arabic and Hebrew.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Restrict date range</title>
|
||||
<title>jQuery UI Calendar - Restrict date range</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,18 +11,18 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({ minDate: -20, maxDate: "+1M +10D" });
|
||||
$( "#calendar" ).calendar({ minDate: -20, maxDate: "+1M +10D" });
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Restrict the range of selectable dates with the <code>minDate</code> and <code>maxDate</code> options. Set the beginning and end dates as actual dates (new Date(2009, 1 - 1, 26)), as a numeric offset from today (-20), or as a string of periods and units ('+1M +10D'). For the last, use 'D' for days, 'W' for weeks, 'M' for months, or 'Y' for years.</p>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Display multiple months</title>
|
||||
<title>jQuery UI Calendar - Display multiple months</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,12 +11,12 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
$( "#calendar" ).calendar({
|
||||
numberOfMonths: 3,
|
||||
showButtonPanel: true
|
||||
});
|
||||
@ -25,10 +25,10 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single datepicker.</p>
|
||||
<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single calendar.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
33
demos/calendar/multiple-months.html
Normal file
33
demos/calendar/multiple-months.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Calendar - Display multiple months</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
<script src="../../external/date.js"></script>
|
||||
<script src="../../external/localization.js"></script>
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#calendar" ).calendar({
|
||||
numberOfMonths: 3
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Set the <code>numberOfMonths</code> option to an integer of 2 or more to show multiple months in a single calendar.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Dates in other months</title>
|
||||
<title>jQuery UI Calendar - Dates in other months</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,12 +11,12 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
$( "#calendar" ).calendar({
|
||||
eachDay: function( day ) {
|
||||
if ( day.lead ) {
|
||||
day.render = true;
|
||||
@ -30,10 +30,10 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>The datepicker can show dates that come from other than the main month
|
||||
<p>The calendar can show dates that come from other than the main month
|
||||
being displayed. These other dates can also be made selectable.</p>
|
||||
</div>
|
||||
</body>
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Show week of the year</title>
|
||||
<title>jQuery UI Calendar - Show week of the year</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
@ -11,12 +11,12 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
$( "#calendar" ).calendar({
|
||||
showWeek: true
|
||||
});
|
||||
});
|
||||
@ -24,10 +24,10 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"></p>
|
||||
<div id="calendar"></div>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>The datepicker can show the week of the year. The calculation follows
|
||||
<p>The calendar can show the week of the year. The calculation follows
|
||||
<a href="http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table">Unicode CLDR specification</a>.
|
||||
This means that some days from one year may be placed into weeks 'belonging' to another year.</p>
|
||||
</div>
|
@ -1,36 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Populate alternate field</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
<script src="../../external/date.js"></script>
|
||||
<script src="../../external/localization.js"></script>
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker({
|
||||
select: function( event, ui ) {
|
||||
var date = Globalize.parseDate( ui.date, { date: "short" } );
|
||||
$( "#alternate" ).val( Globalize.format( date, { date: "long" } ) );
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>Date: <input type="text" id="datepicker"> <input type="text" id="alternate" size="30"/></p>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Populate an alternate field with its own date format whenever a date is selected using the <code>altField</code> and <code>altFormat</code> options. This feature could be used to present a human-friendly date for user selection, while passing a more computer-friendly date through for further processing.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -18,6 +18,7 @@
|
||||
<script src="../../ui/effect-fold.js"></script>
|
||||
<script src="../../ui/effect-slide.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
|
@ -12,29 +12,21 @@
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#datepicker" ).datepicker();
|
||||
$( "#format" ).change(function() {
|
||||
var format;
|
||||
switch( $( this ).val() ) {
|
||||
case "short":
|
||||
$( "#datepicker" ).datepicker( "option", "dateFormat", {
|
||||
date: "short"
|
||||
});
|
||||
break;
|
||||
case "long":
|
||||
$( "#datepicker" ).datepicker( "option", "dateFormat", {
|
||||
date: "long"
|
||||
});
|
||||
break;
|
||||
case "iso":
|
||||
$( "#datepicker" ).datepicker( "option", "dateFormat", {
|
||||
pattern: "yyyy-MM-dd"
|
||||
});
|
||||
break;
|
||||
var value,
|
||||
datepicker = $( "#datepicker" ).datepicker();
|
||||
|
||||
$( "#format" ).change( function() {
|
||||
value = $( this ).val();
|
||||
|
||||
if ( value === "iso" ) {
|
||||
datepicker.datepicker( "option", "dateFormat", { pattern: "yyyy-MM-dd" } );
|
||||
} else {
|
||||
datepicker.datepicker( "option", "dateFormat", { date: value } );
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,49 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Datepicker - Select a Date Range</title>
|
||||
<link rel="stylesheet" href="../../themes/base/all.css">
|
||||
<script src="../../external/jquery/jquery.js"></script>
|
||||
<script src="../../external/globalize/globalize.js"></script>
|
||||
<script src="../../external/date.js"></script>
|
||||
<script src="../../external/localization.js"></script>
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#from" ).datepicker({
|
||||
defaultDate: "+1w",
|
||||
changeMonth: true,
|
||||
numberOfMonths: 3,
|
||||
onClose: function( selectedDate ) {
|
||||
$( "#to" ).datepicker( "option", "minDate", selectedDate );
|
||||
}
|
||||
});
|
||||
$( "#to" ).datepicker({
|
||||
defaultDate: "+1w",
|
||||
changeMonth: true,
|
||||
numberOfMonths: 3,
|
||||
onClose: function( selectedDate ) {
|
||||
$( "#from" ).datepicker( "option", "maxDate", selectedDate );
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<label for="from">From</label>
|
||||
<input type="text" id="from" name="from"/>
|
||||
<label for="to">to</label>
|
||||
<input type="text" id="to" name="to"/>
|
||||
|
||||
<div class="demo-description">
|
||||
<p>Select the date range to search for.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -12,6 +12,7 @@
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
<script>
|
||||
|
@ -10,6 +10,7 @@
|
||||
<script src="../../external/localization.js"></script>
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
|
@ -9,19 +9,10 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="default.html">Default functionality</a></li>
|
||||
<li><a href="date-formats.html">Format date</a></li>
|
||||
<li><a href="min-max.html">Restrict date range</a></li>
|
||||
<li><a href="localization.html">Localize calendar</a></li>
|
||||
<li><a href="alt-field.html">Populate alternate field</a></li>
|
||||
<li><a href="inline.html">Display inline</a></li>
|
||||
<li><a href="buttonbar.html">Display button bar</a></li>
|
||||
<li><a href="dropdown-month-year.html">Display month & year menus</a></li>
|
||||
<li><a href="other-months.html">Dates in other months</a></li>
|
||||
<li><a href="show-week.html">Show week of the year</a></li>
|
||||
<li><a href="multiple-calendars.html">Display multiple months</a></li>
|
||||
<li><a href="icon-trigger.html">Icon trigger</a></li>
|
||||
<li><a href="animation.html">Animations</a></li>
|
||||
<li><a href="date-range.html">Date Range</a></li>
|
||||
<li><a href="date-formats.html">Format date</a></li>
|
||||
<li><a href="icon-trigger.html">Icon trigger</a></li>
|
||||
<li><a href="localization.html">Localize calendar</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
@ -11,6 +11,7 @@
|
||||
<script src="../../ui/core.js"></script>
|
||||
<script src="../../ui/widget.js"></script>
|
||||
<script src="../../ui/button.js"></script>
|
||||
<script src="../../ui/calendar.js"></script>
|
||||
<script src="../../ui/position.js"></script>
|
||||
<script src="../../ui/datepicker.js"></script>
|
||||
<link rel="stylesheet" href="../demos.css">
|
||||
|
@ -11,6 +11,7 @@
|
||||
<li><a href="accordion/">accordion</a></li>
|
||||
<li><a href="autocomplete/">autocomplete</a></li>
|
||||
<li><a href="button/">button</a></li>
|
||||
<li><a href="calendar/">calendar</a></li>
|
||||
<li><a href="datepicker/">datepicker</a></li>
|
||||
<li><a href="dialog/">dialog</a></li>
|
||||
<li><a href="draggable/">draggable</a></li>
|
||||
|
@ -20,6 +20,7 @@
|
||||
"autocomplete/autocomplete.html",
|
||||
"button/button.html",
|
||||
"core/core.html",
|
||||
"calendar/calendar.html",
|
||||
"datepicker/datepicker.html",
|
||||
"dialog/dialog.html",
|
||||
"draggable/draggable.html",
|
||||
|
26
tests/unit/calendar/all.html
Normal file
26
tests/unit/calendar/all.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Calendar Test Suite</title>
|
||||
|
||||
<script src="../../jquery.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../../../external/qunit/qunit.css">
|
||||
<link rel="stylesheet" href="../qunit-composite.css">
|
||||
<script src="../../../external/qunit/qunit.js"></script>
|
||||
<script src="../qunit-composite.js"></script>
|
||||
<script src="../subsuite.js"></script>
|
||||
|
||||
<script>
|
||||
testAllVersions( "calendar" );
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
46
tests/unit/calendar/calendar.html
Normal file
46
tests/unit/calendar/calendar.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery UI Calendar Test Suite</title>
|
||||
|
||||
<script src="../../jquery.js"></script>
|
||||
<script src="../../../external/jquery-simulate/jquery.simulate.js"></script>
|
||||
<script src="../../../external/globalize/globalize.js"></script>
|
||||
<script src="../../../external/localization.js"></script>
|
||||
<script src="../../../external/date.js"></script>
|
||||
<link rel="stylesheet" href="../../../external/qunit/qunit.css">
|
||||
<script src="../../../external/qunit/qunit.js"></script>
|
||||
<script src="../testsuite.js"></script>
|
||||
<script>
|
||||
TestHelpers.loadResources({
|
||||
css: [ "core", "calendar" ],
|
||||
js: [
|
||||
"ui/core.js",
|
||||
"ui/widget.js",
|
||||
"ui/button.js",
|
||||
"ui/calendar.js"
|
||||
]
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="calendar_common.js"></script>
|
||||
<script src="calendar_core.js"></script>
|
||||
<script src="calendar_events.js"></script>
|
||||
<script src="calendar_methods.js"></script>
|
||||
<script src="calendar_options.js"></script>
|
||||
<script src="calendar_test_helpers.js"></script>
|
||||
|
||||
<script src="../swarminject.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture">
|
||||
|
||||
<div id="calendar"></div>
|
||||
<div id="calendar2"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
14
tests/unit/calendar/calendar_common.js
Normal file
14
tests/unit/calendar/calendar_common.js
Normal file
@ -0,0 +1,14 @@
|
||||
TestHelpers.commonWidgetTests( "calendar", {
|
||||
defaults: {
|
||||
dateFormat: { date: "short" },
|
||||
disabled: false,
|
||||
eachDay: $.noop,
|
||||
numberOfMonths: 1,
|
||||
showWeek: false,
|
||||
value: null,
|
||||
|
||||
// callbacks
|
||||
create: null,
|
||||
select: null
|
||||
}
|
||||
});
|
365
tests/unit/calendar/calendar_core.js
Normal file
365
tests/unit/calendar/calendar_core.js
Normal file
@ -0,0 +1,365 @@
|
||||
(function( $ ) {
|
||||
|
||||
module( "calendar: core" );
|
||||
|
||||
TestHelpers.testJshint( "calendar" );
|
||||
|
||||
test( "base structure", function() {
|
||||
expect( 22 );
|
||||
|
||||
var header, title, table, thead, week, child, buttonpane,
|
||||
element = $( "#calendar" ).calendar(),
|
||||
dp = element.calendar( "widget" );
|
||||
|
||||
function step1() {
|
||||
ok( !dp.is( ".ui-calendar-rtl" ), "Structure - not right-to-left" );
|
||||
ok( !dp.is( ".ui-calendar-multi" ), "Structure - not multi-month" );
|
||||
equal( dp.children().length, 3, "Structure - child count (header, calendar)" );
|
||||
|
||||
header = dp.children( ":first" );
|
||||
ok( header.is( "div.ui-calendar-header" ), "Structure - header division" );
|
||||
equal( header.children().length, 3, "Structure - header child count" );
|
||||
ok( header.children( ":first" ).is( ".ui-calendar-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
|
||||
ok( header.children( ":eq(1)" ).is( ".ui-calendar-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
|
||||
|
||||
title = header.children( ":last" ).children( ":first" );
|
||||
ok( title.is( "div.ui-calendar-title" ) && title.html() !== "", "Structure - title division" );
|
||||
equal( title.children().length, 2, "Structure - title child count" );
|
||||
ok( title.children( ":first" ).is( "span.ui-calendar-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
|
||||
ok( title.children( ":last" ).is( "span.ui-calendar-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
|
||||
|
||||
table = dp.children( ":eq(1)" );
|
||||
ok( table.is( "table.ui-calendar-calendar" ), "Structure - month table" );
|
||||
ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
|
||||
|
||||
thead = table.children( ":first" ).children( ":first" );
|
||||
ok( thead.is( "tr" ), "Structure - month table title row" );
|
||||
equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
|
||||
ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
|
||||
ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
|
||||
|
||||
week = table.children( ":eq(1)" ).children( ":first" );
|
||||
ok( week.is( "tr" ), "Structure - month table week row" );
|
||||
equal( week.children().length, 7, "Structure - week child count" );
|
||||
|
||||
element.calendar( "destroy" );
|
||||
|
||||
step2();
|
||||
}
|
||||
|
||||
function step2() {
|
||||
element = $( "#calendar" ).calendar( { numberOfMonths: 2 } );
|
||||
dp = element.calendar( "widget" );
|
||||
|
||||
ok( dp.is( ".ui-calendar-multi" ), "Structure multi [2] - multi-month" );
|
||||
equal( dp.children().length, 4, "Structure multi [2] - child count" );
|
||||
|
||||
child = dp.children( ":eq(2)" );
|
||||
ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" );
|
||||
|
||||
element.calendar( "destroy" );
|
||||
}
|
||||
|
||||
step1();
|
||||
});
|
||||
|
||||
test( "Localization", function() {
|
||||
expect( 5 );
|
||||
|
||||
var defaultLocale = Globalize.locale(),
|
||||
element = $( "#calendar" ),
|
||||
date = new Date( 2014, 0, 1 ),
|
||||
initCalendar = function() {
|
||||
element
|
||||
.calendar()
|
||||
.calendar( "valueAsDate", date );
|
||||
},
|
||||
testLocalization = function( message ) {
|
||||
equal(
|
||||
element.find( ".ui-calendar-month" ).text(),
|
||||
"Januar", message + "titlebar year"
|
||||
);
|
||||
equal(
|
||||
element.find( "thead th:first" ).text(),
|
||||
"Mo.", message + "teader first day"
|
||||
);
|
||||
equal(
|
||||
element.find( "thead th:last" ).text(),
|
||||
"So.", message + "header last day"
|
||||
);
|
||||
equal(
|
||||
element.find( ".ui-calendar-prev" ).text(),
|
||||
"<zurück", message + "header prev"
|
||||
);
|
||||
equal(
|
||||
element.find( ".ui-calendar-next" ).text(),
|
||||
"Vor>", message + "header next"
|
||||
);
|
||||
};
|
||||
|
||||
Globalize.locale( "de-DE" );
|
||||
initCalendar();
|
||||
testLocalization( "Init: " );
|
||||
element.calendar( "destroy" );
|
||||
|
||||
Globalize.locale( defaultLocale.locale );
|
||||
});
|
||||
|
||||
asyncTest( "keyboard handling", function() {
|
||||
expect( 10 );
|
||||
|
||||
var element = $( "#calendar" );
|
||||
|
||||
function step1() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar
|
||||
.focusGrid( element )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2013, 12 - 1, 31 ),
|
||||
"Keystroke left to switch to previous day"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step2();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step2() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2014, 1 - 1, 2 ),
|
||||
"Keystroke right to switch to next day"
|
||||
);
|
||||
step3();
|
||||
}
|
||||
|
||||
function step3() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2013, 12 - 1, 25 ),
|
||||
"Keystroke up to move to the previous week"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step4();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step4() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2014, 1 - 1, 8 ),
|
||||
"Keystroke down to move to the next week"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step5();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step5() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2013, 12 - 1, 1 ),
|
||||
"Keystroke Page Up moves date to previous month"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step6();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step6() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2013, 1 - 1, 1 ),
|
||||
"Keystroke Page Up + ALT moves date to previous year"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step7();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step7() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2014, 2 - 1, 1 ),
|
||||
"Keystroke Page Down moves date to next month"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step8();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step8() {
|
||||
element.calendar({ value: new Date( 2014, 1 - 1, 1 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2015, 1 - 1, 1 ),
|
||||
"Keystroke Page Down + ALT moves date to next year"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step9();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
// Check for moving to short months
|
||||
function step9() {
|
||||
element.calendar({ value: new Date( 2014, 3 - 1, 31 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2014, 2 - 1, 28 ),
|
||||
"Keystroke Page Up and short months"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
step10();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step10() {
|
||||
element.calendar({ value: new Date( 2016, 1 - 1, 30 ) });
|
||||
|
||||
TestHelpers.calendar.focusGrid( element ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2016, 2 - 1, 29 ),
|
||||
"Keystroke Page Down and leap years"
|
||||
);
|
||||
element.calendar( "destroy" );
|
||||
start();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
step1();
|
||||
});
|
||||
|
||||
asyncTest( "mouse", function() {
|
||||
expect( 6 );
|
||||
|
||||
var element = $( "#calendar" ).calendar(),
|
||||
date = new Date();
|
||||
|
||||
function step1() {
|
||||
$( "tbody a:contains(10)", element ).simulate( "mousedown" );
|
||||
date.setDate( 10 );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
date,
|
||||
"Mouse click"
|
||||
);
|
||||
|
||||
element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
|
||||
$( ".ui-calendar-calendar tbody a:contains(12)", element ).simulate( "mousedown" );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2008, 2 - 1, 12 ),
|
||||
"Mouse click - preset"
|
||||
);
|
||||
|
||||
// Previous/next
|
||||
element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
|
||||
$( ".ui-calendar-prev", element ).simulate( "click" );
|
||||
$( ".ui-calendar-calendar tbody a:contains(16)", element ).simulate( "mousedown" );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2008, 1 - 1, 16 ),
|
||||
"Mouse click - previous"
|
||||
);
|
||||
|
||||
element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) );
|
||||
$( ".ui-calendar-next", element ).simulate( "click" );
|
||||
$( ".ui-calendar-calendar tbody a:contains(18)", element ).simulate( "mousedown" );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2008, 3 - 1, 18 ),
|
||||
"Mouse click - next"
|
||||
);
|
||||
|
||||
step2();
|
||||
}
|
||||
|
||||
// Previous/next with minimum/maximum
|
||||
function step2() {
|
||||
element.calendar( "destroy" );
|
||||
element.calendar({
|
||||
value: new Date( 2008, 3 - 1, 4),
|
||||
min: new Date( 2008, 2 - 1, 2 ),
|
||||
max: new Date( 2008, 2 - 1, 26 )
|
||||
});
|
||||
|
||||
$( ".ui-calendar-prev", element ).simulate( "click" );
|
||||
$( "tbody a:contains(16)", element ).simulate( "mousedown" );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2008, 2 - 1, 16 ),
|
||||
"Mouse click - previous + min/max"
|
||||
);
|
||||
step3();
|
||||
}
|
||||
|
||||
function step3() {
|
||||
element.calendar( "destroy" );
|
||||
element.calendar({
|
||||
value: new Date( 2008, 1 - 1, 4),
|
||||
min: new Date( 2008, 2 - 1, 2 ),
|
||||
max: new Date( 2008, 2 - 1, 26 )
|
||||
});
|
||||
|
||||
$( ".ui-calendar-next", element ).simulate( "click" );
|
||||
$( "tbody a:contains(18)", element ).simulate( "mousedown" );
|
||||
TestHelpers.calendar.equalsDate(
|
||||
element.calendar( "valueAsDate" ),
|
||||
new Date( 2008, 2 - 1, 18 ),
|
||||
"Mouse click - next + min/max"
|
||||
);
|
||||
start();
|
||||
}
|
||||
|
||||
step1();
|
||||
});
|
||||
|
||||
})( jQuery );
|
0
tests/unit/calendar/calendar_events.js
Normal file
0
tests/unit/calendar/calendar_events.js
Normal file
71
tests/unit/calendar/calendar_methods.js
Normal file
71
tests/unit/calendar/calendar_methods.js
Normal file
@ -0,0 +1,71 @@
|
||||
(function( $ ) {
|
||||
|
||||
module( "calendar: methods" );
|
||||
|
||||
test( "destroy", function() {
|
||||
expect( 1 );
|
||||
|
||||
domEqual( "#calendar", function() {
|
||||
$( "#calendar" ).calendar().calendar( "destroy" );
|
||||
});
|
||||
});
|
||||
|
||||
test( "enable / disable", function() {
|
||||
expect( 6 );
|
||||
|
||||
var element = $( "#calendar" ).calendar();
|
||||
|
||||
ok( !element.calendar( "option", "disabled" ), "initially enabled" );
|
||||
ok( !element.hasClass( "ui-calendar-disabled" ), "does not have disabled class name" );
|
||||
|
||||
element.calendar( "disable" );
|
||||
ok( element.calendar( "option", "disabled" ), "disabled option is set" );
|
||||
ok( element.hasClass( "ui-calendar-disabled" ), "calendar has disabled class name" );
|
||||
|
||||
element.calendar( "enable" );
|
||||
ok( !element.calendar( "option", "disabled" ), "enabled after enable() call" );
|
||||
ok( !element.hasClass( "ui-calendar-disabled" ), "no longer has disabled class name" );
|
||||
});
|
||||
|
||||
test( "widget", function() {
|
||||
expect( 1 );
|
||||
|
||||
var element = $( "#calendar" ).calendar(),
|
||||
widget = element.calendar( "widget" );
|
||||
|
||||
strictEqual( widget[ 0 ], element[ 0 ] );
|
||||
});
|
||||
|
||||
test( "value", function() {
|
||||
expect( 3 );
|
||||
var element = $( "#calendar" ).calendar();
|
||||
|
||||
element.calendar( "value", "1/1/14" );
|
||||
ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" );
|
||||
equal( element.calendar( "value" ), "1/1/14", "getter" );
|
||||
|
||||
element.calendar( "value", "abc" );
|
||||
equal( element.calendar( "value" ), "1/1/14", "Setting invalid values should be ignored." );
|
||||
});
|
||||
|
||||
test( "valueAsDate", function() {
|
||||
expect( 4 );
|
||||
|
||||
var element = $( "#calendar" ).calendar(),
|
||||
date1 = new Date( 2008, 6 - 1, 4 ),
|
||||
date2 = new Date();
|
||||
|
||||
element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) );
|
||||
ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "First day marked as selected" );
|
||||
TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
|
||||
|
||||
element.calendar( "destroy" );
|
||||
|
||||
element.calendar();
|
||||
TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), date2, "Set date - default" );
|
||||
|
||||
element.calendar( "valueAsDate", date1 );
|
||||
TestHelpers.calendar.equalsDate(element.calendar( "valueAsDate" ), date1, "Set date - 2008-06-04" );
|
||||
});
|
||||
|
||||
})( jQuery );
|
175
tests/unit/calendar/calendar_options.js
Normal file
175
tests/unit/calendar/calendar_options.js
Normal file
@ -0,0 +1,175 @@
|
||||
(function( $ ) {
|
||||
|
||||
module( "calendar: options" );
|
||||
|
||||
test( "dateFormat", function() {
|
||||
expect( 2 );
|
||||
var element = $( "#calendar" ).calendar({
|
||||
value: "1/1/14"
|
||||
}),
|
||||
firstDayLink = element.calendar( "widget" ).find( "td[id]:first a" );
|
||||
|
||||
firstDayLink.trigger( "mousedown" );
|
||||
equal( element.calendar( "value" ), "1/1/14", "default formatting" );
|
||||
|
||||
element.calendar( "option", "dateFormat", { date: "full" } );
|
||||
equal( element.calendar( "value" ), "Wednesday, January 1, 2014", "updated formatting" );
|
||||
});
|
||||
|
||||
test( "eachDay", function() {
|
||||
expect( 5 );
|
||||
var timestamp,
|
||||
input = $( "#calendar" ).calendar(),
|
||||
picker = input.calendar( "widget" ),
|
||||
firstCell = picker.find( "td[id]:first" );
|
||||
|
||||
equal( firstCell.find( "a" ).length, 1, "days are selectable by default" );
|
||||
timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 );
|
||||
equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" );
|
||||
|
||||
// Do not render the 1st of the month
|
||||
input.calendar( "option", "eachDay", function( day ) {
|
||||
if ( day.date === 1 ) {
|
||||
day.render = false;
|
||||
}
|
||||
});
|
||||
firstCell = picker.find( "td[id]:first" );
|
||||
timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 );
|
||||
equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" );
|
||||
|
||||
// Display the 1st of the month but make it not selectable.
|
||||
input.calendar( "option", "eachDay", function( day ) {
|
||||
if ( day.date === 1 ) {
|
||||
day.selectable = false;
|
||||
}
|
||||
});
|
||||
firstCell = picker.find( "td[id]:first" );
|
||||
equal( firstCell.find( "a" ).length, 0, "the 1st is not selectable" );
|
||||
|
||||
input.calendar( "option", "eachDay", function( day ) {
|
||||
if ( day.date === 1 ) {
|
||||
day.extraClasses = "ui-custom";
|
||||
}
|
||||
});
|
||||
ok( picker.find( "td[id]:first a" ).hasClass( "ui-custom" ), "extraClasses applied" );
|
||||
|
||||
input.calendar( "destroy" );
|
||||
});
|
||||
|
||||
test( "showWeek", function() {
|
||||
expect( 7 );
|
||||
var input = $( "#calendar" ).calendar(),
|
||||
container = input.calendar( "widget" );
|
||||
|
||||
equal( container.find( "thead th" ).length, 7, "just 7 days, no column cell" );
|
||||
equal( container.find( ".ui-calendar-week-col" ).length, 0,
|
||||
"no week column cells present" );
|
||||
input.calendar( "destroy" );
|
||||
|
||||
input = $( "#calendar" ).calendar({ showWeek: true });
|
||||
container = input.calendar( "widget" );
|
||||
equal( container.find( "thead th" ).length, 8, "7 days + a column cell" );
|
||||
ok( container.find( "thead th:first" ).is( ".ui-calendar-week-col" ),
|
||||
"first cell should have ui-datepicker-week-col class name" );
|
||||
equal( container.find( ".ui-calendar-week-col" ).length,
|
||||
container.find( "tr" ).length, "one week cell for each week" );
|
||||
input.calendar( "destroy" );
|
||||
|
||||
input = $( "#calendar" ).calendar();
|
||||
container = input.calendar( "widget" );
|
||||
equal( container.find( "thead th" ).length, 7, "no week column" );
|
||||
input.calendar( "option", "showWeek", true );
|
||||
equal( container.find( "thead th" ).length, 8, "supports changing option after init" );
|
||||
});
|
||||
|
||||
test( "min / max", function() {
|
||||
expect( 0 );
|
||||
});
|
||||
|
||||
/*
|
||||
// TODO: Move this to $.date, Globalize or calendar widget
|
||||
test( "daylightSaving", function() {
|
||||
expect( 25 );
|
||||
var inp = TestHelpers.calendar.init( "#inp" ),
|
||||
dp = $( "#ui-datepicker-div" );
|
||||
ok(true, "Daylight saving - " + new Date());
|
||||
// Australia, Sydney - AM change, southern hemisphere
|
||||
inp.val( "04/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "04/05/2008", "Daylight saving - Australia 04/05/2008" );
|
||||
inp.val( "04/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "04/06/2008", "Daylight saving - Australia 04/06/2008" );
|
||||
inp.val( "04/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "04/07/2008", "Daylight saving - Australia 04/07/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/04/2008", "Daylight saving - Australia 10/04/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/05/2008", "Daylight saving - Australia 10/05/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/06/2008", "Daylight saving - Australia 10/06/2008" );
|
||||
// Brasil, Brasilia - midnight change, southern hemisphere
|
||||
inp.val( "02/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(20) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "02/16/2008", "Daylight saving - Brasil 02/16/2008" );
|
||||
inp.val( "02/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(21) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "02/17/2008", "Daylight saving - Brasil 02/17/2008" );
|
||||
inp.val( "02/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(22) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "02/18/2008", "Daylight saving - Brasil 02/18/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/11/2008", "Daylight saving - Brasil 10/11/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/12/2008", "Daylight saving - Brasil 10/12/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/13/2008", "Daylight saving - Brasil 10/13/2008" );
|
||||
// Lebanon, Beirut - midnight change, northern hemisphere
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(34) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/29/2008", "Daylight saving - Lebanon 03/29/2008" );
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(35) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/30/2008", "Daylight saving - Lebanon 03/30/2008" );
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(36) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/31/2008", "Daylight saving - Lebanon 03/31/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(27) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/25/2008", "Daylight saving - Lebanon 10/25/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(28) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/26/2008", "Daylight saving - Lebanon 10/26/2008" );
|
||||
inp.val( "10/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(29) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "10/27/2008", "Daylight saving - Lebanon 10/27/2008" );
|
||||
// US, Eastern - AM change, northern hemisphere
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(13) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/08/2008", "Daylight saving - US 03/08/2008" );
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(14) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/09/2008", "Daylight saving - US 03/09/2008" );
|
||||
inp.val( "03/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(15) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "03/10/2008", "Daylight saving - US 03/10/2008" );
|
||||
inp.val( "11/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(6) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "11/01/2008", "Daylight saving - US 11/01/2008" );
|
||||
inp.val( "11/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(7) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "11/02/2008", "Daylight saving - US 11/02/2008" );
|
||||
inp.val( "11/01/2008" ).calendar( "show" );
|
||||
$( ".ui-calendar-calendar td:eq(8) a", dp).simulate( "click" );
|
||||
equal(inp.val(), "11/03/2008", "Daylight saving - US 11/03/2008" );
|
||||
});
|
||||
*/
|
||||
|
||||
})(jQuery);
|
22
tests/unit/calendar/calendar_test_helpers.js
Normal file
22
tests/unit/calendar/calendar_test_helpers.js
Normal file
@ -0,0 +1,22 @@
|
||||
TestHelpers.calendar = {
|
||||
addMonths: function( date, offset ) {
|
||||
var maxDay = 32 - new Date( date.getFullYear(), date.getMonth() + offset, 32 ).getDate();
|
||||
date.setDate( Math.min( date.getDate(), maxDay ) );
|
||||
date.setMonth( date.getMonth() + offset );
|
||||
return date;
|
||||
},
|
||||
equalsDate: function( d1, d2, message ) {
|
||||
if ( !d1 || !d2 ) {
|
||||
ok( false, message + " - missing date" );
|
||||
return;
|
||||
}
|
||||
d1 = new Date( d1.getFullYear(), d1.getMonth(), d1.getDate() );
|
||||
d2 = new Date( d2.getFullYear(), d2.getMonth(), d2.getDate() );
|
||||
equal( d1.toString(), d2.toString(), message );
|
||||
},
|
||||
focusGrid: function( element ) {
|
||||
element.find( "table:tabbable" ).simulate( "focus" );
|
||||
|
||||
return $( ":focus" );
|
||||
}
|
||||
};
|
@ -14,11 +14,12 @@
|
||||
<script src="../testsuite.js"></script>
|
||||
<script>
|
||||
TestHelpers.loadResources({
|
||||
css: [ "core", "datepicker" ],
|
||||
css: [ "core", "calendar", "datepicker" ],
|
||||
js: [
|
||||
"ui/core.js",
|
||||
"ui/widget.js",
|
||||
"ui/button.js",
|
||||
"ui/calendar.js",
|
||||
"ui/position.js",
|
||||
"ui/datepicker.js"
|
||||
]
|
||||
@ -39,10 +40,8 @@
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture">
|
||||
|
||||
|
||||
<input type="text" id="datepicker">
|
||||
<input type="text" id="datepicker2">
|
||||
<div id="inline"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
@ -1,7 +1,23 @@
|
||||
/*
|
||||
TestHelpers.commonWidgetTests( "datepicker", {
|
||||
defaults: {
|
||||
disabled: false
|
||||
appendTo: null,
|
||||
dateFormat: { date: "short" },
|
||||
disabled: false,
|
||||
eachDay: $.noop,
|
||||
numberOfMonths: 1,
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "left bottom"
|
||||
},
|
||||
show: true,
|
||||
showWeek: false,
|
||||
hide: true,
|
||||
|
||||
// callbacks
|
||||
beforeOpen: null,
|
||||
close: null,
|
||||
create: null,
|
||||
open: null,
|
||||
select: null
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
@ -12,213 +12,35 @@ test( "input's value determines starting date", function() {
|
||||
|
||||
input.datepicker( "open" );
|
||||
|
||||
equal( picker.find( ".ui-datepicker-month" ).html(), "January", "correct month displayed" );
|
||||
equal( picker.find( ".ui-datepicker-year" ).html(), "2014", "correct year displayed" );
|
||||
equal( picker.find( ".ui-state-focus" ).html(), "1", "correct day highlighted" );
|
||||
equal( picker.find( ".ui-calendar-month" ).html(), "January", "correct month displayed" );
|
||||
equal( picker.find( ".ui-calendar-year" ).html(), "2014", "correct year displayed" );
|
||||
equal( picker.find( ".ui-state-active" ).html(), "1", "correct day highlighted" );
|
||||
|
||||
input.val( "" ).datepicker( "destroy" );
|
||||
});
|
||||
|
||||
asyncTest( "baseStructure", function() {
|
||||
expect( 42 );
|
||||
var header, title, table, thead, week, panel, inl, child,
|
||||
inp = TestHelpers.datepicker.initNewInput(),
|
||||
dp = inp.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
asyncTest( "base structure", function() {
|
||||
expect( 5 );
|
||||
|
||||
function step1() {
|
||||
inp.focus();
|
||||
setTimeout(function() {
|
||||
ok( dp.is( ":visible" ), "Structure - datepicker visible" );
|
||||
ok( !dp.is( ".ui-datepicker-rtl" ), "Structure - not right-to-left" );
|
||||
ok( !dp.is( ".ui-datepicker-multi" ), "Structure - not multi-month" );
|
||||
equal( dp.children().length, 3, "Structure - child count (header, calendar, buttonpane)" );
|
||||
var input = TestHelpers.datepicker.initNewInput(),
|
||||
widget = input.datepicker( "widget" );
|
||||
|
||||
header = dp.children( ":first" );
|
||||
ok( header.is( "div.ui-datepicker-header" ), "Structure - header division" );
|
||||
equal( header.children().length, 3, "Structure - header child count" );
|
||||
ok( header.children( ":first" ).is( ".ui-datepicker-prev" ) && header.children( ":first" ).html() !== "", "Structure - prev link" );
|
||||
ok( header.children( ":eq(1)" ).is( ".ui-datepicker-next" ) && header.children( ":eq(1)" ).html() !== "", "Structure - next link" );
|
||||
input.focus();
|
||||
|
||||
title = header.children( ":last" ).children( ":first" );
|
||||
ok( title.is( "div.ui-datepicker-title" ) && title.html() !== "", "Structure - title division" );
|
||||
equal( title.children().length, 2, "Structure - title child count" );
|
||||
ok( title.children( ":first" ).is( "span.ui-datepicker-month" ) && title.children( ":first" ).text() !== "", "Structure - month text" );
|
||||
ok( title.children( ":last" ).is( "span.ui-datepicker-year" ) && title.children( ":last" ).text() !== "", "Structure - year text" );
|
||||
setTimeout(function() {
|
||||
ok( widget.is( ":visible" ), "Datepicker visible" );
|
||||
equal( widget.children().length, 3, "Child count" );
|
||||
ok( widget.is( ".ui-calendar" ), "Class ui-calendar" );
|
||||
ok( widget.is( ".ui-datepicker" ), "Class ui-datepicker" );
|
||||
ok( widget.is( ".ui-front" ), "Class ui-front" );
|
||||
|
||||
table = dp.children( ":eq(1)" );
|
||||
ok( table.is( "table.ui-datepicker-calendar" ), "Structure - month table" );
|
||||
ok( table.children( ":first" ).is( "thead" ), "Structure - month table thead" );
|
||||
|
||||
thead = table.children( ":first" ).children( ":first" );
|
||||
ok( thead.is( "tr" ), "Structure - month table title row" );
|
||||
equal( thead.find( "th" ).length, 7, "Structure - month table title cells" );
|
||||
ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure - month table body" );
|
||||
ok( table.children( ":eq(1)" ).children( "tr" ).length >= 4, "Structure - month table week count" );
|
||||
|
||||
week = table.children( ":eq(1)" ).children( ":first" );
|
||||
ok( week.is( "tr" ), "Structure - month table week row" );
|
||||
equal( week.children().length, 7, "Structure - week child count" );
|
||||
// TODO: Preserve these class names or let the user use :first-child and :last-child?
|
||||
// ok( week.children( ":first" ).is( "td.ui-datepicker-week-end" ), "Structure - month table first day cell" );
|
||||
// ok( week.children( ":last" ).is( "td.ui-datepicker-week-end" ), "Structure - month table second day cell" );
|
||||
|
||||
inp.datepicker( "close" ).datepicker( "destroy" );
|
||||
step2();
|
||||
}, 50 );
|
||||
}
|
||||
|
||||
function step2() {
|
||||
// Editable month/year and button panel
|
||||
inp = TestHelpers.datepicker.initNewInput({
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
showButtonPanel: true
|
||||
});
|
||||
dp = inp.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
inp.focus();
|
||||
setTimeout(function() {
|
||||
title = dp.find( "div.ui-datepicker-title" );
|
||||
// TODO: Re-add tests when changeMonth and changeYear are re-implemented
|
||||
//ok( title.children( ":first" ).is( "select.ui-datepicker-month" ), "Structure - month selector" );
|
||||
//ok( title.children( ":last" ).is( "select.ui-datepicker-year" ), "Structure - year selector" );
|
||||
|
||||
panel = dp.children( ":last" );
|
||||
ok( panel.is( "div.ui-datepicker-buttonpane" ), "Structure - button panel division" );
|
||||
equal( panel.children().length, 2, "Structure - button panel child count" );
|
||||
ok( panel.children( ":first" ).is( "button.ui-datepicker-current" ), "Structure - today button" );
|
||||
ok( panel.children( ":last" ).is( "button.ui-datepicker-close" ), "Structure - close button" );
|
||||
|
||||
inp.datepicker( "close" ).datepicker( "destroy" );
|
||||
step3();
|
||||
});
|
||||
}
|
||||
|
||||
function step3() {
|
||||
// Multi-month 2
|
||||
inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 2 } );
|
||||
dp = inp.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
inp.focus();
|
||||
setTimeout(function() {
|
||||
ok( dp.is( ".ui-datepicker-multi" ), "Structure multi [2] - multi-month" );
|
||||
equal( dp.children().length, 4, "Structure multi [2] - child count" );
|
||||
|
||||
child = dp.children( ":first" );
|
||||
// TODO: Implement ui-datepicker-group-first class name
|
||||
// ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2] - first month division" );
|
||||
|
||||
child = dp.children( ":eq(1)" );
|
||||
// TODO: Implement ui-datepicker-group-last class name
|
||||
// ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2] - second month division" );
|
||||
|
||||
child = dp.children( ":eq(2)" );
|
||||
ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2] - row break" );
|
||||
ok( dp.is( ".ui-datepicker-multi-2" ), "Structure multi [2] - multi-2" );
|
||||
|
||||
inp.datepicker( "close" ).datepicker( "destroy" );
|
||||
step4();
|
||||
});
|
||||
}
|
||||
|
||||
function step4() {
|
||||
// Multi-month 3
|
||||
inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: 3 } );
|
||||
dp = inp.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
inp.focus();
|
||||
setTimeout(function() {
|
||||
ok( dp.is( ".ui-datepicker-multi-3" ), "Structure multi [3] - multi-3" );
|
||||
ok( !dp.is( ".ui-datepicker-multi-2" ), "Structure multi [3] - Trac #6704" );
|
||||
|
||||
inp.datepicker( "close" ).datepicker( "destroy" );
|
||||
step5();
|
||||
});
|
||||
}
|
||||
|
||||
function step5() {
|
||||
// Multi-month [2, 2]
|
||||
inp = TestHelpers.datepicker.initNewInput({ numberOfMonths: [ 2, 2 ] } );
|
||||
dp = inp.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
inp.focus();
|
||||
setTimeout(function() {
|
||||
/*
|
||||
TODO: Re-add after array form of the numberOfMonths option is implemented.
|
||||
ok( dp.is( ".ui-datepicker-multi" ), "Structure multi - multi-month" );
|
||||
equal( dp.children().length, 6, "Structure multi [2,2] - child count" );
|
||||
|
||||
child = dp.children( ":first" );
|
||||
ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - first month division" );
|
||||
|
||||
child = dp.children( ":eq(1)" );
|
||||
ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - second month division" );
|
||||
|
||||
child = dp.children( ":eq(2)" );
|
||||
ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
|
||||
|
||||
child = dp.children( ":eq(3)" );
|
||||
ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure multi [2,2] - third month division" );
|
||||
|
||||
child = dp.children( ":eq(4)" );
|
||||
ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure multi [2,2] - fourth month division" );
|
||||
|
||||
child = dp.children( ":eq(5)" );
|
||||
ok( child.is( "div.ui-datepicker-row-break" ), "Structure multi [2,2] - row break" );
|
||||
*/
|
||||
inp.datepicker( "close" ).datepicker( "destroy" );
|
||||
step6();
|
||||
});
|
||||
}
|
||||
|
||||
function step6() {
|
||||
// Inline
|
||||
inl = TestHelpers.datepicker.init( "#inline" );
|
||||
dp = inl.children();
|
||||
|
||||
ok( dp.is( ".ui-datepicker-inline" ), "Structure inline - main div" );
|
||||
ok( !dp.is( ".ui-datepicker-rtl" ), "Structure inline - not right-to-left" );
|
||||
ok( !dp.is( ".ui-datepicker-multi" ), "Structure inline - not multi-month" );
|
||||
equal( dp.children().length, 3, "Structure inline - child count (header, calendar, buttonpane)" );
|
||||
|
||||
header = dp.children( ":first" );
|
||||
ok( header.is( "div.ui-datepicker-header" ), "Structure inline - header division" );
|
||||
equal( header.children().length, 3, "Structure inline - header child count" );
|
||||
|
||||
table = dp.children( ":eq(1)" );
|
||||
ok( table.is( "table.ui-datepicker-calendar" ), "Structure inline - month table" );
|
||||
ok( table.children( ":first" ).is( "thead" ), "Structure inline - month table thead" );
|
||||
ok( table.children( ":eq(1)" ).is( "tbody" ), "Structure inline - month table body" );
|
||||
|
||||
inl.datepicker( "destroy" );
|
||||
|
||||
step7();
|
||||
}
|
||||
|
||||
function step7() {
|
||||
// Inline multi-month
|
||||
inl = TestHelpers.datepicker.init( "#inline", { numberOfMonths: 2 } );
|
||||
dp = inl.datepicker( "widget" ).find( ".ui-datepicker" );
|
||||
|
||||
ok( dp.is( ".ui-datepicker-inline" ) && dp.is( ".ui-datepicker-multi" ), "Structure inline multi - main div" );
|
||||
equal( dp.children().length, 4, "Structure inline multi - child count" );
|
||||
|
||||
child = dp.children( ":first" );
|
||||
// TODO: Implement ui-datepicker-group-first class name
|
||||
// ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-first" ), "Structure inline multi - first month division" );
|
||||
|
||||
child = dp.children( ":eq(1)" );
|
||||
// TODO: Implement ui-datepicker-group-last class name
|
||||
// ok( child.is( "div.ui-datepicker-group" ) && child.is( "div.ui-datepicker-group-last" ), "Structure inline multi - second month division" );
|
||||
|
||||
child = dp.children( ":eq(2)" );
|
||||
ok( child.is( "div.ui-datepicker-row-break" ), "Structure inline multi - row break" );
|
||||
|
||||
inl.datepicker( "destroy" );
|
||||
input.datepicker( "close" );
|
||||
start();
|
||||
}
|
||||
|
||||
step1();
|
||||
}, 50 );
|
||||
});
|
||||
|
||||
asyncTest( "Keyboard handling: input", function() {
|
||||
expect( 9 );
|
||||
expect( 10 );
|
||||
var picker, instance,
|
||||
input = $( "#datepicker" ).datepicker();
|
||||
|
||||
@ -254,6 +76,15 @@ asyncTest( "Keyboard handling: input", function() {
|
||||
TestHelpers.datepicker.init( input );
|
||||
instance = input.datepicker( "instance" );
|
||||
|
||||
// Enter = Select preset date
|
||||
input
|
||||
.val( "1/1/14" )
|
||||
.datepicker( "refresh" )
|
||||
.datepicker( "open" )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
|
||||
"Keystroke enter - preset" );
|
||||
|
||||
input
|
||||
.val( "" )
|
||||
.datepicker( "open" );
|
||||
@ -290,174 +121,13 @@ asyncTest( "Keyboard handling: input", function() {
|
||||
step1();
|
||||
});
|
||||
|
||||
asyncTest( "keyboard handling: calendar", function() {
|
||||
expect( 7 );
|
||||
|
||||
var input = $( "#datepicker" );
|
||||
|
||||
function step1() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2013, 12 - 1, 31 ),
|
||||
"Keystroke left to switch to previous day"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step2();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
function step2() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.RIGHT } )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2014, 1 - 1, 2 ),
|
||||
"Keystroke right to switch to next day"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step3();
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
function step3() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2013, 12 - 1, 25 ),
|
||||
"Keystroke up to move to the previous week"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step4();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
function step4() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2014, 1 - 1, 8 ),
|
||||
"Keystroke down to move to the next week"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step5();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
function step5() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2014, 2 - 1, 1 ),
|
||||
"Keystroke Page Down moves date to next month"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step6();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
function step6() {
|
||||
input.val( "1/1/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2015, 1 - 1, 1 ),
|
||||
"Keystroke Page Down + Ctrl moves date to next year"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
step7();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
// Check for moving to short months
|
||||
function step7() {
|
||||
input.val( "3/31/14" );
|
||||
TestHelpers.datepicker.init( input );
|
||||
input.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
|
||||
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } );
|
||||
setTimeout(function() {
|
||||
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2014, 2 - 1, 28 ),
|
||||
"Keystroke Page Up and short months"
|
||||
);
|
||||
input.datepicker( "destroy" );
|
||||
start();
|
||||
}, 50 );
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
step1();
|
||||
// TODO: implement
|
||||
test( "ARIA", function() {
|
||||
expect( 0 );
|
||||
});
|
||||
|
||||
/*
|
||||
// TODO: Re-add tests if we implement a stepMonths option
|
||||
input.datepicker( "option", { stepMonths: 2, gotoCurrent: false } )
|
||||
.datepicker( "close" ).val( "02/04/2008" ).datepicker( "open" )
|
||||
.late( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2007, 12 - 1, 4 ),
|
||||
"Keystroke pgup step 2" );
|
||||
|
||||
input.val( "02/04/2008" ).datepicker( "open" )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } )
|
||||
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
|
||||
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 4 ),
|
||||
"Keystroke pgdn step 2" );
|
||||
*/
|
||||
|
||||
asyncTest( "mouse", function() {
|
||||
expect( 3 );
|
||||
expect( 4 );
|
||||
|
||||
var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ),
|
||||
picker = input.datepicker( "widget" );
|
||||
@ -465,23 +135,32 @@ asyncTest( "mouse", function() {
|
||||
input.datepicker( "open" );
|
||||
|
||||
setTimeout(function() {
|
||||
input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
|
||||
$( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2008, 4 - 1, 12 ),
|
||||
"Mouse click - preset"
|
||||
);
|
||||
|
||||
input.val( "" ).datepicker( "refresh" );
|
||||
input.simulate( "click" );
|
||||
strictEqual( input.datepicker( "valueAsDate" ), null, "Mouse click - close" );
|
||||
|
||||
input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" );
|
||||
input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
|
||||
input.simulate( "click" );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2008, 2 - 1, 4 ),
|
||||
new Date( 2008, 4 - 1, 4 ),
|
||||
"Mouse click - close + preset"
|
||||
);
|
||||
|
||||
input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" );
|
||||
input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" );
|
||||
picker.find( "a.ui-calendar-prev" ).simulate( "click" );
|
||||
input.simulate( "click" );
|
||||
TestHelpers.datepicker.equalsDate(
|
||||
input.datepicker( "valueAsDate" ),
|
||||
new Date( 2008, 2 - 1, 4 ),
|
||||
new Date( 2008, 4 - 1, 4 ),
|
||||
"Mouse click - abandoned"
|
||||
);
|
||||
|
||||
@ -490,3 +169,4 @@ asyncTest( "mouse", function() {
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
|
||||
|
@ -3,66 +3,43 @@
|
||||
module( "datepicker: methods" );
|
||||
|
||||
test( "destroy", function() {
|
||||
expect( 10 );
|
||||
var input = $( "#datepicker" ).datepicker(),
|
||||
inline = $( "#inline" ).datepicker();
|
||||
expect( 3 );
|
||||
|
||||
ok( input.datepicker( "instance" ), "instance created" );
|
||||
ok( input.attr( "aria-owns" ), "aria-owns attribute added" );
|
||||
ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" );
|
||||
input.datepicker( "destroy" );
|
||||
ok( !input.datepicker( "instance" ), "instance removed" );
|
||||
ok( !input.attr( "aria-owns" ), "aria-owns attribute removed" );
|
||||
ok( !input.attr( "aria-haspopup" ), "aria-haspopup attribute removed" );
|
||||
|
||||
ok( inline.datepicker( "instance" ), "instance created" );
|
||||
ok( inline.children().length > 0, "inline datepicker has children" );
|
||||
inline.datepicker( "destroy" );
|
||||
ok( !inline.datepicker( "instance" ), "instance removed" );
|
||||
ok( inline.children().length === 0, "inline picker no longer has children" );
|
||||
var input = $( "#datepicker" );
|
||||
domEqual( input, function() {
|
||||
input.datepicker();
|
||||
ok( input.attr( "aria-owns" ), "aria-owns attribute added" );
|
||||
ok( input.attr( "aria-haspopup" ), "aria-haspopup attribute added" );
|
||||
input.datepicker( "destroy" );
|
||||
});
|
||||
});
|
||||
|
||||
test( "enable / disable", function() {
|
||||
expect( 6 );
|
||||
var inl,
|
||||
inp = TestHelpers.datepicker.init( "#datepicker" ),
|
||||
dp = inp.datepicker( "widget" );
|
||||
|
||||
ok( !inp.datepicker( "option", "disabled" ), "initially enabled" );
|
||||
ok( !dp.hasClass( "ui-datepicker-disabled" ), "does not have disabled class name" );
|
||||
var input = TestHelpers.datepicker.init( "#datepicker" ),
|
||||
widget = input.datepicker( "widget" );
|
||||
|
||||
inp.datepicker( "disable" );
|
||||
ok( inp.datepicker( "option", "disabled" ), "disabled option is set" );
|
||||
ok( dp.hasClass( "ui-datepicker-disabled" ), "datepicker has disabled class name" );
|
||||
ok( !input.datepicker( "option", "disabled" ), "initially enabled" );
|
||||
ok( !widget.hasClass( "ui-datepicker-disabled" ), "does not have disabled class name" );
|
||||
|
||||
inp.datepicker( "enable" );
|
||||
ok( !inp.datepicker( "option", "disabled" ), "enabled after enable() call" );
|
||||
ok( !dp.hasClass( "ui-datepicker-disabled" ), "no longer has disabled class name" );
|
||||
input.datepicker( "disable" );
|
||||
ok( input.datepicker( "option", "disabled" ), "disabled option is set" );
|
||||
ok( widget.hasClass( "ui-datepicker-disabled" ), "datepicker has disabled class name" );
|
||||
|
||||
// Inline
|
||||
inl = TestHelpers.datepicker.init( "#inline" );
|
||||
dp = inl.datepicker( "instance" );
|
||||
|
||||
// TODO: Disabling inline pickers does not work.
|
||||
// TODO: When changeMonth and changeYear options are implemented ensure their dropdowns
|
||||
// are properly disabled when in an inline picker.
|
||||
input.datepicker( "enable" );
|
||||
ok( !input.datepicker( "option", "disabled" ), "enabled after enable() call" );
|
||||
ok( !widget.hasClass( "ui-datepicker-disabled" ), "no longer has disabled class name" );
|
||||
});
|
||||
|
||||
test( "widget", function() {
|
||||
expect( 1 );
|
||||
|
||||
var actual = $( "#datepicker" ).datepicker().datepicker( "widget" );
|
||||
deepEqual( $( "body > .ui-front" )[ 0 ], actual[ 0 ] );
|
||||
actual.remove();
|
||||
});
|
||||
|
||||
test( "close", function() {
|
||||
expect( 0 );
|
||||
});
|
||||
|
||||
test( "open", function() {
|
||||
expect( 0 );
|
||||
});
|
||||
|
||||
test( "value", function() {
|
||||
expect( 4 );
|
||||
|
||||
@ -77,7 +54,7 @@ test( "value", function() {
|
||||
equal( input.datepicker( "value" ), "1/1/14", "getter" );
|
||||
|
||||
input.val( "abc" );
|
||||
equal( input.datepicker( "value" ), "abc", "Invalid values should be returned without formatting." );
|
||||
strictEqual( input.datepicker( "value" ), null, "Invalid values should return null." );
|
||||
});
|
||||
|
||||
test( "valueAsDate", function() {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ TestHelpers.datepicker = {
|
||||
return $( id ).datepicker( options );
|
||||
},
|
||||
initNewInput: function( options ) {
|
||||
options = $.extend( { show: false }, options || {} );
|
||||
options = $.extend( { show: false, hide: false }, options || {} );
|
||||
return $( "<input>" ).datepicker( options )
|
||||
.appendTo( "#qunit-fixture" );
|
||||
},
|
||||
|
@ -39,6 +39,7 @@
|
||||
<ul>
|
||||
<li><a href="accordion/accordion.html">Accordion</a></li>
|
||||
<li><a href="autocomplete/autocomplete.html">Autocomplete</a></li>
|
||||
<li><a href="calendar/calendar.html">Calendar</a></li>
|
||||
<li><a href="button/button.html">Button</a></li>
|
||||
<li><a href="datepicker/datepicker.html">Datepicker</a></li>
|
||||
<li><a href="dialog/dialog.html">Dialog</a></li>
|
||||
|
@ -13,6 +13,7 @@
|
||||
@import url("accordion.css");
|
||||
@import url("autocomplete.css");
|
||||
@import url("button.css");
|
||||
@import url("calendar.css");
|
||||
@import url("datepicker.css");
|
||||
@import url("dialog.css");
|
||||
@import url("draggable.css");
|
||||
|
178
themes/base/calendar.css
Normal file
178
themes/base/calendar.css
Normal file
@ -0,0 +1,178 @@
|
||||
/*!
|
||||
* jQuery UI Calendar @VERSION
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright 2014 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/calendar/#theming
|
||||
*/
|
||||
.ui-calendar {
|
||||
width: 17em;
|
||||
padding: .2em .2em 0;
|
||||
}
|
||||
.ui-calendar .ui-calendar-header {
|
||||
position: relative;
|
||||
padding: .2em 0;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev,
|
||||
.ui-calendar .ui-calendar-next {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
width: 19px;
|
||||
height: 18px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev:not(.ui-state-hover):not(.ui-state-focus),
|
||||
.ui-calendar .ui-calendar-next:not(.ui-state-hover):not(.ui-state-focus) {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev-hover,
|
||||
.ui-calendar .ui-calendar-next-hover {
|
||||
top: 1px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev {
|
||||
left: 2px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-next {
|
||||
right: 2px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev-hover {
|
||||
left: 1px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-next-hover {
|
||||
right: 1px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-prev .ui-icon,
|
||||
.ui-calendar .ui-calendar-next .ui-icon {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-calendar .ui-calendar-title {
|
||||
line-height: 1.8em;
|
||||
text-align: center;
|
||||
}
|
||||
.ui-calendar .ui-calendar-title select {
|
||||
font-size: 1em;
|
||||
margin: 1px 0;
|
||||
}
|
||||
.ui-calendar select.ui-calendar-month,
|
||||
.ui-calendar select.ui-calendar-year {
|
||||
width: 49%;
|
||||
}
|
||||
.ui-calendar table {
|
||||
width: 100%;
|
||||
font-size: .9em;
|
||||
border-collapse: collapse;
|
||||
margin: 0 0 .4em;
|
||||
}
|
||||
.ui-calendar th {
|
||||
padding: .7em .3em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border: 0;
|
||||
}
|
||||
.ui-calendar td {
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
}
|
||||
.ui-calendar td span,
|
||||
.ui-calendar td a {
|
||||
display: block;
|
||||
padding: .2em;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-calendar .ui-calendar-buttonpane {
|
||||
background-image: none;
|
||||
margin: .7em 0 0 0;
|
||||
padding: 0 .2em;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.ui-calendar .ui-calendar-buttonpane button {
|
||||
float: right;
|
||||
margin: .5em .2em .4em;
|
||||
cursor: pointer;
|
||||
padding: .2em .6em .3em .6em;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
.ui-calendar .ui-calendar-buttonpane button.ui-calendar-current {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-calendar.ui-calendar-multi {
|
||||
width: 100%;
|
||||
}
|
||||
.ui-calendar-multi .ui-calendar-group {
|
||||
float: left;
|
||||
}
|
||||
.ui-calendar-multi .ui-calendar-group table {
|
||||
width: 95%;
|
||||
margin: 0 auto .4em;
|
||||
}
|
||||
.ui-calendar-multi-2 .ui-calendar-group {
|
||||
width: 50%;
|
||||
}
|
||||
.ui-calendar-multi-3 .ui-calendar-group {
|
||||
width: 33.3%;
|
||||
}
|
||||
.ui-calendar-multi-4 .ui-calendar-group {
|
||||
width: 25%;
|
||||
}
|
||||
.ui-calendar-multi .ui-calendar-group-last .ui-calendar-header,
|
||||
.ui-calendar-multi .ui-calendar-group-middle .ui-calendar-header {
|
||||
border-left-width: 0;
|
||||
}
|
||||
.ui-calendar-multi .ui-calendar-buttonpane {
|
||||
clear: left;
|
||||
}
|
||||
.ui-calendar-row-break {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
/* RTL support */
|
||||
.ui-calendar-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-prev {
|
||||
right: 2px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-next {
|
||||
left: 2px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-prev:hover {
|
||||
right: 1px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-next:hover {
|
||||
left: 1px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-buttonpane {
|
||||
clear: right;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-buttonpane button {
|
||||
float: left;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-buttonpane button.ui-calendar-current,
|
||||
.ui-calendar-rtl .ui-calendar-group {
|
||||
float: right;
|
||||
}
|
||||
.ui-calendar-rtl .ui-calendar-group-last .ui-calendar-header,
|
||||
.ui-calendar-rtl .ui-calendar-group-middle .ui-calendar-header {
|
||||
border-right-width: 0;
|
||||
border-left-width: 1px;
|
||||
}
|
@ -9,172 +9,6 @@
|
||||
* http://api.jqueryui.com/datepicker/#theming
|
||||
*/
|
||||
.ui-datepicker {
|
||||
width: 17em;
|
||||
padding: .2em .2em 0;
|
||||
display: none;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-header {
|
||||
position: relative;
|
||||
padding: .2em 0;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev,
|
||||
.ui-datepicker .ui-datepicker-next {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
width: 19px;
|
||||
height: 18px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev:not(.ui-state-hover):not(.ui-state-focus),
|
||||
.ui-datepicker .ui-datepicker-next:not(.ui-state-hover):not(.ui-state-focus) {
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev-hover,
|
||||
.ui-datepicker .ui-datepicker-next-hover {
|
||||
top: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev {
|
||||
left: 2px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-next {
|
||||
right: 2px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev-hover {
|
||||
left: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-next-hover {
|
||||
right: 1px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-prev .ui-icon,
|
||||
.ui-datepicker .ui-datepicker-next .ui-icon {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -8px;
|
||||
top: 50%;
|
||||
margin-top: -8px;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-title {
|
||||
margin: 0 2.3em;
|
||||
line-height: 1.8em;
|
||||
text-align: center;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-title select {
|
||||
font-size: 1em;
|
||||
margin: 1px 0;
|
||||
}
|
||||
.ui-datepicker select.ui-datepicker-month,
|
||||
.ui-datepicker select.ui-datepicker-year {
|
||||
width: 45%;
|
||||
}
|
||||
.ui-datepicker table {
|
||||
width: 100%;
|
||||
font-size: .9em;
|
||||
border-collapse: collapse;
|
||||
margin: 0 0 .4em;
|
||||
}
|
||||
.ui-datepicker th {
|
||||
padding: .7em .3em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border: 0;
|
||||
}
|
||||
.ui-datepicker td {
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
}
|
||||
.ui-datepicker td span,
|
||||
.ui-datepicker td a {
|
||||
display: block;
|
||||
padding: .2em;
|
||||
text-align: right;
|
||||
text-decoration: none;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane {
|
||||
background-image: none;
|
||||
margin: .7em 0 0 0;
|
||||
padding: 0 .2em;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane button {
|
||||
float: right;
|
||||
margin: .5em .2em .4em;
|
||||
cursor: pointer;
|
||||
padding: .2em .6em .3em .6em;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* with multiple calendars */
|
||||
.ui-datepicker.ui-datepicker-multi {
|
||||
width: auto;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group {
|
||||
float: left;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group table {
|
||||
width: 95%;
|
||||
margin: 0 auto .4em;
|
||||
}
|
||||
.ui-datepicker-multi-2 .ui-datepicker-group {
|
||||
width: 50%;
|
||||
}
|
||||
.ui-datepicker-multi-3 .ui-datepicker-group {
|
||||
width: 33.3%;
|
||||
}
|
||||
.ui-datepicker-multi-4 .ui-datepicker-group {
|
||||
width: 25%;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
|
||||
.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
|
||||
border-left-width: 0;
|
||||
}
|
||||
.ui-datepicker-multi .ui-datepicker-buttonpane {
|
||||
clear: left;
|
||||
}
|
||||
.ui-datepicker-row-break {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
/* RTL support */
|
||||
.ui-datepicker-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-prev {
|
||||
right: 2px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-next {
|
||||
left: 2px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-prev:hover {
|
||||
right: 1px;
|
||||
left: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-next:hover {
|
||||
left: 1px;
|
||||
right: auto;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane {
|
||||
clear: right;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button {
|
||||
float: left;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
|
||||
.ui-datepicker-rtl .ui-datepicker-group {
|
||||
float: right;
|
||||
}
|
||||
.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
|
||||
.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
|
||||
border-right-width: 0;
|
||||
border-left-width: 1px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
497
ui/calendar.js
Normal file
497
ui/calendar.js
Normal file
@ -0,0 +1,497 @@
|
||||
/*!
|
||||
* jQuery UI Calendar @VERSION
|
||||
* http://jqueryui.com
|
||||
*
|
||||
* Copyright 2014 jQuery Foundation and other contributors
|
||||
* Released under the MIT license.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://api.jqueryui.com/calendar/
|
||||
*/
|
||||
(function( factory ) {
|
||||
if ( typeof define === "function" && define.amd ) {
|
||||
|
||||
// AMD. Register as an anonymous module.
|
||||
// TODO Add globalize and $.date
|
||||
define([
|
||||
"jquery",
|
||||
"./core",
|
||||
"./widget",
|
||||
"./button"
|
||||
], factory );
|
||||
} else {
|
||||
|
||||
// Browser globals
|
||||
factory( jQuery );
|
||||
}
|
||||
}(function( $ ) {
|
||||
|
||||
return $.widget( "ui.calendar", {
|
||||
version: "@VERSION",
|
||||
options: {
|
||||
dateFormat: { date: "short" },
|
||||
eachDay: $.noop,
|
||||
numberOfMonths: 1,
|
||||
showWeek: false,
|
||||
value: null,
|
||||
|
||||
// callbacks
|
||||
select: null
|
||||
},
|
||||
|
||||
_create: function() {
|
||||
this.id = this.element.uniqueId().attr( "id" );
|
||||
|
||||
this.date = $.date( this.options.value, this.options.dateFormat ).select();
|
||||
this.date.eachDay = this.options.eachDay;
|
||||
|
||||
this._on( this.element, {
|
||||
"click .ui-calendar-prev": function( event ) {
|
||||
event.preventDefault();
|
||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
||||
this.refresh();
|
||||
},
|
||||
"click .ui-calendar-next": function( event ) {
|
||||
event.preventDefault();
|
||||
this.date.adjust( "M", this.options.numberOfMonths );
|
||||
this.refresh();
|
||||
},
|
||||
"click .ui-calendar-current": function( event ) {
|
||||
event.preventDefault();
|
||||
this._select( event, new Date().getTime() );
|
||||
},
|
||||
"mousedown .ui-calendar-calendar a": function( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
// TODO Exclude clicks on lead days or handle them correctly
|
||||
// TODO Store/read more then just date, also required for multi month picker
|
||||
this._select( event, $( event.currentTarget ).data( "timestamp" ) );
|
||||
this.grid.focus();
|
||||
},
|
||||
"keydown .ui-calendar-calendar": "_handleKeydown"
|
||||
});
|
||||
|
||||
// TODO Use hoverable (no delegation support)? convert to _on?
|
||||
this.element.delegate( ".ui-calendar-header a, .ui-calendar-calendar a", "mouseenter.calendar mouseleave.calendar", function() {
|
||||
$( this ).toggleClass( "ui-state-hover" );
|
||||
});
|
||||
|
||||
this._createCalendar();
|
||||
},
|
||||
|
||||
_handleKeydown: function( event ) {
|
||||
var oldMonth = this.date.month(),
|
||||
oldYear = this.date.year();
|
||||
|
||||
// TODO: Handle for pickers with multiple months
|
||||
switch ( event.keyCode ) {
|
||||
case $.ui.keyCode.ENTER:
|
||||
this.element.find(
|
||||
"#" + this.grid.attr( "aria-activedescendant" ) + " > a:first"
|
||||
).mousedown();
|
||||
return;
|
||||
case $.ui.keyCode.PAGE_UP:
|
||||
this.date.adjust( event.altKey ? "Y" : "M", -1 );
|
||||
break;
|
||||
case $.ui.keyCode.PAGE_DOWN:
|
||||
this.date.adjust( event.altKey ? "Y" : "M", 1 );
|
||||
break;
|
||||
case $.ui.keyCode.END:
|
||||
this.date.setDay( this.date.daysInMonth() );
|
||||
break;
|
||||
case $.ui.keyCode.HOME:
|
||||
this.date.setDay( 1 );
|
||||
break;
|
||||
case $.ui.keyCode.LEFT:
|
||||
this.date.adjust( "D", -1 );
|
||||
break;
|
||||
case $.ui.keyCode.UP:
|
||||
this.date.adjust( "D", -7 );
|
||||
break;
|
||||
case $.ui.keyCode.RIGHT:
|
||||
this.date.adjust( "D", 1 );
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
this.date.adjust( "D", 7 );
|
||||
break;
|
||||
default:
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) {
|
||||
this.refresh();
|
||||
this.grid.focus();
|
||||
}
|
||||
|
||||
this._setActiveDescendant();
|
||||
},
|
||||
|
||||
_setActiveDescendant: function() {
|
||||
var id = this.id + "-" + this.date.day();
|
||||
|
||||
this.grid
|
||||
.attr( "aria-activedescendant", id )
|
||||
.find( ".ui-state-focus" )
|
||||
.removeClass( "ui-state-focus" );
|
||||
this.grid.find( "#" + id ).find ( "a" ).addClass( "ui-state-focus" );
|
||||
},
|
||||
|
||||
_createCalendar: function() {
|
||||
var classes = "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all",
|
||||
pickerHtml = "";
|
||||
|
||||
if ( this.options.numberOfMonths === 1 ) {
|
||||
pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons();
|
||||
} else {
|
||||
pickerHtml = this._buildMultiplePicker();
|
||||
classes += " ui-calendar-multi";
|
||||
}
|
||||
|
||||
this.element
|
||||
.addClass( classes )
|
||||
.attr({
|
||||
role: "region",
|
||||
"aria-labelledby": this.id + "-title"
|
||||
})
|
||||
.html( pickerHtml );
|
||||
|
||||
this.element.find( "button" ).button();
|
||||
|
||||
this.grid = this.element.find( ".ui-calendar-calendar" );
|
||||
},
|
||||
|
||||
_buildMultiplePicker: function() {
|
||||
var headerClass,
|
||||
html = "",
|
||||
currentDate = this.date,
|
||||
months = this.date.months( this.options.numberOfMonths - 1 ),
|
||||
i = 0;
|
||||
|
||||
for ( ; i < months.length; i++ ) {
|
||||
|
||||
// TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
|
||||
this.date = months[ i ];
|
||||
if ( months[ i ].first ) {
|
||||
headerClass = "ui-corner-left";
|
||||
} else if ( months[ i ].last ) {
|
||||
headerClass = "ui-corner-right";
|
||||
}
|
||||
|
||||
html += "<div class='ui-calendar-group'>" +
|
||||
"<div class='ui-calendar-header ui-widget-header ui-helper-clearfix " +
|
||||
headerClass + "'>";
|
||||
if ( months[ i ].first ) {
|
||||
html += this._buildPreviousLink();
|
||||
} else if ( months[ i ].last ) {
|
||||
html += this._buildNextLink();
|
||||
}
|
||||
|
||||
html += this._buildTitlebar() + "</div>" + this._buildGrid() + "</div>";
|
||||
}
|
||||
|
||||
html += "<div class='ui-calendar-row-break'></div>" + this._buildButtons();
|
||||
|
||||
this.date = currentDate;
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
_buildHeader: function() {
|
||||
return "<div class='ui-calendar-header ui-widget-header ui-helper-clearfix ui-corner-all'>" +
|
||||
this._buildPreviousLink() +
|
||||
this._buildNextLink() +
|
||||
this._buildTitlebar() +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
_buildPreviousLink: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<button class='ui-calendar-prev ui-corner-all' title='" + labels.prevText + "'>" +
|
||||
"<span class='ui-icon ui-icon-circle-triangle-w'>" +
|
||||
labels.prevText +
|
||||
"</span>" +
|
||||
"</button>";
|
||||
},
|
||||
|
||||
_buildNextLink: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<button class='ui-calendar-next ui-corner-all' title='" + labels.nextText + "'>" +
|
||||
"<span class='ui-icon ui-icon-circle-triangle-e'>" +
|
||||
labels.nextText +
|
||||
"</span>" +
|
||||
"</button>";
|
||||
},
|
||||
|
||||
_buildTitlebar: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<div role='header' id='" + this.id + "-title'>" +
|
||||
"<div id='" + this.id + "-month-label' class='ui-calendar-title'>" +
|
||||
this._buildTitle() +
|
||||
"</div>" +
|
||||
"<span class='ui-helper-hidden-accessible'>, " + labels.datePickerRole + "</span>" +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
_buildTitle: function() {
|
||||
return "<span class='ui-calendar-month'>" +
|
||||
this.date.monthName() +
|
||||
"</span> " +
|
||||
"<span class='ui-calendar-year'>" +
|
||||
this.date.year() +
|
||||
"</span>";
|
||||
},
|
||||
|
||||
_buildGrid: function() {
|
||||
return "<table class='ui-calendar-calendar' role='grid' aria-readonly='true' " +
|
||||
"aria-labelledby='" + this.id + "-month-label' tabindex='0' aria-activedescendant='" + this.id + "-" + this.date.day() + "'>" +
|
||||
this._buildGridHeading() +
|
||||
this._buildGridBody() +
|
||||
"</table>";
|
||||
},
|
||||
|
||||
_buildGridHeading: function() {
|
||||
var cells = "",
|
||||
i = 0,
|
||||
labels = Globalize.translate( "datepicker" ),
|
||||
weekDayLength = this.date.weekdays().length;
|
||||
|
||||
if ( this.options.showWeek ) {
|
||||
cells += "<th class='ui-calendar-week-col'>" + labels.weekHeader + "</th>";
|
||||
}
|
||||
for ( ; i < weekDayLength; i++ ) {
|
||||
cells += this._buildGridHeaderCell( this.date.weekdays()[ i ] );
|
||||
}
|
||||
|
||||
return "<thead role='presentation'>" +
|
||||
"<tr role='row'>" + cells + "</tr>" +
|
||||
"</thead>";
|
||||
},
|
||||
|
||||
_buildGridHeaderCell: function( day ) {
|
||||
return "<th role='columnheader' abbr='" + day.fullname + "' aria-label='" + day.fullname + "'>" +
|
||||
"<span title='" + day.fullname + "'>" +
|
||||
day.shortname +
|
||||
"</span>" +
|
||||
"</th>";
|
||||
},
|
||||
|
||||
_buildGridBody: function() {
|
||||
|
||||
// this.date.days() needs caching as it has O(n^2) complexity.
|
||||
var days = this.date.days(),
|
||||
i = 0,
|
||||
rows = "";
|
||||
|
||||
for ( ; i < days.length; i++ ) {
|
||||
rows += this._buildWeekRow( days[ i ] );
|
||||
}
|
||||
|
||||
return "<tbody role='presentation'>" + rows + "</tbody>";
|
||||
},
|
||||
|
||||
_buildWeekRow: function( week ) {
|
||||
var cells = "",
|
||||
i = 0;
|
||||
|
||||
if ( this.options.showWeek ) {
|
||||
cells += "<td class='ui-calendar-week-col'>" + week.number + "</td>";
|
||||
}
|
||||
for ( ; i < week.days.length; i++ ) {
|
||||
cells += this._buildDayCell( week.days[ i ] );
|
||||
}
|
||||
|
||||
return "<tr role='row'>" + cells + "</tr>";
|
||||
},
|
||||
|
||||
_buildDayCell: function( day ) {
|
||||
var contents = "",
|
||||
attributes = [
|
||||
"aria-selected" + ( day.current ? "\"true\"" : "\"false\"" )
|
||||
];
|
||||
|
||||
if ( day.render ) {
|
||||
attributes.push( "id=\"" + this.id + "-" + day.date + "\"" );
|
||||
}
|
||||
|
||||
if ( day.selectable ) {
|
||||
attributes.push( "aria-disabled=\"true\"" );
|
||||
}
|
||||
|
||||
if ( day.render ) {
|
||||
if ( day.selectable ) {
|
||||
contents = this._buildDayLink( day );
|
||||
} else {
|
||||
contents = this._buildDayDisplay( day );
|
||||
}
|
||||
}
|
||||
|
||||
return "<td role='gridcell' " + attributes.join( " " ) + ">" +
|
||||
contents +
|
||||
"</td>";
|
||||
},
|
||||
|
||||
_buildDayLink: function( day ) {
|
||||
var link,
|
||||
classes = [ "ui-state-default" ],
|
||||
labels = Globalize.translate( "datepicker" );
|
||||
|
||||
if ( day === this.date ) {
|
||||
classes.push( "ui-state-focus" );
|
||||
}
|
||||
if ( day.current ) {
|
||||
classes.push( "ui-state-active" );
|
||||
}
|
||||
if ( day.today ) {
|
||||
classes.push( "ui-state-highlight" );
|
||||
}
|
||||
// TODO Explain and document this
|
||||
if ( day.extraClasses ) {
|
||||
classes.push( day.extraClasses.split( " " ) );
|
||||
}
|
||||
|
||||
link = "<a href='#' tabindex='-1' data-timestamp='" + day.timestamp +
|
||||
"' class='" + classes.join( " " ) + "'>" + day.date + "</a>";
|
||||
if ( day.today ) {
|
||||
link += "<span class='ui-helper-hidden-accessible'>, " +
|
||||
labels.currentText + "</span>";
|
||||
}
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
_buildDayDisplay: function( day ) {
|
||||
var classes = [];
|
||||
|
||||
if ( day.current ) {
|
||||
classes.push( "ui-state-active" );
|
||||
}
|
||||
if ( day.today ) {
|
||||
classes.push( "ui-state-highlight" );
|
||||
}
|
||||
if ( day.extraClasses ) {
|
||||
classes.push( day.extraClasses.split( " " ) );
|
||||
}
|
||||
|
||||
return "<span class='" + classes.join( " " ) + "'>" + day.date + "</span>";
|
||||
},
|
||||
|
||||
_buildButtons: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<div class='ui-calendar-buttonpane ui-widget-content'>" +
|
||||
"<button class='ui-calendar-current'>" + labels.currentText + "</button>" +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
// Refreshing the entire calendar during interaction confuses screen readers, specifically
|
||||
// because the grid heading is marked up as a live region and will often not update if it's
|
||||
// destroyed and recreated instead of just having its text change. Additionally, interacting
|
||||
// with the prev and next links would cause loss of focus issues because the links being
|
||||
// interacted with will disappear while focused.
|
||||
refresh: function() {
|
||||
|
||||
// Determine which day gridcell to focus after refresh
|
||||
// TODO: Prevent disabled cells from being focused
|
||||
if ( this.options.numberOfMonths === 1 ) {
|
||||
this.grid = $( this._buildGrid() );
|
||||
this.element.find( ".ui-calendar-title" ).html( this._buildTitle() );
|
||||
this.element.find( ".ui-calendar-calendar" ).replaceWith( this.grid );
|
||||
} else {
|
||||
this._refreshMultiplePicker();
|
||||
}
|
||||
},
|
||||
|
||||
_refreshMultiplePicker: function() {
|
||||
var i = 0;
|
||||
|
||||
for ( ; i < this.options.numberOfMonths; i++ ) {
|
||||
this.element.find( ".ui-calendar-title" ).eq( i ).html( this._buildTitle() );
|
||||
this.element.find( ".ui-calendar-calendar" ).eq( i ).html( this._buildGrid() );
|
||||
this.date.adjust( "M", 1 );
|
||||
}
|
||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
||||
|
||||
// TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
|
||||
// to maintain the currently focused grid and base queries like this off of it.
|
||||
this.element.find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" );
|
||||
},
|
||||
|
||||
_setHiddenPicker: function() {
|
||||
this.element.attr({
|
||||
"aria-hidden": "true",
|
||||
"aria-expanded": "false"
|
||||
});
|
||||
},
|
||||
|
||||
_select: function( event, time ) {
|
||||
this._setOption( "value", new Date( time ) );
|
||||
this._trigger( "select", event, {
|
||||
|
||||
// TODO Replace with value option to initialise and read
|
||||
date: this.value()
|
||||
});
|
||||
},
|
||||
|
||||
value: function( value ) {
|
||||
if ( arguments.length ) {
|
||||
this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) );
|
||||
} else {
|
||||
return Globalize.format( this.option( "value" ), this.options.dateFormat );
|
||||
}
|
||||
},
|
||||
|
||||
valueAsDate: function( value ) {
|
||||
if ( arguments.length ) {
|
||||
this._setOption( "value", value );
|
||||
} else {
|
||||
return this.option( "value" );
|
||||
}
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
this.element
|
||||
.off( ".calendar" )
|
||||
.removeClass( "ui-calendar ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-calendar-multi" )
|
||||
.removeAttr( "role aria-labelledby" )
|
||||
.removeUniqueId()
|
||||
.empty();
|
||||
},
|
||||
|
||||
option: function( key ) {
|
||||
if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) {
|
||||
this.options.value = this.date.selectedDate();
|
||||
}
|
||||
|
||||
return this._superApply( arguments );
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
if ( key === "value" ) {
|
||||
if ( $.type( value ) === "date" ) {
|
||||
this.date.setTime( value.getTime() ).select();
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
this._super( key, value );
|
||||
|
||||
if ( key === "eachDay" ) {
|
||||
this.date.eachDay = this.options.eachDay;
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
if ( key === "dateFormat" ) {
|
||||
this.date.setFormat( this.options.dateFormat );
|
||||
}
|
||||
|
||||
if ( key === "showWeek" ) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}));
|
564
ui/datepicker.js
564
ui/datepicker.js
@ -21,7 +21,7 @@
|
||||
"jquery",
|
||||
"./core",
|
||||
"./widget",
|
||||
"./button",
|
||||
"./calendar",
|
||||
"./position"
|
||||
], factory );
|
||||
} else {
|
||||
@ -31,12 +31,13 @@
|
||||
}
|
||||
}(function( $ ) {
|
||||
|
||||
// TODO use uniqueId, if possible
|
||||
// TODO Use uniqueId, if possible
|
||||
var idIncrement = 0,
|
||||
// TODO Move this to the instance
|
||||
suppressExpandOnFocus = false;
|
||||
|
||||
$.widget( "ui.datepicker", {
|
||||
version: "@VERSION",
|
||||
options: {
|
||||
appendTo: null,
|
||||
dateFormat: { date: "short" },
|
||||
@ -50,7 +51,6 @@ $.widget( "ui.datepicker", {
|
||||
showWeek: false,
|
||||
show: true,
|
||||
hide: true,
|
||||
value: null,
|
||||
|
||||
// callbacks
|
||||
beforeOpen: null,
|
||||
@ -60,141 +60,38 @@ $.widget( "ui.datepicker", {
|
||||
},
|
||||
|
||||
_create: function() {
|
||||
this.id = "ui-datepicker-" + idIncrement;
|
||||
idIncrement++;
|
||||
this._createCalendar();
|
||||
},
|
||||
|
||||
if ( this.element.is( "input" ) ) {
|
||||
if ( !this.options.value && this.isValid() ) {
|
||||
this.options.value = this._getParsedValue();
|
||||
}
|
||||
this._createPicker();
|
||||
} else {
|
||||
this.inline = true;
|
||||
this.picker = this.element;
|
||||
}
|
||||
_createCalendar: function() {
|
||||
var that = this;
|
||||
|
||||
this.date = $.date( this.options.value, this.options.dateFormat ).select();
|
||||
this.date.eachDay = this.options.eachDay;
|
||||
this.calendar = $( "<div>" )
|
||||
.addClass( "ui-front ui-datepicker" )
|
||||
.appendTo( this._appendTo() );
|
||||
|
||||
this._on( this.picker, {
|
||||
"click .ui-datepicker-prev": function( event ) {
|
||||
event.preventDefault();
|
||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
||||
this.refresh();
|
||||
},
|
||||
"click .ui-datepicker-next": function( event ) {
|
||||
event.preventDefault();
|
||||
this.date.adjust( "M", this.options.numberOfMonths );
|
||||
this.refresh();
|
||||
},
|
||||
"click .ui-datepicker-current": function( event ) {
|
||||
event.preventDefault();
|
||||
this._select( event, new Date().getTime() );
|
||||
},
|
||||
"click .ui-datepicker-close": function( event ) {
|
||||
event.preventDefault();
|
||||
this.close( event );
|
||||
},
|
||||
"mousedown .ui-datepicker-calendar a": function( event ) {
|
||||
event.preventDefault();
|
||||
|
||||
// TODO Exclude clicks on lead days or handle them correctly
|
||||
// TODO Store/read more then just date, also required for multi month picker
|
||||
this._select( event, $( event.currentTarget ).data( "timestamp" ) );
|
||||
if ( this.inline ) {
|
||||
this.grid.focus();
|
||||
// Initialize calendar widget
|
||||
this.calendarInstance = this.calendar
|
||||
.calendar({
|
||||
dateFormat: this.options.dateFormat,
|
||||
eachDay: this.options.eachDay,
|
||||
numberOfMonths: this.options.numberOfMonths,
|
||||
showWeek: this.options.showWeek,
|
||||
value: this._getParsedValue(),
|
||||
select: function( event, data ) {
|
||||
that.element.val( data.date );
|
||||
that.close();
|
||||
that._focusTrigger();
|
||||
that._trigger( "select", event, data);
|
||||
}
|
||||
},
|
||||
"keydown .ui-datepicker-calendar": "_handleKeydown"
|
||||
});
|
||||
})
|
||||
.calendar( "instance" );
|
||||
|
||||
// TODO Use hoverable (no delegation support)? convert to _on?
|
||||
this.picker.delegate( ".ui-datepicker-header a, .ui-datepicker-calendar a", "mouseenter.datepicker mouseleave.datepicker", function() {
|
||||
$( this ).toggleClass( "ui-state-hover" );
|
||||
});
|
||||
|
||||
this._createTmpl();
|
||||
},
|
||||
|
||||
_handleKeydown: function( event ) {
|
||||
if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) {
|
||||
|
||||
// Only interested navigation keys
|
||||
return;
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
var newId, newCell,
|
||||
activeCell = $( "#" + this.grid.attr( "aria-activedescendant" ) ),
|
||||
oldMonth = this.date.month(),
|
||||
oldYear = this.date.year();
|
||||
|
||||
// TODO: Handle for pickers with multiple months
|
||||
switch ( event.keyCode ) {
|
||||
case $.ui.keyCode.ENTER:
|
||||
activeCell.children( "a:first" ).mousedown();
|
||||
return;
|
||||
case $.ui.keyCode.PAGE_UP:
|
||||
this.date.adjust( event.altKey ? "Y" : "M", -1 );
|
||||
break;
|
||||
case $.ui.keyCode.PAGE_DOWN:
|
||||
this.date.adjust( event.altKey ? "Y" : "M", 1 );
|
||||
break;
|
||||
case $.ui.keyCode.END:
|
||||
this.date.setDay( this.date.daysInMonth() );
|
||||
break;
|
||||
case $.ui.keyCode.HOME:
|
||||
this.date.setDay( 1 );
|
||||
break;
|
||||
case $.ui.keyCode.LEFT:
|
||||
this.date.adjust( "D", -1 );
|
||||
break;
|
||||
case $.ui.keyCode.UP:
|
||||
this.date.adjust( "D", -7 );
|
||||
break;
|
||||
case $.ui.keyCode.RIGHT:
|
||||
this.date.adjust( "D", 1 );
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
this.date.adjust( "D", 7 );
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if ( this.date.month() !== oldMonth || this.date.year() !== oldYear ) {
|
||||
this.refresh();
|
||||
this.grid.focus();
|
||||
} else {
|
||||
newId = this.id + "-" + this.date.day();
|
||||
newCell = $( "#" + newId );
|
||||
|
||||
// TODO Unnecessary optimization? is it really needed?
|
||||
if ( !newCell.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.grid.attr("aria-activedescendant", newId);
|
||||
|
||||
this.grid.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
|
||||
newCell.children( "a" ).addClass( "ui-state-focus" );
|
||||
}
|
||||
},
|
||||
|
||||
_createPicker: function() {
|
||||
this.picker = $( "<div>" )
|
||||
.addClass( "ui-front" )
|
||||
|
||||
// TODO Add a ui-datepicker-popup class, move position:absolute to that
|
||||
.css( "position", "absolute" )
|
||||
.uniqueId()
|
||||
.hide();
|
||||
this._setHiddenPicker();
|
||||
this.picker.appendTo( this._appendTo() );
|
||||
|
||||
this.element
|
||||
.attr( "aria-haspopup", "true" )
|
||||
.attr( "aria-owns", this.picker.attr( "id" ) );
|
||||
.attr( "aria-owns", this.calendar.attr( "id" ) );
|
||||
|
||||
this._on({
|
||||
keydown: function( event ) {
|
||||
@ -202,7 +99,7 @@ $.widget( "ui.datepicker", {
|
||||
case $.ui.keyCode.TAB:
|
||||
|
||||
// Waiting for close() will make popup hide too late, which breaks tab key behavior
|
||||
this.picker.hide();
|
||||
this.calendar.hide();
|
||||
this.close( event );
|
||||
break;
|
||||
case $.ui.keyCode.ESCAPE:
|
||||
@ -211,22 +108,22 @@ $.widget( "ui.datepicker", {
|
||||
}
|
||||
break;
|
||||
case $.ui.keyCode.ENTER:
|
||||
this._handleKeydown( event );
|
||||
this.calendarInstance._handleKeydown( event );
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
case $.ui.keyCode.UP:
|
||||
clearTimeout( this.closeTimer );
|
||||
this._delay( function() {
|
||||
this.open( event );
|
||||
this.grid.focus();
|
||||
this.calendarInstance.grid.focus();
|
||||
}, 1 );
|
||||
break;
|
||||
case $.ui.keyCode.HOME:
|
||||
if ( event.ctrlKey ) {
|
||||
this.date.setTime( new Date() );
|
||||
this.valueAsDate( new Date() );
|
||||
event.preventDefault();
|
||||
if ( this.isOpen ) {
|
||||
this.refresh();
|
||||
this.calendarInstance.refresh();
|
||||
} else {
|
||||
this.open( event );
|
||||
}
|
||||
@ -244,8 +141,7 @@ $.widget( "ui.datepicker", {
|
||||
}
|
||||
},
|
||||
keyup: function() {
|
||||
if ( this.isValid() && !this.inline ) {
|
||||
this.date.setTime( this._getParsedValue() ).select();
|
||||
if ( this.isValid() ) {
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
@ -275,7 +171,7 @@ $.widget( "ui.datepicker", {
|
||||
}
|
||||
});
|
||||
|
||||
this._on( this.picker, {
|
||||
this._on( this.calendar, {
|
||||
focusout: function( event ) {
|
||||
|
||||
// Use a timer to allow click to clear it and letting that
|
||||
@ -294,7 +190,7 @@ $.widget( "ui.datepicker", {
|
||||
|
||||
// TODO On TAB (or shift TAB), make sure it ends up on something useful in DOM order
|
||||
keyup: function( event ) {
|
||||
if ( event.keyCode === $.ui.keyCode.ESCAPE && this.picker.is( ":visible" ) ) {
|
||||
if ( event.keyCode === $.ui.keyCode.ESCAPE && this.calendar.is( ":visible" ) ) {
|
||||
this.close( event );
|
||||
this._focusTrigger();
|
||||
}
|
||||
@ -303,7 +199,7 @@ $.widget( "ui.datepicker", {
|
||||
|
||||
this._on( this.document, {
|
||||
click: function( event ) {
|
||||
if ( this.isOpen && !$( event.target ).closest( this.element.add( this.picker ) ).length ) {
|
||||
if ( this.isOpen && !$( event.target ).closest( this.element.add( this.calendar ) ).length ) {
|
||||
this.close( event );
|
||||
}
|
||||
}
|
||||
@ -319,7 +215,7 @@ $.widget( "ui.datepicker", {
|
||||
this.document.find( element ).eq( 0 );
|
||||
}
|
||||
|
||||
if ( !element ) {
|
||||
if ( !element || !element[ 0 ] ) {
|
||||
element = this.element.closest( ".ui-front" );
|
||||
}
|
||||
|
||||
@ -330,315 +226,33 @@ $.widget( "ui.datepicker", {
|
||||
return element;
|
||||
},
|
||||
|
||||
_createTmpl: function() {
|
||||
this._createDatepicker();
|
||||
this.picker.find( "button" ).button();
|
||||
|
||||
if ( this.inline ) {
|
||||
this.picker.children().addClass( "ui-datepicker-inline" );
|
||||
}
|
||||
|
||||
// Against display:none in datepicker.css
|
||||
this.picker.find( ".ui-datepicker" ).css( "display", "block" );
|
||||
this.grid = this.picker.find( ".ui-datepicker-calendar" );
|
||||
},
|
||||
|
||||
_createDatepicker: function() {
|
||||
var multiClasses = [],
|
||||
pickerHtml = "";
|
||||
|
||||
if (this.options.numberOfMonths === 1 ) {
|
||||
pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons();
|
||||
} else {
|
||||
pickerHtml = this._buildMultiplePicker();
|
||||
multiClasses.push( "ui-datepicker-multi" );
|
||||
multiClasses.push( "ui-datepicker-multi-" + this.options.numberOfMonths );
|
||||
}
|
||||
|
||||
$( "<div>" )
|
||||
.addClass( "ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" )
|
||||
.addClass( multiClasses.join( " " ) )
|
||||
.attr({
|
||||
role: "region",
|
||||
"aria-labelledby": this.id + "-title"
|
||||
})
|
||||
.html( pickerHtml )
|
||||
.appendTo( this.picker );
|
||||
},
|
||||
|
||||
_buildMultiplePicker: function() {
|
||||
var headerClass,
|
||||
html = "",
|
||||
currentDate = this.date,
|
||||
months = this.date.months( this.options.numberOfMonths - 1 ),
|
||||
i = 0;
|
||||
|
||||
for ( i; i < months.length; i++ ) {
|
||||
|
||||
// TODO Shouldn't we pass date as a parameter to build* fns instead of setting this.date?
|
||||
this.date = months[ i ];
|
||||
headerClass = months[ i ].first ? "ui-corner-left" :
|
||||
months[ i ].last ? "ui-corner-right" : "";
|
||||
|
||||
html += "<div class='ui-datepicker-group'>" +
|
||||
"<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix " + headerClass + "'>";
|
||||
if ( months[ i ].first ) {
|
||||
html += this._buildPreviousLink();
|
||||
}
|
||||
if ( months[ i ].last ) {
|
||||
html += this._buildNextLink();
|
||||
}
|
||||
|
||||
html += this._buildTitlebar();
|
||||
html += "</div>";
|
||||
html += this._buildGrid();
|
||||
html += "</div>";
|
||||
}
|
||||
|
||||
html += "<div class='ui-datepicker-row-break'></div>";
|
||||
html += this._buildButtons();
|
||||
|
||||
this.date = currentDate;
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
_buildHeader: function() {
|
||||
return "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix ui-corner-all'>" +
|
||||
this._buildPreviousLink() +
|
||||
this._buildNextLink() +
|
||||
this._buildTitlebar() +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
_buildPreviousLink: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<button class='ui-datepicker-prev ui-corner-all' " +
|
||||
"title='" + labels.prevText + "'>" +
|
||||
"<span class='ui-icon ui-icon-circle-triangle-w'>" +
|
||||
labels.prevText +
|
||||
"</span>" +
|
||||
"</button>";
|
||||
},
|
||||
|
||||
_buildNextLink: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<button class='ui-datepicker-next ui-corner-all' " +
|
||||
"title='" + labels.nextText + "'>" +
|
||||
"<span class='ui-icon ui-icon-circle-triangle-e'>" +
|
||||
labels.nextText +
|
||||
"</span>" +
|
||||
"</button>";
|
||||
},
|
||||
|
||||
_buildTitlebar: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<div role='header' id='" + this.id + "-title'>" +
|
||||
"<div id='" + this.id + "-month-lbl' class='ui-datepicker-title'>" +
|
||||
this._buildTitle() +
|
||||
"</div>" +
|
||||
"<span class='ui-helper-hidden-accessible'>, " + labels.datePickerRole + "</span>" +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
_buildTitle: function() {
|
||||
return "<span class='ui-datepicker-month'>" +
|
||||
this.date.monthName() +
|
||||
"</span> " +
|
||||
"<span class='ui-datepicker-year'>" +
|
||||
this.date.year() +
|
||||
"</span>";
|
||||
},
|
||||
|
||||
_buildGrid: function() {
|
||||
return "<table class='ui-datepicker-calendar' role='grid' aria-readonly='true' " +
|
||||
"aria-labelledby='" + this.id + "-month-lbl' tabindex='0' aria-activedescendant='" + this.id + "-" + this.date.day() + "'>" +
|
||||
this._buildGridHeading() +
|
||||
this._buildGridBody() +
|
||||
"</table>";
|
||||
},
|
||||
|
||||
_buildGridHeading: function() {
|
||||
var cells = "",
|
||||
i = 0,
|
||||
labels = Globalize.translate( "datepicker" );
|
||||
|
||||
if ( this.options.showWeek ) {
|
||||
cells += "<th class='ui-datepicker-week-col'>" + labels.weekHeader + "</th>";
|
||||
}
|
||||
for ( i; i < this.date.weekdays().length; i++ ) {
|
||||
cells += this._buildGridHeaderCell( this.date.weekdays()[i] );
|
||||
}
|
||||
|
||||
return "<thead role='presentation'>" +
|
||||
"<tr role='row'>" + cells + "</tr>" +
|
||||
"</thead>";
|
||||
},
|
||||
|
||||
_buildGridHeaderCell: function( day ) {
|
||||
return "<th role='columnheader' abbr='" + day.fullname + "' aria-label='" + day.fullname + "'>" +
|
||||
"<span title='" + day.fullname + "'>" +
|
||||
day.shortname +
|
||||
"</span>" +
|
||||
"</th>";
|
||||
},
|
||||
|
||||
_buildGridBody: function() {
|
||||
|
||||
// this.date.days() is not cached, and it has O(n^2) complexity. It is run O(n) times. So, it equals O(n^3). Not good at all. Caching.
|
||||
var days = this.date.days(),
|
||||
i = 0,
|
||||
rows = "";
|
||||
|
||||
for ( i; i < days.length; i++ ) {
|
||||
rows += this._buildWeekRow( days[ i ] );
|
||||
}
|
||||
|
||||
return "<tbody role='presentation'>" + rows + "</tbody>";
|
||||
},
|
||||
|
||||
_buildWeekRow: function( week ) {
|
||||
var cells = "",
|
||||
i = 0;
|
||||
|
||||
if ( this.options.showWeek ) {
|
||||
cells += "<td class='ui-datepicker-week-col'>" + week.number + "</td>";
|
||||
}
|
||||
for ( i; i < week.days.length; i++ ) {
|
||||
cells += this._buildDayCell( week.days[i] );
|
||||
}
|
||||
return "<tr role='row'>" + cells + "</tr>";
|
||||
},
|
||||
|
||||
_buildDayCell: function( day ) {
|
||||
var contents = "",
|
||||
idAttribute = day.render ? ( "id=" + this.id + "-" + day.date ) : "",
|
||||
ariaSelectedAttribute = "aria-selected=" + ( day.current ? "true" : "false" ),
|
||||
ariaDisabledAttribute = day.selectable ? "" : "aria-disabled=true";
|
||||
|
||||
if ( day.render ) {
|
||||
if ( day.selectable ) {
|
||||
contents = this._buildDayLink( day );
|
||||
} else {
|
||||
contents = this._buildDayDisplay( day );
|
||||
}
|
||||
}
|
||||
|
||||
return "<td role='gridcell' " + idAttribute + " " + ariaSelectedAttribute + " " + ariaDisabledAttribute + ">" +
|
||||
contents +
|
||||
"</td>";
|
||||
},
|
||||
|
||||
_buildDayLink: function( day ) {
|
||||
var link,
|
||||
classes = [ "ui-state-default" ],
|
||||
labels = Globalize.translate( "datepicker" );
|
||||
|
||||
if ( day.date === this.date.day() ) {
|
||||
classes.push( "ui-state-focus" );
|
||||
}
|
||||
if ( day.current ) {
|
||||
classes.push( "ui-state-active" );
|
||||
}
|
||||
if ( day.today ) {
|
||||
classes.push( "ui-state-highlight" );
|
||||
}
|
||||
if ( day.extraClasses ) {
|
||||
classes.push( day.extraClasses.split( " " ) );
|
||||
}
|
||||
|
||||
link = "<a href='#' tabindex='-1' data-timestamp='" + day.timestamp + "' class='" + classes.join( " " ) + "'>" +
|
||||
day.date + "</a>";
|
||||
if ( day.today ) {
|
||||
link += "<span class='ui-helper-hidden-accessible'>, " + labels.currentText + "</span>";
|
||||
}
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
_buildDayDisplay: function( day ) {
|
||||
var classes = [];
|
||||
|
||||
if ( day.current ) {
|
||||
classes.push( "ui-state-active" );
|
||||
}
|
||||
if ( day.today ) {
|
||||
classes.push( "ui-state-highlight" );
|
||||
}
|
||||
if ( day.extraClasses ) {
|
||||
classes.push( day.extraClasses.split( " " ) );
|
||||
}
|
||||
|
||||
return "<span class='" + classes.join( "" ) + "'>" + day.date + "</span>";
|
||||
},
|
||||
|
||||
_buildButtons: function() {
|
||||
var labels = Globalize.translate( "datepicker" );
|
||||
|
||||
return "<div class='ui-datepicker-buttonpane ui-widget-content'>" +
|
||||
"<button class='ui-datepicker-current'>" + labels.currentText + "</button>" +
|
||||
"<button class='ui-datepicker-close'>" + labels.closeText + "</button>" +
|
||||
"</div>";
|
||||
},
|
||||
|
||||
_focusTrigger: function() {
|
||||
suppressExpandOnFocus = true;
|
||||
this.element.focus();
|
||||
},
|
||||
|
||||
// Refreshing the entire datepicker during interaction confuses screen readers, specifically
|
||||
// because the grid heading is marked up as a live region and will often not update if it's
|
||||
// destroyed and recreated instead of just having its text change. Additionally, interacting
|
||||
// with the prev and next links would cause loss of focus issues because the links being
|
||||
// interacted with will disappear while focused.
|
||||
refresh: function() {
|
||||
|
||||
// Determine which day gridcell to focus after refresh
|
||||
// TODO: Prevent disabled cells from being focused
|
||||
if ( this.options.numberOfMonths === 1 ) {
|
||||
this.grid = $( this._buildGrid() );
|
||||
$( ".ui-datepicker-title", this.picker ).html( this._buildTitle() );
|
||||
$( ".ui-datepicker-calendar", this.picker ).replaceWith( this.grid );
|
||||
} else {
|
||||
this._refreshMultiplePicker();
|
||||
}
|
||||
},
|
||||
|
||||
_refreshMultiplePicker: function() {
|
||||
for ( var i = 0; i < this.options.numberOfMonths; i++ ) {
|
||||
$( ".ui-datepicker-title", this.picker ).eq( i ).html( this._buildTitle() );
|
||||
$( ".ui-datepicker-calendar", this.picker ).eq( i ).html( this._buildGrid() );
|
||||
this.date.adjust( "M", 1 );
|
||||
}
|
||||
|
||||
this.date.adjust( "M", -this.options.numberOfMonths );
|
||||
|
||||
// TODO: This assumes focus is on the first grid. For multi pickers, the widget needs
|
||||
// to maintain the currently focused grid and base queries like this off of it.
|
||||
$( this.picker ).find( ".ui-state-focus" ).not( ":first" ).removeClass( "ui-state-focus" );
|
||||
this.calendarInstance.option( "value", this._getParsedValue() );
|
||||
},
|
||||
|
||||
open: function( event ) {
|
||||
if ( this.inline || this.isOpen ) {
|
||||
if ( this.isOpen ) {
|
||||
return;
|
||||
}
|
||||
if ( this._trigger( "beforeOpen", event ) === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.refresh();
|
||||
this.calendarInstance.refresh();
|
||||
|
||||
this.picker
|
||||
this.calendar
|
||||
.attr( "aria-hidden", "false" )
|
||||
.attr( "aria-expanded", "true" )
|
||||
.show()
|
||||
.position( this._buildPosition() )
|
||||
.hide();
|
||||
|
||||
this._show( this.picker, this.options.show );
|
||||
this._show( this.calendar, this.options.show );
|
||||
|
||||
// Take trigger out of tab order to allow shift-tab to skip trigger
|
||||
// TODO Does this really make sense? related bug: tab-shift moves focus to last element on page
|
||||
@ -649,12 +263,8 @@ $.widget( "ui.datepicker", {
|
||||
},
|
||||
|
||||
close: function( event ) {
|
||||
if ( this.inline ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setHiddenPicker();
|
||||
this._hide( this.picker, this.options.hide );
|
||||
this._hide( this.calendar, this.options.hide );
|
||||
|
||||
this.element.attr( "tabindex" , 0 );
|
||||
|
||||
@ -663,7 +273,7 @@ $.widget( "ui.datepicker", {
|
||||
},
|
||||
|
||||
_setHiddenPicker: function() {
|
||||
this.picker
|
||||
this.calendar
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" );
|
||||
},
|
||||
@ -672,108 +282,66 @@ $.widget( "ui.datepicker", {
|
||||
return $.extend( { of: this.element }, this.options.position );
|
||||
},
|
||||
|
||||
_select: function( event, time ) {
|
||||
this._setOption( "value", new Date( time ) );
|
||||
if ( !this.inline ) {
|
||||
this.close();
|
||||
this._focusTrigger();
|
||||
}
|
||||
this._trigger( "select", event, {
|
||||
|
||||
// TODO Replace with value option to initialise and read
|
||||
date: this.value()
|
||||
});
|
||||
},
|
||||
|
||||
value: function( value ) {
|
||||
if ( arguments.length ) {
|
||||
this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) );
|
||||
} else {
|
||||
if ( this.inline ) {
|
||||
return Globalize.format( this.date.selected(), this.options.dateFormat );
|
||||
} else {
|
||||
return this.element.val();
|
||||
var date = Globalize.parseDate( value, this.options.dateFormat );
|
||||
if ( $.type( date ) === "date" ) {
|
||||
this.valueAsDate( date );
|
||||
this.element.val( value );
|
||||
}
|
||||
} else {
|
||||
return this._getParsedValue() ? this.element.val() : null;
|
||||
}
|
||||
},
|
||||
|
||||
valueAsDate: function( value ) {
|
||||
if ( arguments.length ) {
|
||||
this._setOption( "value", value );
|
||||
if ( $.type( value ) === "date" ) {
|
||||
this.calendarInstance.valueAsDate( value );
|
||||
this.element.val( Globalize.format( value, this.options.dateFormat ) );
|
||||
}
|
||||
} else {
|
||||
return this.option( "value" );
|
||||
return this._getParsedValue();
|
||||
}
|
||||
},
|
||||
|
||||
isValid: function() {
|
||||
if ( this.inline ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this._getParsedValue() !== null;
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
if ( this.inline ) {
|
||||
this.picker.empty();
|
||||
} else {
|
||||
this.picker.remove();
|
||||
this.element
|
||||
.removeAttr( "aria-haspopup" )
|
||||
.removeAttr( "aria-owns" );
|
||||
}
|
||||
this.calendarInstance.destroy();
|
||||
this.calendar.remove();
|
||||
this.element
|
||||
.removeAttr( "aria-haspopup" )
|
||||
.removeAttr( "aria-owns" );
|
||||
},
|
||||
|
||||
widget: function() {
|
||||
return this.picker;
|
||||
return this.calendar;
|
||||
},
|
||||
|
||||
_getParsedValue: function() {
|
||||
return Globalize.parseDate( this.element.val(), this.options.dateFormat );
|
||||
},
|
||||
|
||||
option: function( key ) {
|
||||
if ( arguments.length === 0 || ( arguments.length === 1 && key === "value" ) ) {
|
||||
this.options.value = this.inline ? this.date.selected() : this._getParsedValue();
|
||||
}
|
||||
return this._superApply( arguments );
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
if ( key === "value" ) {
|
||||
if ( $.type( value ) === "date" ) {
|
||||
this.date.setTime( value.getTime() ).select();
|
||||
this.refresh();
|
||||
if ( !this.inline ) {
|
||||
this.element.val( this.date.format() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._super( key, value );
|
||||
|
||||
if ( key === "appendTo" ) {
|
||||
this.picker.appendTo( this._appendTo() );
|
||||
if ( $.inArray( key, [ "showWeek", "numberOfMonths", "dateFormat", "eachDay", "min", "max" ] ) !== -1 ) {
|
||||
this.calendarInstance.option( key, value );
|
||||
}
|
||||
|
||||
if ( key === "eachDay" ) {
|
||||
this.date.eachDay = this.options.eachDay;
|
||||
this.refresh();
|
||||
if ( key === "appendTo" ) {
|
||||
this.calendar.appendTo( this._appendTo() );
|
||||
}
|
||||
|
||||
if ( key === "dateFormat" ) {
|
||||
this.date.setFormat( this.options.dateFormat );
|
||||
if ( !this.inline ) {
|
||||
this.element.val( this.date.format() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( key === "showWeek" ) {
|
||||
this.refresh();
|
||||
this.element.val( this.calendarInstance.value() );
|
||||
}
|
||||
|
||||
if ( key === "position" ) {
|
||||
this.picker.position( this._buildPosition() );
|
||||
this.calendar.position( this._buildPosition() );
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user