Datepicker: Introduce value option

Change status caching, fix existing value related methods, introduce
$.date construction with date object, selected property is null by
default, add selected getter
This commit is contained in:
Felix Nagel 2014-05-16 00:19:32 +02:00 committed by Scott González
parent a11e87c98e
commit 35b52a0dfc
4 changed files with 295 additions and 389 deletions

7
external/date.js vendored
View File

@ -26,9 +26,13 @@ $.date = function( date, globalFormat ) {
if ( typeof date === "string" && date.length ) {
this.dateObject = Globalize.parseDate( date, globalFormat );
}
if ( $.type( date ) === "date" ) {
this.dateObject = date;
}
this.dateObject = this.dateObject || new Date();
this.globalFormat = globalFormat;
this.selected = null;
};
$.date.prototype = {
@ -180,6 +184,9 @@ $.date.prototype = {
this.selected = this.clone();
return this;
},
selectedDate: function() {
return this.selected.date();
},
clone: function() {
var date = this.dateObject;
return new $.date( new Date( date.getFullYear(), date.getMonth(),

View File

@ -64,7 +64,7 @@ asyncTest( "baseStructure", function() {
inp.datepicker( "close" ).datepicker( "destroy" );
step2();
});
}, 50 );
}
function step2() {
@ -217,269 +217,223 @@ asyncTest( "baseStructure", function() {
step1();
});
test( "Keyboard handling", function() {
asyncTest( "Keyboard handling: input", function() {
expect( 9 );
var input = $( "#datepicker" ).datepicker(),
instance = input.datepicker( "instance" ),
date = new Date();
input.datepicker( "open" )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke enter" );
// Enter = Select today's date by default
input.val( "1/1/14" ).datepicker( "open" )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
"Keystroke enter - preset" );
// Control + Home = Change the calendar to the current month
input.val( "1/1/14" ).datepicker( "open" )
.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.HOME } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Keystroke ctrl+home" );
// Control + End = Close the calendar and clear the input
input.val( "1/1/14" ).datepicker( "open" )
.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.END } );
equal( input.val(), "", "Keystroke ctrl+end" );
input.val( "" ).datepicker( "open" );
ok( instance.isOpen, "datepicker is open before escape" );
input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
ok( !instance.isOpen, "escape closes the datepicker" );
input.val( "1/1/14" ).datepicker( "open" )
.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
"Keystroke esc - preset" );
input.val( "1/1/14" ).datepicker( "open" )
.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
"Keystroke esc - abandoned" );
input.val( "1/2/14" )
.simulate( "keyup" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ),
"Picker updated as user types into input" );
input.datepicker( "destroy" );
});
asyncTest( "keyboard handling", function() {
expect( 14 );
var picker,
input = $( "#datepicker" ),
date = new Date();
var picker, instance,
input = $( "#datepicker" ).datepicker();
function step1() {
input.datepicker();
TestHelpers.datepicker.init( input );
picker = input.datepicker( "widget" );
ok( !picker.is( ":visible" ), "datepicker closed" );
input.val( "" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
ok( !picker.is( ":visible" ), "datepicker closed" );
input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
ok( picker.is( ":visible" ), "Keystroke down opens datepicker" );
input.datepicker( "destroy" );
step2();
});
}, 100 );
}
function step2() {
input.datepicker();
TestHelpers.datepicker.init( input );
picker = input.datepicker( "widget" );
ok( !picker.is( ":visible" ), "datepicker closed" );
input.val( "" )
.simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
ok( !picker.is( ":visible" ), "datepicker closed" );
input.val( "" ).simulate( "keydown", { keyCode: $.ui.keyCode.UP } );
setTimeout(function() {
ok( picker.is( ":visible" ), "Keystroke up opens datepicker" );
input.datepicker( "destroy" );
step3();
});
}
function step3() {
input.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.LEFT } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2013, 12 - 1, 31 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke left to switch to previous day" );
input.datepicker( "destroy" );
step4();
}, 100 );
}
function step4() {
input.datepicker()
function step3() {
TestHelpers.datepicker.init( input );
instance = input.datepicker( "instance" );
input
.val( "" )
.datepicker( "open" );
ok( instance.isOpen, "datepicker is open before escape" );
input.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
ok( !instance.isOpen, "escape closes the datepicker" );
input
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
.datepicker( "open" )
.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
"Keystroke esc - preset" );
input
.val( "1/1/14" )
.datepicker( "open" )
.simulate( "keydown", { ctrlKey: true, keyCode: $.ui.keyCode.PAGE_UP } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ),
"Keystroke esc - abandoned" );
input
.val( "1/2/14" )
.simulate( "keyup" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 2 ),
"Picker updated as user types into input" );
input.datepicker( "destroy" );
start();
}
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 } );
date = new Date( 2014, 1 - 1, 2 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke right to switch to next day" );
TestHelpers.datepicker.equalsDate(
input.datepicker( "valueAsDate" ),
new Date( 2014, 1 - 1, 2 ),
"Keystroke right to switch to next day"
);
input.datepicker( "destroy" );
step5();
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.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
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 } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2013, 12 - 1, 25 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke up to move to the previous week" );
input.datepicker( "destroy" );
step6();
$( ":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.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
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 } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2014, 1 - 1, 8 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke down to move to the next week" );
input.datepicker( "destroy" );
step7();
}, 100 );
}
function step7() {
input.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2013, 12 - 1, 1 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Up moves date to previous month" );
input.datepicker( "destroy" );
step8();
}, 100 );
}
function step8() {
input.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_UP, altKey: true } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2013, 1 - 1, 1 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Up + Ctrl moves date to previous year" );
input.datepicker( "destroy" );
step9();
}, 100 );
}
function step9() {
input.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2014, 2 - 1, 1 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Down moves date to next month" );
input.datepicker( "destroy" );
step10();
}, 100 );
}
function step10() {
input.datepicker()
.val( "1/1/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN, altKey: true } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2015, 1 - 1, 1 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Down + Ctrl moves date to next year" );
input.datepicker( "destroy" );
step11();
$( ":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 step11() {
input.datepicker()
.val( "3/31/14" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
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 } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2014, 2 - 1, 28 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Up and short months" );
input.datepicker( "destroy" );
step12();
}, 100 );
}
function step12() {
input.datepicker()
.val( "1/30/16" )
.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } );
setTimeout(function() {
$( ":focus" )
.simulate( "keydown", { keyCode: $.ui.keyCode.PAGE_DOWN } )
.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } );
date = new Date( 2016, 2 - 1, 29 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date,
"Keystroke Page Down and leap years" );
input.datepicker( "destroy" );
start();
$( ":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 );
}
@ -502,110 +456,37 @@ asyncTest( "keyboard handling", function() {
"Keystroke pgdn step 2" );
*/
test( "mouse", function() {
expect( 13 );
var input = $( "#datepicker" ).datepicker(),
picker = input.datepicker( "widget" ),
inline = $( "#inline" ).datepicker,
date = new Date();
asyncTest( "mouse", function() {
expect( 3 );
input.val( "" ).datepicker( "open" );
$( ".ui-datepicker-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} );
date.setDate( 10 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click" );
var input = TestHelpers.datepicker.init( $( "#datepicker" ).val( "" ) ),
picker = input.datepicker( "widget" );
input.val( "2/4/08" ).datepicker( "open" );
$( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ),
"Mouse click - preset" ) ;
input.datepicker( "open" );
input.val( "" ).datepicker( "open" );
$( "button.ui-datepicker-close", picker ).simulate( "click", {} );
ok( input.datepicker( "valueAsDate" ) == null, "Mouse click - close" );
setTimeout(function() {
input.simulate( "click" );
strictEqual( input.datepicker( "valueAsDate" ), null, "Mouse click - close" );
input.val( "2/4/08" ).datepicker( "open" );
$( "button.ui-datepicker-close", picker ).simulate( "click", {} );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ),
"Mouse click - close + preset" );
input.val( "2/4/08" ).datepicker( "refresh" ).datepicker( "open" );
input.simulate( "click" );
TestHelpers.datepicker.equalsDate(
input.datepicker( "valueAsDate" ),
new Date( 2008, 2 - 1, 4 ),
"Mouse click - close + preset"
);
input.val( "2/4/08" ).datepicker( "open" );
$( "a.ui-datepicker-prev", picker ).simulate( "click", {} );
$( "button.ui-datepicker-close", picker ).simulate( "click", {} );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 4 ),
"Mouse click - abandoned" );
input.val( "2/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 ),
"Mouse click - abandoned"
);
// Current/previous/next
input.val( "" ).datepicker( "open" );
$( ".ui-datepicker-current", picker ).simulate( "click", {} );
date.setDate( new Date().getDate() );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date, "Mouse click - current" );
input.val( "2/4/08" ).datepicker( "open" );
$( ".ui-datepicker-prev", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ),
"Mouse click - previous" );
input.val( "2/4/08" ).datepicker( "open" );
$( ".ui-datepicker-next", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ),
"Mouse click - next" );
/*
// TODO: Re-add when min and max options are introduced.
// Previous/next with minimum/maximum
input.datepicker( "option", {
minDate: new Date( 2008, 2 - 1, 2 ),
maxDate: new Date( 2008, 2 - 1, 26 )
}).val( "2/4/08" ).datepicker( "open" );
$( ".ui-datepicker-prev", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ),
"Mouse click - previous + min/max" );
input.val( "2/4/08" ).datepicker( "open" );
$( ".ui-datepicker-next", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate(input.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ),
"Mouse click - next + min/max" );
*/
// Inline
inline = TestHelpers.datepicker.init( "#inline" );
picker = $( ".ui-datepicker-inline", inline );
date = new Date();
inline.datepicker( "valueAsDate", date );
$( ".ui-datepicker-calendar tbody a:contains(10)", picker ).simulate( "mousedown", {} );
date.setDate( 10 );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline" );
inline.datepicker( "option", { showButtonPanel: true } )
.datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4 ));
$( ".ui-datepicker-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ),
"Mouse click inline - preset" );
inline.datepicker( "option", { showButtonPanel: true } );
$( ".ui-datepicker-current", picker ).simulate( "click", {} );
$( ".ui-datepicker-calendar tbody a:contains(14)", picker ).simulate( "mousedown", {} );
date.setDate( 14 );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), date, "Mouse click inline - current" );
inline.datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4) );
$( ".ui-datepicker-prev", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(16)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ),
"Mouse click inline - previous" );
inline.datepicker( "valueAsDate", new Date( 2008, 2 - 1, 4) );
$( ".ui-datepicker-next", picker ).simulate( "click" );
$( ".ui-datepicker-calendar tbody a:contains(18)", picker ).simulate( "mousedown" );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ),
"Mouse click inline - next" );
input.datepicker( "destroy" );
inline.datepicker( "destroy" );
start();
}, 100 );
});
})( jQuery );

View File

@ -64,54 +64,43 @@ test( "open", function() {
});
test( "value", function() {
expect( 6 );
expect( 4 );
var input = $( "#datepicker" ).datepicker(),
picker = input.datepicker( "widget" ),
inline = $( "#inline" ).datepicker();
picker = input.datepicker( "widget" );
input.datepicker( "value", "1/1/14" );
equal( input.val(), "1/1/14", "input's value set" );
ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ),
"first day marked as selected" );
input.datepicker( "open" );
ok( picker.find( "a[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "first day marked as selected" );
equal( input.datepicker( "value" ), "1/1/14", "getter" );
input.val( "abc" );
equal( input.datepicker( "value" ), "abc",
"Invalid values should be returned without formatting." );
inline.datepicker( "value", "1/1/14" );
ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ),
"first day marked as selected" );
equal( inline.datepicker( "value" ), "1/1/14", "getter" );
input.datepicker( "destroy" );
inline.datepicker( "destroy" );
equal( input.datepicker( "value" ), "abc", "Invalid values should be returned without formatting." );
});
test( "valueAsDate", function() {
expect( 6 );
var input = $( "#datepicker" ).datepicker(),
var input = TestHelpers.datepicker.init( "#datepicker" ),
picker = input.datepicker( "widget" ),
inline = $( "#inline" ).datepicker();
date1 = new Date( 2008, 6 - 1, 4 );
input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) );
equal( input.val(), "1/1/14", "input's value set" );
ok( picker.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ),
"first day marked as selected" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ),
new Date( 2014, 0, 1 ), "getter" );
equal( input.val(), "1/1/14", "Input's value set" );
ok( picker.find( "a[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "First day marked as selected" );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" );
input.val( "a/b/c" );
equal( input.datepicker( "valueAsDate" ), null, "Invalid dates return null" );
inline.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) );
ok( inline.find( "a[data-timestamp]:first" ).hasClass( "ui-state-focus" ),
"first day marked as selected" );
TestHelpers.datepicker.equalsDate( inline.datepicker( "valueAsDate" ),
new Date( 2014, 0, 1 ), "getter" );
input.val( "" ).datepicker( "destroy" );
input = TestHelpers.datepicker.init( "#datepicker" );
input.datepicker( "destroy" );
inline.datepicker( "destroy" );
strictEqual( input.datepicker( "valueAsDate" ), null, "Set date - default" );
input.datepicker( "valueAsDate", date1 );
TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), date1, "Set date - 2008-06-04" );
});
test( "isValid", function() {

View File

@ -33,14 +33,14 @@
// TODO use uniqueId, if possible
var idIncrement = 0,
// TODO move this to the instance
// TODO Move this to the instance
suppressExpandOnFocus = false;
$.widget( "ui.datepicker", {
options: {
appendTo: null,
dateFormat: { date: "short" },
// TODO review
// TODO Review
eachDay: $.noop,
numberOfMonths: 1,
position: {
@ -50,6 +50,7 @@ $.widget( "ui.datepicker", {
showWeek: false,
show: true,
hide: true,
value: null,
// callbacks
beforeOpen: null,
@ -59,17 +60,22 @@ $.widget( "ui.datepicker", {
},
_create: function() {
this.date = $.date( null, this.options.dateFormat );
this.date.eachDay = this.options.eachDay;
this.id = "ui-datepicker-" + idIncrement;
idIncrement++;
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;
}
this.date = $.date( this.options.value, this.options.dateFormat ).select();
this.date.eachDay = this.options.eachDay;
this._on( this.picker, {
"click .ui-datepicker-prev": function( event ) {
event.preventDefault();
@ -91,8 +97,9 @@ $.widget( "ui.datepicker", {
},
"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
// 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();
@ -101,7 +108,7 @@ $.widget( "ui.datepicker", {
"keydown .ui-datepicker-calendar": "_handleKeydown"
});
// TODO use hoverable (no delegation support)? convert to _on?
// 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" );
});
@ -111,7 +118,8 @@ $.widget( "ui.datepicker", {
_handleKeydown: function( event ) {
if ( jQuery.inArray( event.keyCode, [ 13, 33, 34, 35, 36, 37, 38, 39, 40 ] ) === -1 ) {
//only interested navigation keys
// Only interested navigation keys
return;
}
event.preventDefault();
@ -161,7 +169,7 @@ $.widget( "ui.datepicker", {
newId = this.id + "-" + this.date.day();
newCell = $( "#" + newId );
// TODO unnecessary optimization? is it really needed?
// TODO Unnecessary optimization? is it really needed?
if ( !newCell.length ) {
return;
}
@ -176,7 +184,8 @@ $.widget( "ui.datepicker", {
_createPicker: function() {
this.picker = $( "<div>" )
.addClass( "ui-front" )
// TODO add a ui-datepicker-popup class, move position:absolte to that
// TODO Add a ui-datepicker-popup class, move position:absolute to that
.css( "position", "absolute" )
.uniqueId()
.hide();
@ -191,6 +200,7 @@ $.widget( "ui.datepicker", {
keydown: function( event ) {
switch ( event.keyCode ) {
case $.ui.keyCode.TAB:
// Waiting for close() will make popup hide too late, which breaks tab key behavior
this.picker.hide();
this.close( event );
@ -235,12 +245,12 @@ $.widget( "ui.datepicker", {
},
keyup: function() {
if ( this.isValid() && !this.inline ) {
this.date.setTime( this.element.val() ).select();
this.date.setTime( this._getParsedValue() ).select();
this.refresh();
}
},
mousedown: function( event ) {
if (this.isOpen) {
if ( this.isOpen ) {
suppressExpandOnFocus = true;
this.close();
return;
@ -267,7 +277,8 @@ $.widget( "ui.datepicker", {
this._on( this.picker, {
focusout: function( event ) {
// use a timer to allow click to clear it and letting that
// Use a timer to allow click to clear it and letting that
// handle the closing instead of opening again
// also allows tabbing inside the calendar without it closing
this.closeTimer = this._delay( function() {
@ -280,7 +291,8 @@ $.widget( "ui.datepicker", {
mouseup: function() {
clearTimeout( this.closeTimer );
},
// TODO on TAB (or shift TAB), make sure it ends up on something useful in DOM order
// 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" ) ) {
this.close( event );
@ -317,6 +329,7 @@ $.widget( "ui.datepicker", {
return element;
},
_createTmpl: function() {
this._createDatepicker();
this.picker.find( "button" ).button();
@ -324,10 +337,12 @@ $.widget( "ui.datepicker", {
if ( this.inline ) {
this.picker.children().addClass( "ui-datepicker-inline" );
}
// against display:none in datepicker.css
// 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 = "";
@ -350,6 +365,7 @@ $.widget( "ui.datepicker", {
.html( pickerHtml )
.appendTo( this.picker );
},
_buildMultiplePicker: function() {
var headerClass,
html = "",
@ -358,6 +374,7 @@ $.widget( "ui.datepicker", {
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" :
@ -470,6 +487,7 @@ $.widget( "ui.datepicker", {
},
_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,
@ -577,8 +595,9 @@ $.widget( "ui.datepicker", {
// 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
// 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() );
@ -610,10 +629,6 @@ $.widget( "ui.datepicker", {
return;
}
// TODO explain this
this.date = $.date( this.element.val(), this.options.dateFormat );
this.date.eachDay = this.options.eachDay;
this.date.select();
this.refresh();
this.picker
@ -625,8 +640,8 @@ $.widget( "ui.datepicker", {
this._show( this.picker, 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
// 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
this.element.attr( "tabindex", -1 );
this.isOpen = true;
@ -654,46 +669,39 @@ $.widget( "ui.datepicker", {
},
_buildPosition: function() {
return $.extend( {}, {
of: this.element
}, this.options.position );
return $.extend( { of: this.element }, this.options.position );
},
_select: function( event, time ) {
this.date.setTime( time ).select();
this.refresh();
this._setOption( "value", new Date( time ) );
if ( !this.inline ) {
this.element.val( this.date.format() );
this.close();
this._focusTrigger();
}
this._trigger( "select", event, {
// TODO replace with value option to initialise and read
date: this.date.format()
});
},
_value: function( value ) {
this.date.setTime( value ).select();
if ( !this.inline ) {
this.element.val( this.date.format() );
}
this.refresh();
// TODO Replace with value option to initialise and read
date: this.value()
});
},
value: function( value ) {
if ( arguments.length ) {
this._value( value );
this._setOption( "value", Globalize.parseDate( value, this.options.dateFormat ) );
} else {
return this.isValid() ? this.date.format() : this.element.val();
if ( this.inline ) {
return Globalize.format( this.date.selected(), this.options.dateFormat );
} else {
return this.element.val();
}
}
},
valueAsDate: function( value ) {
if ( arguments.length ) {
this._value( value );
this._setOption( "value", value );
} else {
return this.isValid() ? this.date.date() : null;
return this.option( "value" );
}
},
@ -702,7 +710,7 @@ $.widget( "ui.datepicker", {
return true;
}
return Globalize.parseDate( this.element.val(), this.options.dateFormat ) !== null;
return this._getParsedValue() !== null;
},
_destroy: function() {
@ -720,7 +728,28 @@ $.widget( "ui.datepicker", {
return this.picker;
},
_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" ) {