31 votes

Sélecteur de date jQuery Mobile

Y a-t-il quelqu'un qui a un bon sélecteur de date pour jQuery mobile ?

Je vais laisser l'utilisateur sélectionner une date "de" et une date "à" et je n'ai rien trouvé de bien pour cette situation.

Des idées ?

30voto

sustainablepace Points 886

Je suggère Datebox

https://github.com/jtsage/jquery-mobile-datebox

ou Mobiscroll

http://mobiscroll.com/

Si vous voulez quelque chose à la sauce Android, essayez mon propre Mobi Pick.

http://mobipick.sustainablepace.net/

19voto

dioslaska Points 2393

Essayez Mobiscroll un afficheur de dates personnalisable et optimisé pour les appareils tactiles.

6voto

Tushar Ahirrao Points 2189

Voici le sélecteur de date spécialement conçu pour les téléphones portables.

http://jquerymobile.com/demos/1.0a4.1/experiments/ui-datepicker/

5voto

Aureltime Points 226

J'ai travaillé sur la mise à jour du datepicker jquery ui aux dernières versions de jquery , jqueryui et jquery mobile donc pour jq1.9.1 jqui 1.10.2 et jqm 1.3.0. J'ai préféré laisser telle quelle ma réponse précédente pour que vous puissiez voir comment elle a évolué.

le menu déroulant "changeMonth" et "changeYear" a dû faire l'objet d'une attention particulière pour fonctionner (les erreurs de manipulation étaient fréquentes).

Voici comment j'ai mis à jour l'afficheur de date expérimental de jqueryui pour jqmobile :

js bin code snippet

Vous pouvez établir un lien vers le script du datepicker au lieu de l'ensemble du paquet jqueryui.

L'option readonly empêche le clavier d'apparaître sur ios.

C'est juste une modification du datepicker pour le faire fonctionner sur jqm, le but serait de pouvoir surcharger la fonction _generatehtml du widget datepicker et de pouvoir donner en entrée le thème jquery mobile à utiliser. Ainsi, vous n'aurez pas besoin de tout ce tas d'addClass et éviterez toute manipulation inutile du DOM.

Je n'ai testé que pour ios 6 (iphone, ipad) et desktop (chrome, firefox, safari), faites-nous part des autres tests.

J'espère que cela vous aidera autant que vous en avez besoin :)

voici tout le code séparé en html, js et css :

HTML

<!DOCTYPE html> 
<html> 
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <title>Jqueryui 1.10.2 datepicker Integration in jquery mobile 1.3.0 and jquery 1.9.1 by aureltime</title> 
    <link rel="stylesheet" href="http://stackoverflow.com//ajax.aspnetcdn.com/ajax/jquery.mobile/1.3.0/jquery.mobile-1.3.0.min.css">
    <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"></script>
    <script src="//ajax.aspnetcdn.com/ajax/jquery.mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
</head> 
<body>  
<div data-role="page">
    <div data-role="header">
        <h1>jQuery UI's Datepicker Styled for mobile adapted by Aureltime</h1>      
    </div>
    <div data-role="content">
        <form action="#" method="get" id="form">
            <div data-role="fieldcontain">
                <label for="date">Date:</label>
                <input type="date" name="date" id="date" value=""  />
            </div>      
        </form>
    </div>
</div>
</body>
</html>  

JS

//reset type=date inputs to text
$.mobile.page.prototype.options.degradeInputs.date = true;

$("#form").trigger("create");
$( document )
  .on( "pageinit", function(){

$("#date")
    .prop("readonly", "true")
    .on("click", function(){
$input=$(this);
$next=$input.next();

if($next.hasClass("hasDatepicker"))
  $next.hide();

$input
      .hide()
      .after( $( "<div />", {   id  :   "datepicker_"+$input.attr("id")}).datepicker(
        {
          altField          : "#" + $input.attr( "id" ),
          altFormat         : "dd/mm/yy",
          defaultDate       : $input.val(),
          showOtherMonths   : true,
          selectOtherMonths : true,
          //showWeek        : true,
          changeYear        : true,
          changeMonth       : true,
          //showButtonPanel : true,
          //beforeShowDay   : beforeShowDay,
          onSelect          : function( dateText, inst)
          {             $("#datepicker_"+$input.attr("id")).hide();
$input.show();
          }
        }));
    });
        });

(function($, undefined ) {

    //cache previous datepicker ui method
    var prevDp = $.fn.datepicker;

    //rewrite datepicker
    $.fn.datepicker = function( options ){

        var dp = this;

        //call cached datepicker plugin
        prevDp.call( this, options );

        //extend with some dom manipulation to update the markup for jQM
        //call immediately
        function updateDatepicker(event){

          $( ".ui-datepicker-header", dp ).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
            $( ".ui-datepicker-prev, .ui-datepicker-next", dp ).attr("href", "#");
            $( ".ui-datepicker-prev", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-l", shadow: true, corners: true});
            $( ".ui-datepicker-next", dp ).buttonMarkup({iconpos: "notext", icon: "arrow-r", shadow: true, corners: true});
            $( ".ui-datepicker-calendar th", dp ).addClass("ui-bar-c");
            $( ".ui-datepicker-calendar td", dp ).addClass("ui-body-c");
            $( ".ui-datepicker-calendar a", dp ).buttonMarkup({corners: false, shadow: false}); 
            $( ".ui-datepicker-calendar a.ui-state-active", dp ).addClass("ui-btn-active"); // selected date
            $( ".ui-datepicker-calendar a.ui-state-highlight", dp ).addClass("ui-btn-up-e"); // today"s date

            if(typeof event != "undefined")
                {
                var classe= $(event.target).attr("class");
                //alert(classe);
                }
          $( ".ui-datepicker-calendar .ui-btn", dp ).each(function(){
                    var el = $(this);
                    var buttonText = el.find( ".ui-btn-text" );
                    // remove extra button markup - necessary for date value to be interpreted correctly
                    if(buttonText.length)
                        el.html( el.find( ".ui-btn-text" ).text() ); 
                    });
        //      }

        $( dp )
            .off()
            .on( "click", updateDatepicker)
            .find("select")
            .on( "change", function(event){updateDatepicker(event);});
        }

        //update now
        updateDatepicker();

        //return jqm obj 
        return this;
    };
})( jQuery );

CSS

div.hasDatepicker{ display: block; padding: 0; overflow: visible;  margin: 8px 0; }
.ui-datepicker {  overflow: visible; margin: 0; max-width: 500px;  }
.ui-datepicker .ui-datepicker-header { position:relative; padding:.4em 0; border-bottom: 0; font-weight: bold; }
.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { padding: 1px 0 1px 2px; position:absolute; top: .5em; margin-top: 0; text-indent: -9999px; }

.ui-datepicker .ui-datepicker-prev { left:6px; }
.ui-datepicker .ui-datepicker-next { right:6px; }
.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }
.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }
.ui-datepicker select.ui-datepicker-month-year {width: 100%;}
.ui-datepicker select.ui-datepicker-month, 
.ui-datepicker select.ui-datepicker-year { width: 49%;}
.ui-datepicker table {width: 100%; border-collapse: collapse; margin:0; }
.ui-datepicker td { border-width: 1px; padding: 0; text-align: center; }
.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em 0; font-weight: bold; margin: 0; border-width: 0; text-align: center; text-decoration: none; }

.ui-datepicker-calendar th { padding-top: .3em; padding-bottom: .3em; }
.ui-datepicker-calendar th span, .ui-datepicker-calendar span.ui-state-default { opacity: .3; }
.ui-datepicker-calendar td a { padding-top: .5em; padding-bottom: .5em; }

Voici la version mise à jour pour fonctionner avec jqm 1.4 : jsbin jqm 1.4.0

Il tient compte des changements de jquery mobile 1.4.0 et nécessite un peu moins de manipulation de dom

3voto

Aureltime Points 226

voici une copie de ma réponse à un autre message ici, concernant l'intégration de l'indicateur de date jqueryui dans le cadre de jquerymobile. j'espère que cela vous aidera, comme cela m'aurait aidé si cela existait :)

Après de nombreuses recherches sur Internet, notamment en comparant datebox et jqueryui datepicker (mobiscroll et mobipick ne me conviennent pas car je cherche une vue de calendrier), j'ai décidé d'utiliser ui datepicker pour plusieurs raisons :

  • Je l'utilise depuis longtemps, je le connais assez bien.
  • j'avais besoin du beforeShowDay (événement s'il est certainement possible d'avoir une fonction similaire en utilisant la datebox et les événements/callbacks) pour personnaliser les jours avec des classes
  • J'avais besoin d'un en-tête avec la possibilité de changer le mois et l'année (également possible dans la boîte de données).
  • avec cette expérience, je disposais déjà d'un afficheur de date avec un aspect et une apparence jquerymobile.

Je l'ai utilisé avec :

  • jquery 1.8.3
  • jquery mobile 1.2.0
  • jqueryui datepicker 1.8.21 ( Obtenez-le d'ici )

L'utilisation du sélecteur de date avec les versions plus récentes casse la mise en page lors du changement de mois/année.

de ici j'ai obtenu les fichiers dont j'avais besoin. J'ai utilisé plusieurs réponses que j'ai trouvées sur différentes questions de stackoverflow, pour faire les changements suivants :

  • pas de changement sur jquery.ui.datepicker.mobile.css
  • jquery.ui.datepicker.mobile.js nouveau code :

    (function ($, undefined) {
    
    //cache previous datepicker ui method
    var prevDp = $.fn.datepicker;
    
    //rewrite datepicker
    $.fn.datepicker = function (options) {
    
    var dp = this;
    
    //call cached datepicker plugin
    var retValue = prevDp.apply(this, arguments);
    
    //extend with some dom manipulation to update the markup for jQM
    //call immediately
    function updateDatepicker() {
        $(".ui-datepicker-header", dp).addClass("ui-body-c ui-corner-top").removeClass("ui-corner-all");
        $(".ui-datepicker-prev, .ui-datepicker-next", dp).attr("href", "#");
        $(".ui-datepicker-prev", dp).buttonMarkup({ iconpos: "notext", icon: "arrow-l", shadow: true, corners: true });
        $(".ui-datepicker-next", dp).buttonMarkup({ iconpos: "notext", icon: "arrow-r", shadow: true, corners: true });
        $(".ui-datepicker-calendar th", dp).addClass("ui-bar-c");
        $(".ui-datepicker-calendar td", dp).addClass("ui-body-c");
        $(".ui-datepicker-calendar a", dp).buttonMarkup({ corners: false, shadow: false });
        $(".ui-datepicker-calendar a.ui-state-active", dp).addClass("ui-btn-active"); // selected date
        $(".ui-datepicker-calendar a.ui-state-highlight", dp).addClass("ui-btn-up-e"); // today"s date
        $(".ui-datepicker-calendar .ui-btn", dp).each(function () {
            var el = $(this);
            // remove extra button markup - necessary for date value to be interpreted correctly
            // only do this if needed, sometimes clicks are received that don't require update
            // e.g. clicking in the datepicker region but not on a button.
            // e.g. clicking on a disabled date (from next month)
            var uiBtnText = el.find(".ui-btn-text");
            if (uiBtnText.length)
                el.html(uiBtnText.text());
        });
    };
    
    //update after each operation
    updateDatepicker();
    
       $( dp ).on( "click change", function( event, ui)
    {
    $target=$(event.target);
    if(event.type=="click" && ($target.hasClass("ui-datepicker-month") || $target.hasClass("ui-datepicker-year")))          
        event.preventDefault();
    else
        updateDatepicker( event);
    });
    
    //return jqm obj 
    if (retValue) {
        if (!retValue.jquery) return retValue;
    }
    return this;
    };
    
    })(jQuery);

J'utilise on() au lieu de l'événement click et je préviensDefault en cas de clic sur le menu de sélection du mois/de l'année.

Et je l'utilise de cette façon :

$form
    .trigger( "create" )
    .find( "input[type='date'], input:jqmData(type='date')")
    .each(function()
        {
        $(this)
            .after( $( "<div />" ).datepicker(
                {
                altField            : "#" + $(this).attr( "id" ),
                altFormat           : "dd/mm/yy",
                showOtherMonths     : true,
                selectOtherMonths           : true,
                showWeek            : true,
                changeYear          : true,
                changeMonth         : true,
                beforeShowDay       : beforeShowDay
                }));
        });

avec beforeShowDay qui est une fonction retournant un tableau (voir le manuel de jqueryui datepicker).

Cela fonctionne pour moi de cette façon et j'ai maintenant juste besoin d'ajouter des événements pour ne montrer le calendrier que lorsque l'entrée de la date a obtenu le focus.

Un lien vers l'exemple de jsbin

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X