Hola a todos.
Me encontré con el problema de tener que utilizar un datepicker que me permitiera seleccionar solo los meses de diferentes años, y que, tras la selección del usuario, escribiera en un TextBox una fecha en formato mm/yyyy.
Me basé en el código encontrado en el siguiente foro: http://forums.asp.net/t/1349086.aspx e hice unas modificaciones para que se adaptara a mis necesidades.
A continaución les dejo el código completo de la página (que funciona) y unas cuantas observaciones:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Prueba.aspx.cs" Inherits="WebSiteEncuestas.Prueba"
Culture="es-AR" UICulture="es" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script type="text/javascript">
var cal1;
var cal2;
function pageLoad() {
cal1 = $find("calendar1");
cal2 = $find("calendar2");
modifyCalDelegates(cal1);
modifyCalDelegates(cal2);
}
function modifyCalDelegates(cal) {
//we need to modify the original delegate of the month cell.
cal._cell$delegates = {
mouseover: Function.createDelegate(cal, cal._cell_onmouseover),
mouseout: Function.createDelegate(cal, cal._cell_onmouseout),
click: Function.createDelegate(cal, function (e) {
/// <summary>
/// Handles the click event of a cell
/// </summary>
/// <param name="e" type="Sys.UI.DomEvent">The arguments for the event</param>
e.stopPropagation();
e.preventDefault();
if (!cal._enabled) return;
var target = e.target;
var visibleDate = cal._getEffectiveVisibleDate();
Sys.UI.DomElement.removeCssClass(target.parentNode, "ajax__calendar_hover");
switch (target.mode) {
case "prev":
case "next":
cal._switchMonth(target.date);
break;
case "title":
switch (cal._mode) {
case "days": cal._switchMode("months"); break;
case "months": cal._switchMode("years"); break;
}
break;
case "month":
//if the mode is month, then stop switching to day mode.
if (target.month == visibleDate.getMonth()) {
//this._switchMode("days");
} else {
cal._visibleDate = target.date;
//this._switchMode("days");
}
cal.set_selectedDate(target.date);
cal._switchMonth(target.date);
cal._blur.post(true);
cal.raiseDateSelectionChanged();
break;
case "year":
if (target.date.getFullYear() == visibleDate.getFullYear()) {
cal._switchMode("months");
} else {
cal._visibleDate = target.date;
cal._switchMode("months");
}
break;
// case "day":
// this.set_selectedDate(target.date);
// this._switchMonth(target.date);
// this._blur.post(true);
// this.raiseDateSelectionChanged();
// break;
case "today":
cal.set_selectedDate(target.date);
cal._switchMonth(target.date);
cal._blur.post(true);
cal.raiseDateSelectionChanged();
break;
}
})
}
}
function onCalendarShown(sender, args) {
//set the default mode to month
sender._switchMode("months", true);
changeCellHandlers(cal1);
}
function changeCellHandlers(cal) {
if (cal._monthsBody) {
//remove the old handler of each month body.
for (var i = 0; i < cal._monthsBody.rows.length; i++) {
var row = cal._monthsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
$common.removeHandlers(row.cells[j].firstChild, cal._cell$delegates);
}
}
//add the new handler of each month body.
for (var i = 0; i < cal._monthsBody.rows.length; i++) {
var row = cal._monthsBody.rows[i];
for (var j = 0; j < row.cells.length; j++) {
$addHandlers(row.cells[j].firstChild, cal._cell$delegates);
}
}
}
}
function onCalendarHidden(sender, args) {
if (sender.get_selectedDate()) {
if (cal1.get_selectedDate() && cal2.get_selectedDate() && cal1.get_selectedDate() > cal2.get_selectedDate()) {
alert('La fecha de inicio debe ser menor que la fecha de fin. Por favor, seleccione nuvamente.');
sender.show();
return;
}
//get the final date
var finalDate = new Date(sender.get_selectedDate());
var selectedMonth = finalDate.getMonth();
finalDate.setDate(1);
if (sender == cal2) {
// set the calender2's default date as the last day
finalDate.setMonth(selectedMonth + 1);
finalDate = new Date(finalDate - 1);
}
//set the date to the TextBox
sender.get_element().value = finalDate.format(sender._format);
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ToolkitScriptManager ID="ToolkitScriptManager2" runat="server" EnableScriptGlobalization="true"
EnableScriptLocalization="true" />
From :
<asp:TextBox ID="TextBox1" runat="server" AutoCompleteType="Disabled"></asp:TextBox>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Images/Calendar_scheduleHS.png" />
<asp:CalendarExtender ID="CalendarExtender1" BehaviorID="calendar1" runat="server"
Enabled="True" Format="MM/yyyy" TargetControlID="TextBox1" OnClientShown="onCalendarShown"
OnClientHidden="onCalendarHidden" PopupButtonID="ImageButton1">
</asp:CalendarExtender>
To :
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:CalendarExtender ID="CalendarExtender2" BehaviorID="calendar2" runat="server"
Enabled="True" Format="MM/yyyy" TargetControlID="TextBox2" OnClientShown="onCalendarShown"
OnClientHidden="onCalendarHidden" TodaysDateFormat="MM/yyyy">
</asp:CalendarExtender>
</div>
</form>
</body>
</html>
Observaciones:
1. El CalendarExtender es parte del AjaxControlToolkit. Deben bajar esta librería y añadir una referencia a ella para poder trabajar con este control.
2. Hay dos maravillosas propiedades del CalendarExtender muy notables (observar los CalendarExtenders):
Format="MM/yyyy"
TodaysDateFormat="MM/yyyy"
Yo las fijé de ésta manera porque necesitaba que el TextBox tomara los valores en dicho formato, pero esto es configurable totalmente.
3. Las propiedades de la página deben ser fijadas así (ver primeras líneas de código).
Culture="es-AR" UICulture="es"
para que el Calendar tome el idioma español correctamente. De lo contrario, habría que fijar estos mismos valores en el web.config correspondiente (generalmente el que se encuentra en la raíz del sitio).
4. Las propiedades de EnableScriptGloablization y EnableScriptLocalization del ToolkitScriptManager o del ScriptManager deben ser fijadas como se muestra aquí:
<asp:ToolkitScriptManager ID="ToolkitScriptManager2" runat="server" EnableScriptGlobalization="true"
EnableScriptLocalization="true" />
5. En la página hay código JavaScript que funciona para impedir que la fecha de fin sea menor que la fecha de inicio y lanza un cartel de tipo "alert" de JavaScript advirtiéndolo, obligándolo a seleccionar nuevamente una fecha de fin. Esto puede ser útil para el caso de necesitar parejas de fecha "inicio - fin".
6. Si aún después de hacer todo esto tienen el problema de que el "Today" que se muestra en la sección inferior del calendario no ha sido traducido a "Hoy", es porque el AjaxControlToolkit no está encontrando la carpeta de resources correspondiente al idioma que quieren utilizar (español en el caso de este ejemplo). Verifiquen que junto a la librería AjaxControlToolkit.dll referenciada por su aplicación / sitio se encuentren las carpetas con los recursos para los diferentes idiomas, como se muestra en las siguientes imágenes:
y que dentro de ellas (al menos de las que van a utilizar) se encuentre el archivo .dll correspondiente a cada una, que tendrá una apariencia como el de la siguiente imagen:
7. Por último, vale aclarar que uno de los calendarios de selección se está mostrando cuando se hace clic sobre un ImageButton, y otro cuando el TextBox de destino toma el foco. El ejemplo es útil para que ustedes decidan usar el modo que más les guste o que necesiten.
Espero haber sido clara y que les haya servido.
Hastra pronto.
Hola ...
ResponderEliminargracias por esto me ayudo mucho..
y ahora tengo una duda.. ¿Se puede configurar para que solo me seleccione el año?
osea sin el mes ni el dia solo el año ejem:"2012"
..
espero que me ayudes
gracias.