Calendar: Add buttons option

This commit is contained in:
Felix Nagel 2014-06-20 00:13:20 +02:00 committed by Scott González
parent 5df6d39d13
commit 9461f6680b
10 changed files with 219 additions and 23 deletions

View File

@ -17,7 +17,11 @@
<script>
$(function() {
$( "#calendar" ).calendar({
showButtonPanel: true
buttons: {
"Today": function() {
$( this ).calendar( "valueAsDate", new Date() );
}
}
});
});
</script>
@ -27,7 +31,7 @@
<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>
<p>Display a button for selecting Today's date with the <code>buttons</code> option.</p>
</div>
</body>
</html>

View File

@ -1,5 +1,6 @@
TestHelpers.commonWidgetTests( "calendar", {
defaults: {
buttons: [],
dateFormat: { date: "short" },
disabled: false,
eachDay: $.noop,

View File

@ -5,7 +5,7 @@ module( "calendar: core" );
TestHelpers.testJshint( "calendar" );
test( "base structure", function() {
expect( 22 );
expect( 26 );
var header, title, table, thead, week, child, buttonpane,
element = $( "#calendar" ).calendar(),
@ -14,7 +14,7 @@ test( "base structure", function() {
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)" );
equal( dp.children().length, 2, "Structure - child count (header, calendar)" );
header = dp.children( ":first" );
ok( header.is( "div.ui-calendar-header" ), "Structure - header division" );
@ -42,17 +42,33 @@ test( "base structure", function() {
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( "option", "buttons", {
"test": function() {},
"test button": function() {}
});
equal( dp.children().length, 3, "Structure buttons - child count (header, calendar, buttonpane)" );
buttonpane = dp.children( ".ui-calendar-buttonpane" );
equal( buttonpane.children( "div.ui-calendar-buttonset" ).length, 1, "Structure buttons - buttonset" );
equal( buttonpane.find( "button.ui-button:first" ).text(), "test", "Structure buttons - buttonset" );
equal( buttonpane.find( "button.ui-button:eq(1)" ).text(), "test button", "Structure buttons - buttonset" );
element.calendar( "destroy" );
step3();
}
function step3() {
// Multi-month 2
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" );
equal( dp.children().length, 3, "Structure multi [2] - child count" );
child = dp.children( ":eq(2)" );
ok( child.is( "div.ui-calendar-row-break" ), "Structure multi [2] - row break" );

View File

@ -2,6 +2,111 @@
module( "calendar: options" );
test("buttons", function() {
expect( 21 );
var button, i, newButtons,
buttons = {
"Ok": function( event ) {
ok(true, "button click fires callback" );
equal( this, element[ 0 ], "context of callback" );
equal( event.target, button[ 0 ], "event target" );
},
"Cancel": function( event ) {
ok( true, "button click fires callback" );
equal( this, element[ 0 ], "context of callback" );
equal( event.target, button[ 1 ], "event target" );
}
},
element = $( "#calendar" ).calendar({ buttons: buttons });
button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
equal( button.length, 2, "number of buttons" );
i = 0;
$.each( buttons, function( key ) {
equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
i++;
});
ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container" );
ok(
element.calendar( "widget" ).hasClass( "ui-calendar-buttons" ),
"calendar wrapper adds class about having buttons"
);
button.trigger( "click" );
newButtons = {
"Close": function( event ) {
ok( true, "button click fires callback" );
equal( this, element[ 0 ], "context of callback" );
equal( event.target, button[ 0 ], "event target" );
}
};
deepEqual(
element.calendar( "option", "buttons" ),
buttons,
".calendar('option', 'buttons') getter"
);
element.calendar( "option", "buttons", newButtons );
deepEqual(
element.calendar( "option", "buttons" ),
newButtons,
".calendar('option', 'buttons', ...) setter"
);
button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
equal( button.length, 1, "number of buttons after setter" );
button.trigger( "click" );
i = 0;
$.each( newButtons, function( key ) {
equal( button.eq( i ).text(), key, "text of button " + ( i + 1 ) );
i += 1;
});
element.calendar( "option", "buttons", null );
button = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
equal( button.length, 0, "all buttons have been removed" );
equal( element.find( ".ui-calendar-buttonset" ).length, 0, "buttonset has been removed" );
equal( element.hasClass( "ui-calendar-buttons" ), false, "calendar element removes class about having buttons" );
element.remove();
});
test( "buttons - advanced", function() {
expect( 7 );
var buttons,
element = $( "#calendar" ).calendar({
buttons: [{
text: "a button",
"class": "additional-class",
id: "my-button-id",
click: function() {
equal( this, element[ 0 ], "correct context" );
},
icons: {
primary: "ui-icon-cancel"
},
showText: false
}]
});
buttons = element.calendar( "widget" ).find( ".ui-calendar-buttonpane button" );
equal( buttons.length, 1, "correct number of buttons" );
equal( buttons.attr( "id" ), "my-button-id", "correct id" );
equal ( buttons.text(), "a button", "correct label" );
ok( buttons.hasClass( "additional-class" ), "additional classes added" );
deepEqual( buttons.button( "option", "icons" ), { primary: "ui-icon-cancel", secondary: null } );
equal( buttons.button( "option", "text" ), false );
buttons.click();
element.remove();
});
test( "dateFormat", function() {
expect( 2 );
var element = $( "#calendar" ).calendar({

View File

@ -15,7 +15,9 @@ TestHelpers.calendar = {
equal( d1.toString(), d2.toString(), message );
},
focusGrid: function( element ) {
element.find( "table:tabbable" ).simulate( "focus" );
element.find( ":tabbable" ).last().simulate( "focus" );
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
$( ":focus" ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB } );
return $( ":focus" );
}

View File

@ -1,6 +1,7 @@
TestHelpers.commonWidgetTests( "datepicker", {
defaults: {
appendTo: null,
buttons: [],
dateFormat: { date: "short" },
disabled: false,
eachDay: $.noop,

View File

@ -29,7 +29,7 @@ asyncTest( "base structure", function() {
setTimeout(function() {
ok( widget.is( ":visible" ), "Datepicker visible" );
equal( widget.children().length, 3, "Child count" );
equal( widget.children().length, 2, "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" );

View File

@ -40,6 +40,22 @@ test( "appendTo", function() {
input.datepicker( "destroy" );
});
test("buttons", function() {
expect( 3 );
var button,
buttons = {
"Ok": function() {},
"Cancel": function() {}
},
element = $( "#datepicker" ).datepicker({ buttons: buttons });
button = element.datepicker( "widget" ).find( ".ui-calendar-buttonpane button" );
equal( button.length, 2, "number of buttons" );
ok( button.parent().hasClass( "ui-calendar-buttonset" ), "buttons in container");
ok( element.datepicker( "widget" ).hasClass( "ui-calendar-buttons" ), "calendar wrapper adds class about having buttons" );
});
test( "dateFormat", function() {
expect( 2 );
var input = $( "#datepicker" ).val( "1/1/14" ).datepicker(),
@ -149,7 +165,7 @@ test( "showWeek", function() {
input.datepicker( "option", "showWeek", true );
equal( container.find( "thead th" ).length, 8, "supports changing option after init" );
});
test( "min / max", function() {
expect( 14 );

View File

@ -13,6 +13,7 @@
// AMD. Register as an anonymous module.
// TODO Add globalize and $.date
// TODO: Keep button even if its optional?
define([
"jquery",
"./core",
@ -29,6 +30,7 @@
return $.widget( "ui.calendar", {
version: "@VERSION",
options: {
buttons: [],
dateFormat: { date: "short" },
eachDay: $.noop,
max: null,
@ -44,6 +46,7 @@ return $.widget( "ui.calendar", {
_create: function() {
this.id = this.element.uniqueId().attr( "id" );
this.labels = Globalize.translate( "datepicker" );
this.buttonClickContext = this.element[ 0 ];
this.date = $.date( this.options.value, this.options.dateFormat ).select();
this.date.eachDay = this.options.eachDay;
@ -59,10 +62,6 @@ return $.widget( "ui.calendar", {
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();
@ -144,7 +143,7 @@ return $.widget( "ui.calendar", {
pickerHtml = "";
if ( this.options.numberOfMonths === 1 ) {
pickerHtml = this._buildHeader() + this._buildGrid() + this._buildButtons();
pickerHtml = this._buildHeader() + this._buildGrid();
} else {
pickerHtml = this._buildMultiplePicker();
classes += " ui-calendar-multi";
@ -158,6 +157,8 @@ return $.widget( "ui.calendar", {
})
.html( pickerHtml );
this._createButtonPane();
this.grid = this.element.find( ".ui-calendar-calendar" );
},
@ -190,7 +191,7 @@ return $.widget( "ui.calendar", {
html += this._buildTitlebar() + "</div>" + this._buildGrid() + "</div>";
}
html += "<div class='ui-calendar-row-break'></div>" + this._buildButtons();
html += "<div class='ui-calendar-row-break'></div>";
this.date = currentDate;
@ -363,12 +364,55 @@ return $.widget( "ui.calendar", {
return content;
},
_buildButtons: function() {
return "<div class='ui-calendar-buttonpane ui-widget-content'>" +
"<button class='ui-calendar-current'>" +
this._getTranslation( "currentText" ) +
"</button>" +
"</div>";
_createButtonPane: function() {
this.buttonPane = $( "<div>" )
.addClass( "ui-calendar-buttonpane ui-widget-content ui-helper-clearfix" );
this.buttonSet = $( "<div>" )
.addClass( "ui-calendar-buttonset" )
.appendTo( this.buttonPane );
this._createButtons();
},
_createButtons: function() {
var that = this,
buttons = this.options.buttons;
this.buttonPane.remove();
this.buttonSet.empty();
if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
this.element.removeClass( "ui-calendar-buttons" );
return;
}
$.each( buttons, function( name, props ) {
var click, buttonOptions;
props = $.isFunction( props ) ?
{ click: props, text: name } :
props;
// Default to a non-submitting button
props = $.extend( { type: "button" }, props );
// Change the context for the click callback to be the main element
click = props.click;
props.click = function() {
click.apply( that.buttonClickContext, arguments );
};
buttonOptions = {
icons: props.icons,
text: props.showText
};
delete props.icons;
delete props.showText;
$( "<button></button>", props )
.button( buttonOptions )
.appendTo( that.buttonSet );
});
this.element.addClass( "ui-calendar-buttons" );
this.buttonPane.appendTo( this.element );
},
// Refreshing the entire calendar during interaction confuses screen readers, specifically
@ -389,6 +433,7 @@ return $.widget( "ui.calendar", {
.children().html( this.labels.prevText );
$( ".ui-calendar-next", this.element ).attr( "title", this.labels.nextText )
.children().html( this.labels.nextText );
this._createButtons();
} else {
this._refreshMultiplePicker();
}
@ -496,6 +541,10 @@ return $.widget( "ui.calendar", {
this._super( key, value );
if ( key === "buttons" ) {
this._createButtons();
}
if ( key === "eachDay" ) {
this.date.eachDay = value;
this.refresh();

View File

@ -32,7 +32,7 @@
}(function( $ ) {
var widget,
calendarOptions = [ "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ];
calendarOptions = [ "buttons", "dateFormat", "eachDay", "max", "min", "numberOfMonths", "showWeek" ];
widget = $.widget( "ui.datepicker", {
version: "@VERSION",
@ -97,6 +97,8 @@ widget = $.widget( "ui.datepicker", {
}) )
.calendar( "instance" );
this.calendarInstance.buttonClickContext = that.element[ 0 ];
this._setHiddenPicker();
this.element.attr({