web-dev-qa-db-fra.com

jQuery datepicker - 2 entrées / zones de texte et plage de restriction

J'utilise le widget jQuery Datepicker avec deux zones de saisie, une pour la date "De" et la seconde avec la Date "à" . J'utilise la démo fonctionnelle jQuery Datepicker comme base pour faire fonctionner les deux zones de saisie, mais je dois pouvoir ajouter ces restrictions supplémentaires:

  1. La plage de dates ne peut pas être antérieure au 01 décembre 2008

  2. La date "À" ne peut pas être postérieure à aujourd'hui

  3. Lorsqu'une date "De" est sélectionnée, la date "A" ne peut se situer que dans une plage de 7 jours après la date "De"

  4. Si une date "À" est sélectionnée en premier, alors la date "De" la date ne peut être comprise que dans la plage de 7 jours avant la date "À" (la limite du 01 décembre étant la première date sélectionnable)

Je n'arrive pas à faire fonctionner tous les éléments ci-dessus ensemble.

En résumé, je voudrais pouvoir sélectionner une plage allant jusqu'à 7 jours entre le 01 décembre et aujourd'hui (je me rends compte que je poste ceci le 1er décembre donc je n'obtiendrai qu'aujourd'hui pour le moment).

Mon code jusqu'à présent

$(function () {

$('#txtStartDate, #txtEndDate').datepicker(
            {
            showOn: "both",
            beforeShow: customRange,
            dateFormat: "dd M yy",
            firstDay: 1, 
            changeFirstDay: false
            });
});

function customRange(input) 
{ 

return {
         minDate: (input.id == "txtStartDate" ? new Date(2008, 12 - 1, 1) : null),
         minDate: (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate") : null), 
         maxDate: (input.id == "txtStartDate" ? $("#txtEndDate").datepicker("getDate") : null)
       }; 
}

Il me manque la restriction de plage de 7 jours et j'empêche également une sélection de date "À" avant le 01 décembre 2008 ou après aujourd'hui. Toute aide serait très appréciée, merci.

51
Russ Cam

Merci beaucoup pour votre aide Ben, je me suis appuyé sur vos messages et j'ai trouvé cela. Il est maintenant terminé et fonctionne à merveille!

Voici un Démo de travail. Ajoutez /éditez à l'URL pour voir le code

Code complet ci-dessous-

$(function () 
{   
    $('#txtStartDate, #txtEndDate').datepicker({
        showOn: "both",
        beforeShow: customRange,
        dateFormat: "dd M yy",
        firstDay: 1, 
        changeFirstDay: false
    });

});

function customRange(input) { 
    var min = new Date(2008, 11 - 1, 1), //Set this to your absolute minimum date
        dateMin = min,
        dateMax = null,
        dayRange = 6; // Set this to the range of days you want to restrict to

    if (input.id === "txtStartDate") {
        if ($("#txtEndDate").datepicker("getDate") != null) {
            dateMax = $("#txtEndDate").datepicker("getDate");
            dateMin = $("#txtEndDate").datepicker("getDate");
            dateMin.setDate(dateMin.getDate() - dayRange);
            if (dateMin < min) {
                dateMin = min;
            }
        }
        else {
            dateMax = new Date; //Set this to your absolute maximum date
        }                      
    }
    else if (input.id === "txtEndDate") {
        dateMax = new Date; //Set this to your absolute maximum date
        if ($("#txtStartDate").datepicker("getDate") != null) {
            dateMin = $("#txtStartDate").datepicker("getDate");
            var rangeMax = new Date(dateMin.getFullYear(), dateMin.getMonth(),dateMin.getDate() + dayRange);

            if(rangeMax < dateMax) {
                dateMax = rangeMax; 
            }
        }
    }
    return {
        minDate: dateMin, 
        maxDate: dateMax
    };     
}
49
Russ Cam

Je me rends compte que je suis un peu en retard à la fête, mais voici comment j'ai modifié l'exemple de code de travail. Je n'avais pas besoin de définir une date maximale et minimale spécifique, je ne voulais tout simplement pas que la plage de dates se chevauche, alors je les laisse simplement se définir:

jQuery(function() {
  jQuery('#calendardatetime_required_to, #calendardatetime_required_from').datepicker('option', {
    beforeShow: customRange
  });
});

function customRange(input) {
  if (input.id == 'calendardatetime_required_to') {
    return {
      minDate: jQuery('#calendardatetime_required_from').datepicker("getDate")
    };
  } else if (input.id == 'calendardatetime_required_from') {
    return {
      maxDate: jQuery('#calendardatetime_required_to').datepicker("getDate")
    };
  }
}

(Mes sélecteurs de dates ont déjà été initialisés dans un script plus haut, mais ce ne sont que des paramètres par défaut.)

Semble faire ce dont j'ai besoin :)

Voir ici pour mon exemple.

14
Robin Duckett

D'accord, que pensez-vous de cela:

function customRange(input) 
{ 
    var min = new Date(2008, 12 - 1, 1);
    var dateMin = min;
    var dateMax = null;

    if (input.id == "txtStartDate" && $("#txtEndDate").datepicker("getDate") != null)
    {
        dateMax = $("#txtEndDate").datepicker("getDate");
        dateMin = $("#txtEndDate").datepicker("getDate");
        dateMin.setDate(dateMin.getDate() - 7);
        if (dateMin < min)
        {
            dateMin = min;
        }           
    }
    else if (input.id == "txtEndDate")
    {
        dateMax = new Date();
        if ($("#txtStartDate").datepicker("getDate") != null)
        {
            dateMin = $("#txtStartDate").datepicker("getDate");
            dateMax = $("#txtStartDate").datepicker("getDate");
            dateMax.setDate(dateMax.getDate() + 7); 
        }
    }
    return {
     minDate: dateMin, 
     maxDate: dateMax
   }; 

}

C'est le mieux que j'ai pu trouver qui réponde à toutes vos exigences (je pense ...)

14
Ben Koehler

Votre date de début pour txtStartDate ne fonctionne pas, car votre deuxième minDate est défini sur null lors de la deuxième vérification du fichier input.id. De plus, maxDate devrait vérifier txtEndDate, pas txtStartDate. Essaye ça:

    function customRange(input) 
{ 
    var mDate = (input.id == "txtStartDate" ? new Date(2008, 12 - 1, 1) : $("#txtStartDate").datepicker("getDate"));
    return {
         minDate: mDate, 
         maxDate: (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate").getDate() + 5 : null)
       }; 
}

Je ne sais pas pourquoi le '+ 5' au lieu de '+ 7', mais si j'ajoute 0, j'obtiens une plage de dates sélectionnable du jour que j'ai choisi plus le suivant.

4
Ben Koehler

Envisagez d'utiliser rangeSelect pour avoir un contrôle au lieu de deux.

Pour obtenir ce que vous recherchez, je suppose que vous devez ajouter un écouteur onSelect, puis appeler datepicker( "option", settings ) pour modifier les paramètres.

4
kgiannakakis

Voici une solution que j'ai trouvée après beaucoup de recherches pour trouver une solution à ce que je pense être un problème commun. Cela "rebondit" efficacement les entrées autour d'une plage d'entrée partagée de jours compatibles. Signification - si j'ai deux champs, l'un peut être utilisé pour contraindre l'autre, et l'autre pourrait redéfinir l'original si nécessaire. Le but de ceci est de toujours s'assurer qu'il n'y a qu'une plage finie de jours (ou mois ou autre) entre les deux champs. Cet exemple spécifique limite également la durée dans le temps à laquelle quelque chose pourrait être sélectionné dans l'un ou l'autre domaine (par exemple 3 mois).


$("#startdate").datepicker({
   minDate: '+5', 
   maxDate: '+3M',
   changeMonth: true,
   showAnim: 'blind',
   onSelect: function(dateText, inst){ 

    // Capture the Date from User Selection
    var oldDate = new Date(dateText);
    var newDate = new Date(dateText);

    // Compute the Future Limiting Date
    newDate.setDate(newDate.getDate()+5);


    // Set the Widget Properties
    $("#enddate").datepicker('option', 'minDate', oldDate);
    $("#enddate").datepicker('option', 'maxDate', newDate);

    }
  });

 $("#enddate").datepicker({
  minDate: '+5',
  maxDate: '+3M',
  changeMonth: true,
  showAnim: 'blind', 
  onSelect: function(dateText, inst){ 

    // Capture the Date from User Selection
    var endDate = new Date(dateText);
    var startDate = new Date(dateText);

    // Compute the Future Limiting Date
    startDate.setDate(startDate.getDate()-5);

    // Set the Widget Properties
    $("#startdate").datepicker('option', 'minDate', startDate);
    $("#startdate").datepicker('option', 'maxDate', endDate);

    }

  });
4
David Bigelow

voici comment je l'utilise:

function customRange(input)
{
    var min = new Date();
    return {
        minDate: ((input.id == "txtStartDate") ? min : (input.id == "txtEndDate" ? $("#txtStartDate").datepicker("getDate") : null)),
        maxDate: (input.id == "txtStartDate" ? $("#txtEndDate").datepicker("getDate") : null)
    };
}
3
gaby

Voilà comment je l'ai fait. J'ai pris la source sur le site Web de l'interface utilisateur Jquery et l'ai modifiée pour ajouter vos contraintes.

$(document).ready(function ()
{      
  var dates = $('#StartDate, #EndDate').datepicker({
        minDate: new Date(2008, 11, 1), 
        maxDate: "+0D",
        dateFormat: "dd M yy",
        changeMonth: true,
        changeYear: true,
        onSelect: function (selectedDate)
        {
            var option = this.id == "StartDate" ? "minDate" : "maxDate",
                instance = $(this).data("datepicker"),
                date = $.datepicker.parseDate(
                    instance.settings.dateFormat ||
                    $.datepicker._defaults.dateFormat,
                    selectedDate, instance.settings);
            var edate;
            var otherOption;
            var d;
            if (option == "minDate")
            {
                otherOption = "maxDate";
                d = date.getDate() + 7;
            }
            else if (option == "maxDate")
            {
                otherOption = "minDate";
                d = date.getDate() - 7;
            }

            var m = date.getMonth();
            var y = date.getFullYear();
            edate = new Date(y, m, d);

            dates.not(this).datepicker("option", option, date);
            dates.not(this).datepicker("option", otherOption, edate);
        }
    });
});

Idée initiale de: http://jqueryui.com/demos/datepicker/#date-range

Remarque: Vous auriez également besoin d'une option pour réinitialiser/effacer les dates (c.-à-d. Si un utilisateur choisit une date de début, la date de fin devient limitée. Après avoir choisi une date de début si l'utilisateur choisit maintenant une date de fin, la date de début est également limitée. Vous devez avoir une option claire pour permettre à l'utilisateur de choisir une autre date de début maintenant.)

0
escist