Ich bin mit jQuery Datum Picker, um den Kalender alle über meine app anzuzeigen. Ich möchte wissen, ob ich es verwenden können, um den Monat und das Jahr (Mai 2010) und nicht den Kalender anzuzeigen?
Antworten
Zu viele Anzeigen?Das habe ich mir ausgedacht. Es blendet den Kalender aus, ohne dass ein zusätzlicher Stilblock erforderlich ist, und fügt eine Schaltfläche zum Löschen hinzu, um das Problem zu lösen, dass der Wert nicht gelöscht werden kann, sobald Sie auf die Eingabe klicken. Auch funktioniert gut mit mehreren monthpickers auf der gleichen Seite.
HTML:
<input type='text' class='monthpicker'>
JavaScript:
$(".monthpicker").datepicker({
changeMonth: true,
changeYear: true,
dateFormat: "yy-mm",
showButtonPanel: true,
currentText: "This Month",
onChangeMonthYear: function (year, month, inst) {
$(this).val($.datepicker.formatDate('yy-mm', new Date(year, month - 1, 1)));
},
onClose: function(dateText, inst) {
var month = $(".ui-datepicker-month :selected").val();
var year = $(".ui-datepicker-year :selected").val();
$(this).val($.datepicker.formatDate('yy-mm', new Date(year, month, 1)));
}
}).focus(function () {
$(".ui-datepicker-calendar").hide();
}).after(
$("<a href='javascript: void(0);'>clear</a>").click(function() {
$(this).prev().val('');
})
);
Wie viele andere bin auch ich bei dem Versuch, dies zu tun, auf zahlreiche Probleme gestoßen, und nur eine Kombination aus den geposteten Lösungen und schließlich einem großen Hack, um es perfekt zu machen, hat mich zu einem Lösung, die mit allen Datumsformaten und Lokalisierungen funktioniert genau wie normale Dattelpflücker.
Probleme mit anderen Lösungen in diesem Thread, die ich ausprobiert habe:
- Die Auswahl eines neuen Datums in einer Datumsauswahl würde auch das (interne) Datum anderer Datumsauswahlen ändern, so dass beim erneuten Öffnen der anderen Datumsauswahlen (oder beim Versuch, deren Datum abzurufen) ein anderes Datum als das in dem ihnen zugewiesenen Eingabefeld angezeigte angezeigt würde.
- Die Datumsauswahl "merkt" sich das Datum nicht, wenn sie erneut geöffnet wird.
- Der Code für das Jonglieren mit den Datumsangaben verwendete Substring, so dass er nicht mit allen Formaten kompatibel war.
- Das Eingabefeld wurde nicht korrekt aktualisiert, wenn man eine falsch formatierte Zeichenkette für ein Datum eingab und dann auf "Schließen" in der Datumsauswahl klickte.
- Der Monatspicker änderte das Eingabefeld nur beim Schließen und nicht immer, wenn die Werte geändert wurden.
- Normale Datumspicker, die die Tage anzeigen, können nicht auf derselben Seite stehen wie Monatspicker, die die Tage nicht anzeigen.
Ich habe endlich einen Weg gefunden, um all diese Probleme beheben sogar in den originalen Datepickern!
HINWEIS: Sie müssen Folgendes NICHT verwenden Monatspicker-Skripte um die ersten vier Probleme in Ihrem normalen jQuery Datumspicker . Verwenden Sie einfach die Datepicker-Instanziierung Skript weiter unten in diesem Beitrag. Die Probleme 5 und 6 beziehen sich nur auf verschiedene Lösungen für den Monatspicker, die ich ausprobiert habe.
Die Probleme 1-3 und 5 hatten damit zu tun, wie die Datums- und Monatspicker in ihrem internen Code referenziert werden, um sicherzustellen, dass sie nicht mit anderen Datums- und Monatspickern kollidieren, sowie mit einigen manuellen Aktualisierungen der Picker. Dies ist in den Beispielen zur Instanziierung unten zu sehen. Das vierte Problem wurde durch Hinzufügen von eigenem Code zu den Datepicker-Funktionen behoben (siehe Kommentare in den Beispielen, insbesondere zu onClose).
Für das sechste und letzte Problem, das sich nur auf die Verwendung der Monatspicker neben Datumspickern Wir müssen nur die Datumsauswahl und die Monatsauswahl richtig trennen.
Also, warum nicht eine der wenigen benutzerdefinierten jQuery-UI Monatspicker Addons da draußen? Diejenigen, die ich gefunden habe, als ich dies schrieb, waren nicht flexibel genug, um sie zu lokalisieren, und einige unterstützten keine Animationen... was also tun? Rollen Sie Ihren "eigenen" Code aus dem Datepicker-Code! Damit erhalten Sie einen voll funktionsfähigen Monatspicker, mit allen Funktionen des Datumspickers, nur ohne die Anzeige der Tage.
Ich habe eine monthpicker js-script とのことです。 begleitendes CSS-Skript mit der unten beschriebenen Methode und dem jQuery-UI v1.11.1-Code. Kopieren Sie diese Code-Schnipsel einfach in zwei neue Dateien, monthpicker.js bzw. monthpicker.css, und verwenden Sie die unten stehenden Code-Schnipsel für die Instanziierung.
Wenn Sie sich über die eher einfaches Verfahren, mit dem ich die Datumsauswahl in eine Monatsauswahl umgewandelt habe und scrollen Sie bis zum letzten Abschnitt. Dann können Sie den Vorgang vielleicht mit einer neueren Version von jQuery-UI wiederholen.
Jetzt müssen noch die Datums- und Monatspicker auf der Seite hinzugefügt werden!
Die folgenden Javascript-Code-Schnipsel funktionieren mit mehrere Datumspicker und/oder Monatspicker auf der Seite, ohne die oben erwähnten Probleme! In der Regel durch häufige Verwendung von "$(this)." behoben :)
Das erste Skript ist für einen normalen Datumspicker, das zweite für die "neuen" Monatspicker.
Der unkommentierte .nach , mit dem Sie ein Element erstellen können, um das Eingabefeld zu löschen, ist aus der Antwort von Paul Richards gestohlen.
Ich verwende das Format "MM yy" in meinem Monatspicker und das Format "yy-mm-dd" in meinem Datumspicker, aber das ist vollständig kompatibel mit allen Formaten Es steht Ihnen also frei, die von Ihnen gewünschte Variante zu verwenden. Ändern Sie einfach die Option "dateFormat". Die Standardoptionen 'showButtonPanel', 'showAnim' und 'yearRange' sind natürlich optional und können nach Ihren Wünschen angepasst werden.
Hinzufügen einer Datumsauswahl
Datepicker-Instanziierung. Diese reicht von vor 90 Jahren bis in die heutige Zeit. Es hilft Ihnen, das Eingabefeld korrekt zu halten, vor allem, wenn Sie die Optionen defaultDate, minDate und maxDate setzen, aber es kann damit umgehen, wenn Sie es nicht tun. Es funktioniert mit jedem dateFormat, das Sie wählen.
HINWEIS: Die vielen "new Date()"-Aufrufe sehen lächerlich aus, aber ich kann keinen anderen Weg finden, ein dynamisches Datum in die Deklaration zu packen, ohne das für jeden Teil zu tun, da ich (meines Wissens nach) keine wiederverwendbare Instanz in diesem Kontext erstellen kann. Wenn jemand eine bessere Möglichkeit kennt, ein erweitertes Datum in einem Kontext zu setzen, in dem Sie minDate und maxDate setzen, wäre ich Ihnen sehr dankbar!
$('#MyDateTextBox').datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showMonthAfterYear: true,
showWeek: true,
showAnim: "drop",
constrainInput: true,
yearRange: "-90:",
minDate: new Date((new Date().getFullYear() - 90), new Date().getMonth(), new Date().getDate()),
maxDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
onClose: function (dateText, inst) {
// When onClose is called after we have clicked a day (and not clicked 'Close' or outside the datepicker), the input-field is automatically
// updated with a valid date-string. They will always pass, because minDate and maxDate are already enforced by the datepicker UI.
// This try is to catch and handle the situations, where you open the datepicker, and manually type in an invalid date in the field,
// and then close the datepicker by clicking outside the datepicker, or click 'Close', in which case no validation takes place.
try {
// If datepicker can parse the date using our formatstring, the instance will automatically parse
// and apply it for us (after the onClose is done).
// If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
// If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());
// typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
// reset to the last set default date.
// You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
if (typedDate == null)throw "No date selected";
// We do a manual check to see if the date is within minDate and maxDate, if they are defined.
// If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
var minDate = $(this).datepicker("option", "minDate");
var maxDate = $(this).datepicker("option", "maxDate");
if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";
// We update the default date, because the date seems valid.
// We do not need to manually update the input-field, as datepicker has already done this automatically.
$(this).datepicker('option', 'defaultDate', typedDate);
}
catch (err) {
console.log("onClose: " + err);
// Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
// a new valid date, by clicking on a day.
// Instead, we set the current date, as well as the value of the input-field, to the last selected (and
// accepted/validated) date from the datepicker, by getting its default date. This only works, because
// we manually change the default date of the datepicker whenever a new date is selected, in both 'beforeShow'
// and 'onClose'.
var date = $(this).datepicker('option', 'defaultDate');
$(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
$(this).datepicker('setDate', date);
}
},
beforeShow: function (input, inst) {
// beforeShow is particularly irritating when initializing the input-field with a date-string.
// The date-string will be parsed, and used to set the currently selected date in the datepicker.
// BUT, if it is outside the scope of the minDate and maxDate, the text in the input-field is not
// automatically updated, only the internal selected date, until you choose a new date (or, because
// of our onClose function, whenever you click close or click outside the datepicker).
// We want the input-field to always show the date that is currently chosen in our datepicker,
// so we do some checks to see if it needs updating. This may not catch ALL cases, but these are
// the primary ones: invalid date-format; date is too early; date is too late.
try {
// If datepicker can parse the date using our formatstring, the instance will automatically parse
// and apply it for us (after the onClose is done).
// If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
// If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());
// typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
// reset to the last set default date.
// You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
if (typedDate == null)throw "No date selected";
// We do a manual check to see if the date is within minDate and maxDate, if they are defined.
// If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
var minDate = $(this).datepicker("option", "minDate");
var maxDate = $(this).datepicker("option", "maxDate");
if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";
// We update the input-field, and the default date, because the date seems valid.
// We also manually update the input-field, as datepicker does not automatically do this when opened.
$(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), typedDate));
$(this).datepicker('option', 'defaultDate', typedDate);
}
catch (err) {
// Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
// a new valid date, by clicking on a day.
// We want the same behavior when opening the datepicker, so we set the current date, as well as the value
// of the input-field, to the last selected (and accepted/validated) date from the datepicker, by getting
// its default date. This only works, because we manually change the default date of the datepicker whenever
// a new date is selected, in both 'beforeShow' and 'onClose', AND have a default date set in the datepicker options.
var date = $(this).datepicker('option', 'defaultDate');
$(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
$(this).datepicker('setDate', date);
}
}
})
//.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
// $("<a href='javascript: void(0);'>clear</a>").click(function() {
// $(this).prev().val('');
// })
//)
;
Hinzufügen eines Monatspickers
Binden Sie die Datei monthpicker.js und die Datei monthpicker.css in die Seite ein, auf der Sie die Monatspicker verwenden möchten.
Monatspicker-Instanziierung Der Wert, der von diesem Monatspicker abgerufen wird, ist immer der ERSTE Tag des ausgewählten Monats. Er beginnt mit dem aktuellen Monat und reicht von vor 100 Jahren bis 10 Jahre in die Zukunft.
$('#MyMonthTextBox').monthpicker({
dateFormat: 'MM yy',
changeMonth: true,
changeYear: true,
showMonthAfterYear: true,
showAnim: "drop",
constrainInput: true,
yearRange: "-100Y:+10Y",
minDate: new Date(new Date().getFullYear() - 100, new Date().getMonth(), 1),
maxDate: new Date((new Date().getFullYear() + 10), new Date().getMonth(), 1),
defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), 1),
// Monthpicker functions
onClose: function (dateText, inst) {
var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
$(this).monthpicker('option', 'defaultDate', date);
$(this).monthpicker('setDate', date);
},
beforeShow: function (input, inst) {
if ($(this).monthpicker("getDate") !== null) {
// Making sure that the date set is the first of the month.
if($(this).monthpicker("getDate").getDate() !== 1){
var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
$(this).monthpicker('option', 'defaultDate', date);
$(this).monthpicker('setDate', date);
}
} else {
// If the date is null, we reset it to the defaultDate. Make sure that the defaultDate is always set to the first of the month!
$(this).monthpicker('setDate', $(this).monthpicker('option', 'defaultDate'));
}
},
// Special monthpicker function!
onChangeMonthYear: function (year, month, inst) {
$(this).val($.monthpicker.formatDate($(this).monthpicker('option', 'dateFormat'), new Date(year, month - 1, 1)));
}
})
//.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
// $("<a href='javascript: void(0);'>clear</a>").click(function() {
// $(this).prev().val('');
// })
//)
;
Das war's! Das ist alles, was man für einen Monatspicker braucht.
Ich kann nicht scheinen, um eine jsfiddle Arbeit mit diesem zu machen, aber es funktioniert für mich in meinem ASP.NET MVC-Projekt. Tun Sie einfach, was Sie normalerweise tun, um einen Datepicker zu Ihrer Seite hinzuzufügen, und integrieren Sie die oben genannten Skripte, möglicherweise durch Ändern des Selektors (d.h. $("#MyMonthTextBox")) auf etwas, das für Sie funktioniert.
Ich hoffe, das hilft jemandem.
Links zu Pastebins für einige zusätzliche Datums- und Monatspicker-Einstellungen:
-
Monthpicker arbeitet am letzten Tag des Monats . Das Datum, das Sie mit diesem Monatspicker erhalten, ist immer der letzte Tag des Monats.
-
Zwei kollaborierende Monatspflücker Start' arbeitet am Ersten des Monats, und 'Ende' arbeitet am Letzten des Monats. Beide sind voneinander abhängig, d.h. wenn Sie bei "Ende" einen Monat auswählen, der vor dem bei "Anfang" ausgewählten Monat liegt, wird "Anfang" auf denselben Monat wie "Ende" gesetzt. Und andersherum. OPTIONAL: Wenn Sie einen Monat auf 'start' auswählen, wird das 'minDate' auf 'end' auf diesen Monat gesetzt. Um diese Funktion zu entfernen, kommentieren Sie eine Zeile in onClose aus (lesen Sie die Kommentare).
-
Zwei kollaborierende Dattelpflücker Sie sind beide voneinander abhängig, d. h. wenn Sie ein Datum für "Ende" wählen, das vor dem ausgewählten Datum für "Anfang" liegt, wird "Anfang" auf denselben Monat wie "Ende" gesetzt. Und andersherum. OPTIONAL: Bei der Auswahl eines Datums auf 'Start' wird das 'minDate' auf 'Ende' auf dieses Datum gesetzt. Um diese Funktion zu entfernen, kommentieren Sie eine Zeile in onClose aus (lesen Sie die Kommentare).
Wie ich den DatePicker in einen MonthPicker verwandelt habe
Ich habe alle Javascript-Code aus jquery-ui-1.11.1.js in Bezug auf ihre datepicker genommen, fügte es in eine neue js-Datei, und ersetzt die folgenden Zeichenfolgen:
- "Datumspicker" ==> "Monatspicker"
- "Datepicker" ==> "Monatspicker"
- "Datumspicker" ==> "Monatspicker"
- "Datumsauswahl" ==> "Monatsauswahl"
Dann habe ich den Teil der for-Schleife entfernt, der das gesamte ui-datepicker-calendar div erzeugt (das div, das andere Lösungen mit CSS ausblenden). Dieser Teil ist in der Funktion _generateHTML: (inst) zu finden.
Suchen Sie die Zeile, in der steht:
"</div><table class='ui-datepicker-calendar'><thead>" +
Markieren Sie alles von nach dem schließenden div-Tag und hinunter zu (und no einschließlich) der Zeile, in der es heißt:
drawMonth++;
Jetzt wird es unglücklich sein, weil wir einige Dinge abschließen müssen. Fügen Sie nach dem schließenden div-Tag von vorhin dies hinzu:
";
Der Code sollte jetzt gut zusammengefügt sein. Hier ist ein Code-Schnipsel, der zeigt, was Sie am Ende haben sollten:
...other code...
calender += "<div class='ui-monthpicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
"</div>";
drawMonth++;
if (drawMonth > 11) {
drawMonth = 0;
drawYear++;
}
...other code...
Dann habe ich den Code aus jquery-ui.css, der sich auf die Datepicker bezieht, in eine neue CSS-Datei kopiert und die folgenden Zeichenfolgen ersetzt:
- "datepicker" ==> "monthpicker"
Fügen Sie eine weitere einfache Lösung hinzu
$(function() {
$('.monthYearPicker').datepicker({
changeMonth: true,
changeYear: true,
showButtonPanel: true,
dateFormat: 'M yy'
}).focus(function() {
var thisCalendar = $(this);
$('.ui-datepicker-calendar').detach();
$('.ui-datepicker-close').click(function() {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
thisCalendar.datepicker('setDate', new Date(year, month, 1));
});
});
});
http://jsfiddle.net/tmnasim/JLydp/
Eigenschaften :
- nur Monat/Jahr anzeigen
- Fügt den Wert für den Monat und das Jahr in das Eingabefeld ein, wenn Sie auf die Schaltfläche "Fertig" klicken.
- Kein "Wiederöffnen"-Verhalten bei Klick auf "Fertig"
------------------------------------
eine andere Lösung, die gut für datepicker und monthpicker in der gleichen Seite arbeiten: (auch vermeiden den Fehler der mehrfachen Klick auf vorherige Schaltfläche in IE, die auftreten können, wenn wir Fokus-Funktion verwenden)
JS-Gefiedel-Link
Ich brauchte eine Monat/Jahr-Auswahl für zwei Felder (Von & Bis) und wenn eine ausgewählt wurde, wurde die Max/Min auf die andere gesetzt...a la Auswahl von Flugticketdaten. Ich hatte Probleme beim Festlegen der Maximal- und Minimalwerte... die Daten des anderen Feldes würden gelöscht werden. Dank einiger der oben genannten Beiträge habe ich es schließlich herausgefunden. Sie müssen die Optionen und Daten in einer ganz bestimmten Reihenfolge festlegen.
Die vollständige Lösung finden Sie in dieser Fiddle: Monat/Jahr-Auswahl @ JSFiddle
Code:
var searchMinDate = "-2y";
var searchMaxDate = "-1m";
if ((new Date()).getDate() <= 5) {
searchMaxDate = "-2m";
}
$("#txtFrom").datepicker({
dateFormat: "M yy",
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showAnim: "",
minDate: searchMinDate,
maxDate: searchMaxDate,
showButtonPanel: true,
beforeShow: function (input, inst) {
if ((datestr = $("#txtFrom").val()).length > 0) {
var year = datestr.substring(datestr.length - 4, datestr.length);
var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), "#txtFrom").datepicker('option', 'monthNamesShort'));
$("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
$("#txtFrom").datepicker('setDate', new Date(year, month, 1));
}
},
onClose: function (input, inst) {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
$("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
$("#txtFrom").datepicker('setDate', new Date(year, month, 1));
var to = $("#txtTo").val();
$("#txtTo").datepicker('option', 'minDate', new Date(year, month, 1));
if (to.length > 0) {
var toyear = to.substring(to.length - 4, to.length);
var tomonth = jQuery.inArray(to.substring(0, to.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
$("#txtTo").datepicker('option', 'defaultDate', new Date(toyear, tomonth, 1));
$("#txtTo").datepicker('setDate', new Date(toyear, tomonth, 1));
}
}
});
$("#txtTo").datepicker({
dateFormat: "M yy",
changeMonth: true,
changeYear: true,
showButtonPanel: true,
showAnim: "",
minDate: searchMinDate,
maxDate: searchMaxDate,
showButtonPanel: true,
beforeShow: function (input, inst) {
if ((datestr = $("#txtTo").val()).length > 0) {
var year = datestr.substring(datestr.length - 4, datestr.length);
var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
$("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
$("#txtTo").datepicker('setDate', new Date(year, month, 1));
}
},
onClose: function (input, inst) {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
$("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
$("#txtTo").datepicker('setDate', new Date(year, month, 1));
var from = $("#txtFrom").val();
$("#txtFrom").datepicker('option', 'maxDate', new Date(year, month, 1));
if (from.length > 0) {
var fryear = from.substring(from.length - 4, from.length);
var frmonth = jQuery.inArray(from.substring(0, from.length - 5), $("#txtFrom").datepicker('option', 'monthNamesShort'));
$("#txtFrom").datepicker('option', 'defaultDate', new Date(fryear, frmonth, 1));
$("#txtFrom").datepicker('setDate', new Date(fryear, frmonth, 1));
}
}
});
Fügen Sie dies auch in einen Stilblock ein, wie oben erwähnt:
.ui-datepicker-calendar { display: none !important; }