Objeto JSON, jQuery y PHP

eXtreM3

Buenas, estoy utilizando esta librería http://glad.github.io/glDatePicker/ , la cual tiene una propiedad que se llama "specialDates", para marcar días sueltos en el calendario.

Esa propiedad espera recibir un objeto con esta estructura

//    specialDates: [
    //        {
    //            date: new Date(0, 8, 5),
    //            data: { message: 'Happy Birthday!' },
    //            repeatYear: true,
    //            cssClass: 'special-bday'
    //        },
    //        {
    //            date: new Date(2013, 0, 8),
    //            data: { message: 'Meeting every day 8 of the month' },
    //            repeatMonth: true
    //        }
    //    ]

El caso es que tengo que obtener esas fechas especiales desde una base de datos llamando a mi controlador php, en el cual, después de hacer las consultas pertinentes, devuelvo esto:

echo json_encode(array('status' => 'ok', 'data' => $data, 'error_message' => null));

donde $data es la variable que guarda valores así:

{date:new Date(2015,0,29),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},
{date:new Date(2015,1,06),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},
{date:new Date(2015,1,27),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},

Realizo la petición por Ajax y guardo en una variable "specialDates" esa respuesta del controlador. Sin embargo si intento hacer esto

$("#mydate").glDatePicker({
	showAlways: true,
	allowMonthSelect: false,
	allowYearSelect: false,
    specialDates: [
        specialDates
    ],

Se peta y no pinta nada, dando un error de la librería del calendario. El caso es que si hago un console.log(specialDates) saca por consola la cadena esperada, si esa cadena la pego en el código tal que así:

$("#mydate").glDatePicker({
	showAlways: true,
	allowMonthSelect: false,
	allowYearSelect: false,
    specialDates: [
        {date:new Date(2015,0,29),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},
{date:new Date(2015,1,06),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},
{date:new Date(2015,1,27),data:{message:'closed'},repeatMonth:false,cssClass:'noday'},
    ],

Funciona perfectamente. ¿Qué se me está escapando? ¿Tiene que estar la cadena con algún formato concreto para que pueda leerla bien y funcione?

Gracias adelantadas ^^

RaymaN

El json devuelto por php está entrecomillado, por lo que, si no me equivoco, te devuelve

{"date":"new Date(2015,0,29)","data":{"message":"closed"},"repeatMonth":false,"cssClass":"noday"}

Luego, new Date, al ser un objeto, no puede estar entre comillas en js.

1 respuesta
eXtreM3

#2 gracias por contestar. Pero si al hacer un console.log(specialDates) lo imprime como debe, dónde está el error? Lo hago justo antes de llamar al calendario, por lo que no tendría que haber comillas extras añadidas por php... o es que internamente el tipo de variable es erróneo?

1 respuesta
RaymaN

#3 no sé si el navegador hace alguna conversión en consola, pero la respuesta de php es la que te he puesto 100% seguro. Lo que puedes hacer es borrar las comillas de new Date con una expresión regular para que js lo lea como objeto y no string.

1 respuesta
eXtreM3

#4 algo raro debe haber con las comillas sí. Estoy pasándole una exp reg y convierte unas sí y otras no, lo que me hace pensar que hay algo raro en el proceso intermedio.

Sigo investigando a ver si doy con la tecla ;)

MTX_Anubis

Lo que deberías hacer es mandar la fecha en un formato y parsearla cuando recibas los datos vaya.

Los JSON define los siguientes tipos:

  • Strings (entrecomillados)
  • Numeros (pues eso)
  • Arrays ([] y dentro va cualquiera de los 4 tipos)
  • Objetos (hash)
  • true, false, null

Si tu pones new Date() lo tomará como un string "new Date()" y si en la consola te sale eso es porque efectivamente es un string, si no te saldría la fecha y no new Date(). Si quieres puedes hacer un eval sobre ese string pero hacer eso es una aberración.

Vamos que no es tan listo como para decirle que lo que quieres es un objecto de fecha. Si especificas el formato de la fecha así "yyyy-MM-dd" pues puedes hacer algo así cuando recibas la petición por ajax

function response(data) {
 $.each(data,function(index,d) {
   d.date = new Date(d.date);
 };
 le metes las fechas al datepicker.
}
1 respuesta
eXtreM3

#6 efectivamente creo que la mejor solución es enviar el objeto y después parsearlo correctamente en lugar de intentar mandarlo ya "stringfiado", recorro con el each y a volar.

Mañana comento a ver qué tal me ha ido, gracias.

Usuarios habituales

  • eXtreM3
  • MTX_Anubis
  • RaymaN