lunes, 2 de mayo de 2011

Posicionar jscalendar

5 horas!!!!
5 putas horas!!!
Esto es lo que yo llamo perder el tiempo!

Lo dejo aquí escrito por si a alguien le puede ayudar.

Situación:

Tengo una capa (div) llamemosla "padre" , que contiene capas dentro, llamemoslas "hija"
Cuando le doy a un botón +, por javascript introduzco una capa hija en la capa padre.
Están alineadas, de forma que crecen hacia la derecha, y si es necesario, la capa padre sacará un scroll horizontal.

¿hasta aquí ok?

Seguimos.

Ahora quiero que cada capa hija, tenga un campo para meter una fecha, y que esa fecha se meta con un jsCalendar, exactamente, con éste: http://www.dynarch.com/projects/calendar/

Primer problema... como cojones genero el codigo javascript que me dibuja y da vida al calendar?

Solución: (voy a evitar contaros las mil pruebas que he hecho hasta que he encontrado la solución perfecta, voy a ella)

Poner un evento onclick en el botón + para que, además de generar la nueva capa por javascript, con todas sus cosas (incluido el boton del calendario) dentro, genere este script y cuando le des al boton de calendar ya esté todo creado.

onclick="abreCalendario(getNbJornada('competicion_1');"

function abreCalendario(nombre){
Calendar.setup({trigger : 'boton_fecha_'+nombre,
inputField : 'input_fecha_'+nombre,
weekNumbers : false,
selection : Calendar.dateToInt(new Date()),
dateFormat : '%d/%m/%Y',
ifFormat : '%d/%m/%Y',
align : 'BR'
});
}

Esto, lo podéis configurar como os salga de la ... (puede haber niños...) de la punta de la nariz.
¿cómo se hace? RTFM

Problema 2: cuando haces click en el botón del calendario, aparece el calendario... siempre al ladito del botón según las coordenadas.... DE LA PÁGINA.

¿Problema? el maldito scroll horizontal!!!!
Pasa que cuando por meter capas hijas ha saltado el scroll... según lo ves tu en tu pantalla, puede ser que estés en la posicion 1000, pero para el calendario que lo mira según la página... tu posición mil... será para el la... yo que se... depende de la cantidad de scroll que hay... por ejemplo la 4815162342

Así que el calendario sale a tomar por culo.

Solución: Después de leerme mil manuales, de intentar hacer todo lo que mis pocos conocimientos de javascript me permiten, de probar a insultarle y escupirle, de mirarle con el ceño fruncido, de probar todo lo que se me ha ocurrido...

Me he metido en la libreria del jsCalendar, después de formatear el texto... en la linea 710. Buscar un "this.showAt(i.x,i,y,!0)"

Y he cambiado los i.x,i.y primero por un 100,100 y... MAGIA, el calendario ha salido en la posición 100,100 de la página!!!
Ahora sólo me queda ponerlo donde yo quiera dinámicamente...
Así que dejo esa parte de esta forma: "this.showAt(posXCalendar,posYCalendar,!0)" con dos variables globales de javascript.

Y así cada vez que añado una capa hija, tan sólo tengo que pillar la posición del botón del calendar e igualar las variables.

¿Cómo se hace?
La posición X se saca con boton.offsetLeft
La posición Y se saca con boton.offsetTop

Problema: 4 horas... y resulta que no he hecho nada!!! el calendario me sale donde al principio, a tomar viento!!!!

Solución:
boton.offsetLeft boton.offsetTop devuelven las coordenadas de un objeto dentro de la página, pero yo las quiero segun la pantalla!!!!
Se me ha ocurrido, que seguro que había alguna forma ver donde haces click con el ratón, y entonces... posicionar el calendar ahí, ahora que lo puedo poner donde quiera!

Así que he buscando, y creando un evento onclick en el botón del calendar, puedo pasarle el "evento del ratón" a una funcion para capturar la x,y del ratón

onclick='posicionCalendario(event);'

function posicionCalendario(event){
posXCalendar = event.screenX;
posYCalendar = event.screenY;
}

Premio!!! ya lo tengo.... ¿o no?

Como algunos sabréis, trabajo con 2 monitores, así que paso la pantalla del navegador al otro monitor y.... OSTIAS, NO FUNCIONA.

pongo un alert para ver qué posicion x,y me esta pillando... y resulta, que como la otra pantalla no es la principal... la posicion Y me la saca bien... pero lo X no, me saca -540

Problema: Si la referencia "pagina" es la pagina web, y la referencia "screen" es la pantalla, y ni una ni la otra me sirve... ¿qué hago?

Pues como todo en esta vida... y si has llegado hasta aquí leyendo será porque has hecho lo mismo que yo, buscar información porque algo tiene que haber! Pero tu has tenido suerte... has encontrado mi post.
Yo, he tenido que mirar la api para encontrar que lo que hay que poner en la funcion es:

function posicionCalendario(event){
posXCalendar = event.clientX;
posYCalendar = event.clientY;
}

Y con eso, consigues un punto intermedio entre "pagina" y "screen" que es la posición del "cliente" o navegador.

Como estoy hasta las narices de perder el tiempo... si no ha quedado claro, preguntáis en los comentarios y en cuanto pueda os contesto.

Ah! y sí, seguramente habrá alguna forma de configurar la librería para que no haya que hacer este apaño... pero a veces el camino más corto entre dos puntos, no es la linea recta.


Edito la entrada... un par de horas más tarde... cuando he contuado con el proyecto... y he tenido que bajar la página :(

La movida, es que el event.y te da la posición del ratón respecto a la ventana, sin embargo, cuando bajas la pagina, sí que quiero saber la posición, respecto de la página, no del ratón, así pues, la función final queda así:


function posicionCalendario(nombre,event){
posXCalendar = event.clientX;
posYCalendar = document.getElementById(nombre).offsetTop;
}


Actualización, un día más tarde.


Pues me sigue tocando las narices!

He puesto ahora el calendario dentro de una tabla... y se vuelve a ir de madre.

Buscando información, he encontrado que el offsetTop te devuelve la posición "relativa al padre", así que si se quiere saber la de una página, hay que hacer un bucle hasta llegar al "padre null"

while (elem = elem.offsetParent) {
y += elem.offsetTop;
}

Total, que la funcion me ha quedado así:


function posicionCalendario(nombre,event){

posXCalendar = event.clientX;

var boton = document.getElementById(nombre);

var offSetTop = 0;

var elem = boton;

while (elem = elem.offsetPar ent) {

offSetTop += elem.offsetTop;

}

posYCalendar = offSetTop;

}

No hay comentarios:

Publicar un comentario