Un Date Range Slider pour vos projet MVC
Un Date Range Slider est le mariage entre un Range Slider (un composant graphique permettant de sélectionner une plage de valeurs, soit un minimum et un maximum) et un Date Picker.
Voici un petit aperçu du composant :

Au début je pensais que le composant
MVC Telerik Slider prenait en charge ce type de comportement mais en fait non, le composant ne gère que des nombres.
L'astuce est donc de traduire à la volée le chiffre minimum et le chiffre maximum en date. Pour cela je prends une date pivot qui correspond à ma date minimum. Cette date pivot sera le minimum saisissable dans le Slider. Pour chaque nombre (le minimum saisissable, le minimum choisit, le maximum choisit, le maximum saisissable) je compte le nombre de jours par rapport à cette date pivot et donc j'en déduis les dates.
Voici le code razor pour définir le composant Slider :
<div id="timewrapper">
@(Html.Telerik().RangeSlider<int>()
.Name("DateRange")
.Tooltip(tooltip => tooltip.Enabled(false))
.ClientEvents(events => events
.OnChange("CustomTelerikExtensions.dateRangeSlider().updateDates")
.OnSlide("CustomTelerikExtensions.dateRangeSlider().updateDates"))
.Min(1)
.Max(22)
.Values(1, 22)
.SmallStep(1)
.LargeStep(21)
.Orientation(SliderOrientation.Horizontal)
.TickPlacement(SliderTickPlacement.BottomRight)
)
</div><p>
Début : <span id="minValueDiv"></span>
<br />
Fin : <span id="maxValueDiv"></span>
</p>Je dois cacher le tooltip car le composant Telerik ne permet pas de surcharger son rendu. Si quelqu'un a une technique je suis preneur :)
J'indique donc la fonction à exécuter sur le changement ou le slide : updateDates.
Voici le code JavaScript pour gérer l'affichage et le calcul des dates :
<script type="text/javascript">
(function () {
CustomTelerikExtensions = window.CustomTelerikExtensions || {};
CustomTelerikExtensions.dateRangeSlider = function (tId, minValueId, maxValueId, pDate, step) {
var self = this;
self.id = tId ? tId : "timewrapper";
self.minBlocId = minValueId ? minValueId : "minValueDiv";
self.maxBlocId = maxValueId ? maxValueId : "maxValueDiv";
self.pivotDate = pDate ? pDate : new Date();
self.col = $("#" + self.id + " .t-tick-large .t-label");
self.largeStep = step ? step : 21;
self.formatDate = function (d) {
var day = d.getDate();
var month = d.getMonth() + 1;
day = (day < 10) ? "0" + day : day;
month = (month < 10) ? "0" + month : month;
return day + "/" + month;
};
var my = {};
my.init = function (min, max) {
my.updateValues(min, max);
};
my.updateDates = function (e) {
var rangeSlider = $(this).data('tRangeSlider');
var start = e.values[0];
var end = e.values[1];
my.updateValues(start, end);
};
my.updateValues = function (valueMin, valueMax) {
var fDate = new Date(self.pivotDate);
for (var i = 0; i < self.col.length; i++) {
var j = (i < 1) ? 0 : self.largeStep;
fDate.setDate(fDate.getDate() + j);
var d = fDate.getDate();
var m = fDate.getMonth() + 1;
d = (d < 10) ? "0" + d : d;
m = (m < 10) ? "0" + m : m;
var txt = d + "/" + m;
$(self.col[ i ]).text(txt);
}
var min = new Date(self.pivotDate);
min.setDate(min.getDate() + valueMin - 1);
$("#" + self.minBlocId).html(self.formatDate(min));
var max = new Date(self.pivotDate);
max.setDate(max.getDate() + valueMax - 1);
$("#" + self.maxBlocId).html(self.formatDate(max));
};
return my;
};
})();
</script>Il reste à initialiser une première fois les dates à l'affichage de la page :
<script type="text/javascript"> $(function () {
CustomTelerikExtensions.dateRangeSlider().init(1, 22);
});</script>Pour que le code fonctionne, il faut que la propriété LargeStep du RangeSlider possède la même valeur que la variable largeStep de la classe JavaScript dateRangeSlider.
Par défaut le code utilisera le slider contenu dans un bloc HTML avec l'Id "timewrapper", et les éléments HTML "minValueDiv" et "maxValueDiv" pour l'affichage des dates sélectionnées. La date pivot par défaut et la date du jour et le largeStep par défaut est de 21 jours.
Ces éléments peuvent être bien sûr redéfinis dans la création de la classe dateRangeSlider.
Pour utiliser le code et le rendre dynamique, il reste donc à utiliser des propriétés du ViewModel mais pour cela je vous laisserez écrire le code qui n'a rien de compliqué.
Il doit sûrement rester beaucoup de points d'optimisation du code, si vous avez des questions ou suggestions n'hésitez pas.
Julien Lefebvre
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :