Hola:
Tengo un problema con un datepicker creado con jQuery. En mi versión local funciona correctamente, el problema está en el servidor de producción. El problema es el siguiente:
Tengo un formulario que coge dos fechas (entrada y salida). Cuando cojo un mes con más de 30 días, al darle enviar me resta un día del de salida y de entrada.
Ejemplo:
Esperada: fecha entrada: 30/03 fecha salida: 31/03
Resultado: fecha entrada: 29/03 fecha salida: 30/03
Pero el problema no solo es ese, sino que tengo otro formulario con las mismas características (de hecho, el mismo código JavaScript, solo cambian los css) y este funciona correctamente. Probé a cambiar el formulario de la página que no funciona a la que si, pero nada. Os dejo el código:
Formulario que funciona:
<form id="reserva" action="#" class="contenido col-md-12" role="form" method="post" {{ form_enctype(formulario) }}> <br> <div class="form-group"> {{ form_label (formulario.fechaEntrada, '' ,{'label_attr':{'class':' contact col-sm-1 col-xs-3 control-label'}}) }} <div class="col-sm-3 reserva"> <div class="col-sm-12 input-group"> {{ form_widget (formulario.fechaEntrada,{'id':'datestart','attr':{'class':'form-control input-reserva'}}) }} <span class="input-group-addon"><i id="datestartButton" onclick="$('#datestart').datepicker();$('#datestart').datepicker('show');" style="cursor: pointer" class="fa fa-calendar fa-fw black"></i></span> </div> {{ form_errors (formulario.fechaEntrada) }} </div> <div class="col-sm-1"></div> {{ form_label (formulario.fechaSalida,'',{'label_attr':{'class':'contact col-sm-1 col-xs-3 control-label'}}) }} <div class="col-sm-3 reserva"> <div class="col-sm-12 input-group"> {{ form_widget (formulario.fechaSalida,{'id':'dateend','attr':{'class':'form-control input-reserva'}}) }} <span class="input-group-addon"><i onclick="$('#dateend').datepicker();$('#dateend').datepicker('show');" style="cursor: pointer" class="fa fa-calendar fa-fw black"></i></span> </div> {{ form_errors (formulario.fechaSalida) }} </div> <input class=" reserva pull-right btn btn-default botones btn-booking" type="submit" value="Change dates"/> </div> {{ form_rest(formulario) }} </form>
Formulario que no funciona:
<form action="" class="col-md-3 col-xs-10 reservas-portada " role="form" method="post" {{ form_enctype(formulario) }}> <div class="contenido-formulario"> <br> <span class="titulo-reserva" itemprop="legalName">{{ plantilla.empresa }}</span> <div class="clearfix"></div> <br> <div class="form-group col-md-11"> {{ form_label (formulario.fechaEntrada, '' ,{'label_attr':{'class':'col-sm-4 col-lg-5 col-xs-4 control-label'}}) }} <div class="col-sm-6 col-lg-7 col-xs-6 input-group"> {{ form_widget (formulario.fechaEntrada,{'id':'datestart','attr':{'class':'form-control input-reserva'}}) }} <span class="input-group-addon"><i id="datestartButton" onclick="$('#datestart').datepicker();$('#datestart').datepicker('show');" style="cursor: pointer" class="fa fa-calendar fa-fw black"></i></span> </div> {{ form_errors(formulario.fechaEntrada) }} </div> <div class="clearfix"></div> <div class="form-group col-md-11"> {{ form_label (formulario.fechaSalida, '' ,{'label_attr':{'class':'col-sm-4 col-lg-5 col-xs-4 control-label'}}) }} <div class="col-sm-6 col-lg-7 col-xs-6 input-group"> {{ form_widget (formulario.fechaSalida,{'id':'dateend','attr':{'class':'form-control input-reserva'}}) }} <span class="input-group-addon"><i onclick="$('#dateend').datepicker();$('#dateend').datepicker('show');" style="cursor: pointer" class="fa fa-calendar fa-fw black"></i></span> </div> {{ form_errors(formulario.fechaSalida) }} </div> <div class="clearfix"></div> <div class="btn-reservas"> <input class="btn btn-default botones btn-booking" type="submit" value="Check Availability"/> </div> <br> <div class="clearfix"></div> {{ form_rest(formulario) }} </div> </form>
Javascript:
$(document).ready(function () { $("#datestart").datepicker({ dateFormat: "dd/mm/yy", minDate: 0, onSelect: function (date) { var date2 = $('#datestart').datepicker('getDate'); date2.setDate(date2.getDate() + 1); $('#dateend').datepicker('setDate', date2); //sets minDate to dt1 date + 1 $('#dateend').datepicker('option', 'minDate', date2); } }); $('#dateend').datepicker({ dateFormat: "dd/mm/yy", onClose: function () { var dt1 = $('#datestart').datepicker('getDate'); var dt2 = $('#dateend').datepicker('getDate'); //check to prevent a user from entering a date below date of dt1 if (dt2 <= dt1) { var minDate = $('#dateend').datepicker('option', 'minDate'); $('#dateend').datepicker('setDate', minDate); } } }); });
La web en cuestión: http://uhuruheightsa.com/
Respuestas
He probado el datepicker en la web que comentas y todo parece que funciona bien. No tengo ningún problema con las fechas que selecciono, incluso en los meses de 31 días.
En cualquier caso, como el formulario que muestras parece correcto y el código JavaScript dices que te funciona perfectamente en otros proyectos, ¿es posible que el error se encuentre en la propia aplicación del backend? Si haces un dump()
en el controlador que procesa el formulario, ¿te llegan mal las fechas a ese punto ... o llegan bien y el problema sucede después?
@javiereguiluz
Yo lo acabo de probar y me falla. Si en la portada pongo
fecha de entrada: 31/03/2015 fecha de salida: 01/04/2015
luego en la pantalla de seleccionar habitación me pone:
fecha de entrada: 30/03/2015 fecha de salida: 31/03/2015
La cuestión es que en local funciona y el dump es correcto (en local).
¿Puede ser algun plugin de pagespeed de google que afecta a los JS?
@TsubasaAkai
Cuando selecciono el 31/03/2015
, al inspeccionar el elemento <input>
con el navegador, veo que el valor de su atributo value
es exactamente 31/03/2015
, así que parece que esa parte funciona bien.
Sin embargo, leyendo esta pregunta de StackOverflow veo que hablan del mismo problema que te sucede a ti. En una de las respuestas le aconsejan que utilice el formato completo de fecha y hora (con la hora a cero) para evitar esos problemas:
// en vez de esto new Date('2015-03-31'); // usa esto new Date('2015-03-31T00:00:00');
@javiereguiluz
Siento abusar, pero no tengo ni idea de dónde poner eso.
@TsubasaAkai
Lo lógico parece que sería configurar este formato de fecha en el propio código JavaScript. Sin embargo, he intentado forzarlo en el navegador y la página me ha devuelto el formulario con los errores generados desde el servidor. Así que te aconsejo en el controlador que procesa el formulario, manipules las fechas antes de utilizarlas en la consulta que realices.
@javiereguiluz
Al final encontré la solución yéndome a dormir. Cuando me desperté probé a forzarle la timezone en el formulario y al mostrar las fechas por pantalla:
$builder ->add('fechaEntrada', 'date', [ 'widget' => 'single_text', 'format' => 'dd/MM/yyyy', 'model_timezone' => 'Europe/Madrid', 'view_timezone' => 'Europe/Madrid', 'label' => $this->translator->trans('booking.form.checkin'), 'attr' => ['class' => 'datepicker', 'id' => 'datestart'], ]) ->add('fechaSalida', 'date', [ 'widget' => 'single_text', 'format' => 'dd/MM/yyyy', 'model_timezone' => 'Europe/Madrid', 'view_timezone' => 'Europe/Madrid', 'label' => $this->translator->trans('booking.form.checkout'), 'attr' => ['class' => 'datepicker', 'id' => 'dateend'] ]) ;
Y en en twig:
{{ pre.fechaSalida | date ('d/m/Y',"Europe/Madrid")}}
Hay veces que para encontrar la respuesta sólo hay que dejar de pensar en el problema.
@TsubasaAkai
Justo esta mañana he visto este issue en el repositorio de Symfony que creo que está muy relacionado con el problema que nos comentas: Date displayed as single_text is off by one
@javiereguiluz
Pues muchas gracias por ayudarme!
@TsubasaAkai