jueves, 27 de agosto de 2009

Mudanza

Dado que Wordpress es mucho mejor que Blogspot y tiene más futuro, he mudado la web. Me ha costado un tiempo, así que he ido añadiendo entradas nuevas según traspasaba las anteriores. La dirección es la siguiente:

Constructor sobrecargado

No voy a actualizar este blog, así que por favor seguid las actualizaciones en Wordpress.

jueves, 6 de agosto de 2009

Abrir reproductor en ventana nueva mediante javascript

Necesitaba que un reproductor basado en jQuery se cargase en un popup y desapareciese de la ventana original para que el usuario pudiese navegar por la página y seguir escuchando las canciones sin interrupción.

Decidí usar variables de sesión. En la página original condicioné que se mostrase el reproductor a si la siguiente variable era falsa:


if Session("ventana_reproductor_abierta") = false then

...

end if


Al reproductor le añadí un enlace y usé jQuery para enlazarle el evento.


//Busco el enlace al que hay que añadirle el evento click.

var botonReproductorVentanaNueva = $('#columnaUno #reproductor-ventana-nueva');

botonReproductorVentanaNueva.click(function(){

abrePopup('carga_reproductor_ventana.asp','Titulo',300,400);


});

function abrePopup(url,titulo,h,w){

newwindow=window.open(url,titulo,'height=' + h + ',width=' + w);
if (window.focus) {newwindow.focus()}
return false;

}


El script ASP 'carga_reproductor_ventana.asp' se asegura de establecer la variable de sesión a verdadero, de manera que al recargarse la página original no se muestre el reproductor:


Session("ventana_reproductor_abierta") = true


Ahora viene la parte difícil. Necesitamos que cuando la ventana abierta se cierre, se devuelva la variable de sesión a falso y se recargue la página que lanzó el popup. Para ello necesitamos una función poco documentada llamada window.onbeforeunload que se lanza cuando uno cierra la ventana. Además necesito llamar a otro script ASP mediante AJAX que se encargará de devolver la variable de sesión al valor adecuado.


//Funciones para el reproductor cargado en un popup.

$(document).ready(function(){

//Controlo el evento que se dispara cuando intenta quitar la página.

window.onbeforeunload = function() {

$.ajax({

contentType: 'application/x-www-form-urlencoded',
type: "GET",
url: "cierra_ventana_reproductor.asp"

});

window.opener.location.reload();


}

});


Como se ve, window.opener permite acceder a la ventana que llamó al popup, y location.reload() recarga la página. El script 'cierra_ventana_reproductor.asp' establece la variable de sesión al valor necesario.


<%

Session("ventana_reproductor_abierta") = false

%>

miércoles, 5 de agosto de 2009

Función que vacía campos de un formulario que tengan en el contenido un patrón común

$(document).ready(function(){

//Asume que los campos de tipo input text empiezan con "Escriba aquí...",
// y vacía esos campos en focus, siempre que tengan ese valor, y vuelve a escribir ese texto
// en blur si se ha dejado el campo vacío.

var campos=$("form :input[value *= Escriba aqu]");

$.each(campos,function(){

//Por cada campo, compruebo si el contenido contiene la cadena "escriba aqu".

var contenido=$(this).attr("value");

$(this).bind("focus", function(){

if ($(this).attr("value") == contenido){

$(this).attr("value","");

}

});

$(this).bind("blur", function(){

if ($(this).attr("value")==""){

//Ha dejado el campo vacío, así que vuelvo a ponerle de texto lo que había antes de entrar en el foco.

$(this).attr("value",contenido);

}

});


});


});

'player-viral.swf' y otros reproductores flash sin funcionar en ciertos servidores

Anduvimos con un problema de aparente difícil solución al implementar un reproductor programado en flash que cogía archivos de tipo flv. La solución, sobre todo cuando va en un servidor y no en otro, consiste en probar a descargarse directamente el fichero desde donde esté almacenado, en el servidor donde el reproductor no funcione. Si la respuesta del navegador es que no reconoce ese tipo de fichero o que no existe cuando sí debería de reconocerlo, es que no está añadido el MIME Type en IIS.

La siguiente página es una buena manera de empezar a buscar:

Adding .FLV MIME Type in IIS

Usar campos TEXT en consultas con GROUP BY en SQL

En ocasiones no queda más remedio que agrupar consultas, ya que hay que usar funciones de grupo como MIN, MAX, AVG, etc. En este caso necesitábamos un MIN(fecha), además de cargar campos de tipo TEXT que de manera normal no podrían agruparse. Si se hace lo siguiente, la consulta fallará:


SELECT descripcion ,
ficha ,
min(fecha) minfecha

from tabla

GROUP BY
descripcion ,
ficha

ORDER BY min(fecha)



Una consulta normalmente válida de este tipo, siendo los campos 'descripcion' y 'ficha' de tipo TEXT, fallará. Para ello tenemos que engañar convirtiendo los campos de tipo texto en cadenas con longitud limitada mediante la función SUBSTRING. La solución sería la siguiente:


SELECT substring(descripcion,1,500) descripcion ,
substring(ficha,1,500) ficha ,
min(fecha) minfecha

from tabla

GROUP BY
substring(descripcion,1,500) ,
substring(ficha,1,500)

ORDER BY min(fecha)

CONCAT en SQL Server

CONCAT es una función propia de MySQL y Oracle que sirve para juntar diferentes campos y cadenas para que se muestren como una en una consulta de SQL. Por desgracia, no puede usarse en SQL Server. Para ello podríamos hacer lo siguiente:

SELECT id,nombre_es + ' (' + tipo + ')' FROM tabla ORDER BY nombre_es asc

martes, 4 de agosto de 2009

Error de javascript en IE, sin problemas en Mozilla

Cuando surja un error en IE que impida que algún script funcione, hay que fijarse en las diferencias en interpretación y capacidad para evitar ciertos errores. Nos hemos pasado un buen rato intentando descubrir qué parte del código daba problemas, y resulta que IE no consigue interpretar arrays a cuyo último elemento le sigue una coma. Mozilla lo interpreta sin problemas.

El código era el siguiente:


function almacenaReproduccion(){


var cancion = myPlayList[playItem].filename;

//Los dos otros datos que necesito guardar son el id de la sesión y la fecha y hora
// actual, pero los recojo en el servidor.

$.ajax({

contentType: 'application/x-www-form-urlencoded',
type: "GET",
url: "../web/cuenta_reproduccion.asp",
data: "archivo=" + myPlayList[playItem].filename

});


}


El error se encontraba en la línea siguiente:

data: "archivo=" + myPlayList[playItem].filename

Anteriormente terminaba en una coma, ya que en el pasado le seguía otro parámetro. Como he dicho, Mozilla lo entendía e IE no. Algo a tener en cuenta.

Guardar una cuenta de reproducciones usando AJAX en ASP

Primero localizamos el botón de play del reproductor y asociamos una función al evento click:


var botonPlay = $('#player_play_archivos');

$(botonPlay).click(function(){

$('#jquery_jplayer').play();

//Necesito los datos de la canción que se está escuchando en este momento.

almacenaReproduccion();

});


La función almacenaReproduccion() coge el nombre del archivo (en el ejemplo, la ruta completa), y la envía por AJAX al servidor.


function almacenaReproduccion(){


var cancion = myPlayList[playItem].filename;

//Los dos otros datos que necesito guardar son el id de la sesión y la fecha y hora
// actual, pero los recojo en el servidor.

$.ajax({

contentType: 'application/x-www-form-urlencoded',
type: "GET",
url: "cuenta_reproduccion.asp",
data: "archivo=" + myPlayList[playItem].filename,

});


}



Como se ve, se llama a un archivo llamado 'cuenta_reproduccion.asp'. En el servidor añado el ID de la sesión actual y la fecha y la hora en la que se ha reproducido el archivo.



dim archivo
archivo = LimpiarRequest(Request("archivo"))

dim intCurrentPos, intFileNamePos

'Cojo el nombre del archivo encontrando la última barra
Do

intCurrentPos = InStr(intCurrentPos + 1, archivo, "/", vbTextCompare)
If intCurrentPos <> 0 then
intFileNamePos = intCurrentPos
else
intFileNamePos = intFileNamePos + 1
Exit Do
End If
Loop

dim FileName

If intFileNamePos <> 1 then

FileName = mid(archivo, intFileNamePos, len(archivo) - intFileNamePos + 1)

End If

'FileNamewExt contiene el nombre del archivo, sin la ruta.

'Necesitamos tanto el id de la sesión y la fecha y hora actuales.

dim idSesion,momentoActual

idSesion = Session.SessionID

momentoActual = now()

'Envío los datos a la consulta que realiza la inserción.

dim resultado

set resultado = setCuentaReproduccion(FileName,idSesion,momentoActual)

'response.write(resultado)



lunes, 3 de agosto de 2009

Problemas con la sesión y objetos desconocidos al trabajar con AJAX en PHP

En un script, llamémosle script1.php, llamaba mediante jQuery a otro script, llamémosle script2.php, intentaba acceder a los datos de la variable $_SESSION. A pesar de establecer el session_start(), y ver mediante el Firebug que podía ver la información, no podía acceder por programación a los atributos de la clase con la que tenía que trabajar. El Firebug la definía de la siguiente manera:

__PHP_Incomplete_Class Object ( [__PHP_Incomplete_Class_Name] ...

Obviamente sugiere que la clase no existe. La solución está en cargar un include o un require con la definición de la clase antes de session_start().

sábado, 1 de agosto de 2009

Explode en jQuery y javascript

Explode es una manera muy útil de sacar información de algún elemento de la web, ya que, por ejemplo, suelo almacenar ids de elementos de la base de datos como parte del nombre de un id o de una clase. Aquí tenemos un ejemplo de explode en jQuery, que sería un split:

var valor=$('#elemento').attr('id').split('filtro-id')[1];

La variable 'valor' contendría ahora 'id'.