Cerrar ventanas popup javascript

Puf!!!

Hacía mucho que tenia olvidado este pequeño blog, pero siempre termina consumiendome el tiempo de desarrollo y otros proyectos en los que ando mas tiempo; pero en ultimos días tuve un problema con una ventana popup la cual se generaba desde un link para impresión de reportes. La idea era abrir una ventana popup para generar un reporte y mandarlo a impresión y no podía faltar IE y sus problemas de compatibilidad.

<!--archivo: index.html-->
<a href="#" onclick="window.open("reporte.html","_reporte","{opciones}")">Imprimir Reporte</a>

Y para cerrar la ventana popup opté por la vía mas fácil y de lógica bastante coherente…

//archivo:reporte.html
window.print(this); //dialogo de impresión
window.close(this); //cerramos la ventana despues de hacer o no la impresión

Pues pareciera que todo bien, en FF y Chrome pero cuando intento ejecutarlo en IE8… Crash!!… el script simplemente no funciona, si envía el dialogo de impresión pero independientemente de que se aceptara la impresión o no, la ventana popup no se cerraba, e investigando un poco, en navegadores como FF y Chrome la ejecución de javascript se detiene al momento de terminar la creación del cuadro de dialogo de impresión, y cuando se cierra el código continua, en este caso window.close(); y para casos de IE+ el código se ejecuta completo, esto hace que el evento close() sea anulado por la acción del cuadro de dialogo, entonces la solución mas simple ha sido de la siguiente forma:

//archivo: reporte.html
window.print(this); //dialogo de impresion
window.onfocus = function(){
    window.close();
};//cuando regrese el control de foco, cerramos la ventana

De esta forma cuando el dialogo de impresión sea cancelado o mandado la impresión la ventana se cierra en cualquiera de los casos, porque al cerrar vuelve el control de foco a la ventana y se ejecuta el evento close() quedando asi compatible para todos los exploradores, y sin tanta complicación, espero les ayude a ustedes así como he disfrutado yo investigando.

Happy coding!! 🙂 Sigue leyendo

Escribir codigo HTML descriptivo y compatible

Estos son unos simples, sencillos pero efectivos pasos para desplegar código HTML, compatible, bello a la vista del explorador de código fuente del explorador y sobre todo comprensible para otros desarrolladores o programadores de acuerdo al caso:

1. HTML5 es la mejor opción del momento (no dejemos encapsulados en el tiempo los «strict»)

2. El titulo: Debe ser simple y limpio, puede ir el propósito de la pagina al principio, un separador y por ultimo el titulo del sitio.

3. CSS: Si existe una sola hoja de estilos los tipos y medios deben estar declarados dentro de la hoja de estilos y solo dar soporte a los navegadores mas actualizados, en caso de IE6 debe usarse un formato universal, recordemos que debajo de IE6 no hay «nada».


<!--[if!IE]><!-->
    <link rel="stylesheet" type="text/css" href="css/estilo.css"/>
<!--<![endif]-->
<!--[if gte IE 7]>
    <link rel="stylesheet" type="text/css" href="css/estilo.css" media="screen, projection"/>
<![endif]-->
<!--[if IE 6]>
    <link rel="stylesheet" type="text/css" href="http://universal-ie6-css.codegoogle.com/files/ie6.0.3.css" media="screen, projection"/>
<![endif]-->

4. Rutas de archivos, enlaces y recursos: Los sitios de recursos a archivos deben usarse rutas relativas a menos que se tenga contenido estático, pero lo primero es mejor por cuestiones de eficiencia.

5. El cuerpo de la pagina «BODY»: Es opciones aplicar un ID cuando es una pagina con un estilo único y que o contenga ningún estilo adicional o algún complemento que se deba mostrar en especial.

6. Usar bloques descriptivos:

<div id="menu-principal"></div>
<div id="sidebar"</div>
<div id="pie-pagina"></div>

5. Herencia de objetos DOM correctas: Utilizamos un encabezado <H1> para un subtitulo <H2> y así sucesivamente.

6. Todas las imágenes debes tener el atributo»alt», muchas veces no se logran renderizar imágenes por distintas razones y es mejor siempre tener un texto descriptivo alusivo a la imagen en cuestión, también se debe hacer uso de las propiedades «width» y «height» para una correcta renderización.

7. Se deben usar los «tags» apropiadamente: cuando se abre uno se debe cerrar:

<ul> <!--Se abre un tag-->
<li>Ejemplo 1</li>
<li>Ejemplo 2</li>
</ul> <!--y siempre se cierra-->

y no olvidar siempre usar los apropiados, siempre se tiene tendencia a usar los equivocados y el mensaje o información tiende a dar una percepción equivocada del contenido.

8. Inclusiones: Cosas como uso de diversas plataformas HTML+PHP, HTML+Jquery, etc, estos siempre deben ser insertados por el lado del servidor, muchas veces no es necesario que se hagan forzosamente pero cualquier tipo de inclusión que use dos plataformas deben estar correctamente incrustadas:

include_once('inc/menu.php');

9. Codificación de caracteres: Si es un carácter especial… debe estar correctamente codificado.

10. Dinámico: Si hay cosas que deben ser dinámicas, que así sea.

11. Comentarios: Los comentarios deben ser incluidos pro cualquier situación, puede no ser inmediato pero debe hacerse para evitar reescribir parte de código o re-visitarlo constantemente para saber que hace

12. CSS clases y herencia: Detrás de los nombres e ID’s debe existir semántica de estilos que al mismo tiempo describa el estilo que deben llevar: además, de que se debe utilizar la misma semántica de estilos para las clases heredadas y con esto «reutilizar» estos estilos para múltiples elementos

13. ID’s: Estos deben usarse cada vez que un elemento vaya a aparecer por una «única» vez o que no puedan ser manipulados  por algún motivo o razón especial.

14. Javascript: La gran ventaja que tenemos de los frameworks como JQuery, MooTools, Prototype podemos obtener la ultima versión vía Google, podemos cargar la base de nuestro proyecto desde la red y enlazar otro único archivo nuestro que hace el trabajo dinámico, estos pueden ir al final de la pagina, algunos recomiendan esto para agilizar la carga de objetos y después se apliquen las propiedades y eventos, y también para que la pagina se ejecute de manera mas rápida.

<script type="text/javascript" src="http://.../libs/jquery.min.js?ver=1.3.2"></script>
<script type="text/javascript" src="js/script.js"></script>

15. Libre de estilos «free»: Nada dentro de la pagina debe contener estilos «distintos» fuera de la plantilla de diseño o que implique hacerlo es un ultimo recurso, si no es necesario es mejor mantener siempre la estética de la pagina para mejor visualización, además recuerda que cada pagina, imagen o contenido es un recurso mas dentro de la pagina.

16. Contenido válido: Todo el contenido HTML debe ser correcto y valido por la W3C, tags cerrados y atributos requeridos deben ser completados a conciencia, etc.

17. Los Tabs o espacios son usados para identar el código correctamente; de esta forma podemos identificar correctamente las relaciones padre-hijo de los tags.

Podemos ir tomando practica de estos habitos para ir mejorando constantemente, muchas veces es mas agradable a la vista un buen código, correctamente identado, comentado y sobre todo entendible, evitemos quebraderos de cabeza a otros y dejemos de lado el «es mio… solo yo lo entiendo», y vayamos por el buen camino.

Happy coding! 🙂

Cliente de chat «bot» – C#

Ya hacía mucho que deseaba escribir esta entrada… aunque por muchas circunstancias de la vida y de trabajo me alejé de este querido blog, pero nuevamente aqui les traigo una forma de conectarnos a los servidores de gtalk de google usando la libreria agsXMPP, nuevamente reitero no voy a explicar como agregar una referencia a nuestro proyecto en Visual Studio, como veíamos en un post anterior, las formas basicas de conexion con PHP ahora toca el turno con C#, hay muchas formas de hacerlo pero tambien debemos recordar que cuando se trabajan con clientes de chat hay estandares que se tienen que respetar; bueno, demos paso al codigo porque tambien no soy muy bueno para escribir textos muy grandes.

Asumiendo que ya tienen la libreria agregada a las referencias del proyecto, en mi caso se hizo desde una aplicación de consola asi que no veo gran diferencia el trasladarlo a un cliente grafico que sirva para el mismo proposito, ahora en las inclusiones de librerias debemos tener estas inclusiones:

//Librerias para conexion XMPP
using agsXMPP;
using agsXMPP.protocol.client;
using agsXMPP.protocol.component;
using agsXMPP.protocol.Base;

Dentro de la inicialización de componentes hay una clase que nos permitirá realizar la conexion y la manipulación de mensajes y estados de nuestra lista de usuarios las lineas basicas que necesitamos para la conexion son las siguientes:

//Clase de conexion y datos de acceso a la cuenta de chat.
public static agsXMPP.XmppClientConnection cliente = new agsXMPP.XmppClientConnection();
//Los objetos de conexion tienen que ser en formato Jid para que sea preparado en el formato XML aceptado por el estandar XMPP y sea aceptado por la conexion
public static Jid user = new Jid("yo@gmail.com");
public static Jid pass = new Jid("laclave");
//variable que indica la ruta del archivo de logs
public static string ArchLog = @"log.txt";
static void Main(string[] args){
    Console.WriteLine("Intentando conectar a servidor talk.google.com..");
    Console.WriteLine();
    //Conectamos con el servidor de google
    cliente.Server = "google.com";
    cliente.ConnectServer = "talk.google.com";
    cliente.Port = 5222;
    cliente.AutoRoster = true;
    cliente.AutoPresence = true;
    cliente.AutoResolveConnectServer = false;
    cliente.AutoPresence = true;
    cliente.Priority = 24;
    //funciones de control
    cliente.OnLogin += new ObjectHandler(cliente_OnLogin);
    cliente.OnError += new ErrorHandler(cliente_OnError);
    cliente.OnMessage += new agsXMPP.protocol.client.MessageHandler(cliente_OnMessage);
    cliente.OnPresence += new agsXMPP.protocol.client.PresenceHandler(cliente_OnPresence);
    cliente.OnReadXml += new XmlHandler(cliente_OnReadXml);
    cliente.OnWriteXml += new XmlHandler(cliente_OnWriteXml);
    cliente.Open(user, pass, "home"); //realizamos a conexion
    Console.ReadKey();
    cliente.Close();
}

En la funcion main tenemos 6 funciones; las dos ultimas nos serviran para parseo de errores del programa en tiempo de ejecución y tambien para ir guardando un log de actividades del mismo programa, aunque estas ultimas no tienen mucha importancia pero al momento de depurar son de alta prioridad, ahora a las que nos enfocaremos son a las primeras cuatro que son funciones delegadas de la funcion y que tenemos que programar con ciertas acciones cuando sucedan en tiempo de ejecución tales como cuando se conecta un usuario, al recibir un mensaje, cuando los logueamos y cuando ocurra un error durante la conexion. Muchos se preguntarán  el porque de «Console.ReadKey();» esto es porque las conexiones y la forma de comunicación del protocolo es asincrono, debemos estepera hasta que la conexion este completa para que las funciones delegadas funcionen correctamente de otra forma el programa nunca se conectará, vayamos a ver el contenido de las funciones de control.

//cliente.OnLogin += new ObjectHandler(cliente_OnLogin);
static void cliente_OnLogin(object sender){
    cliente.Status = "Estoy conectado!";
    Console.WriteLine("Status:"+ cliente.XmppConnectionState.ToString());
    //throw new NotImplementedException();
}

Esta funcion nos permitirá establecer un mensaje de bienvenida y realizar algunas configuraciones basicas del cliente, como establecer priproridad de conexion, pero la mas importante es mostrar nuestro mensaje de bienvenida al estio messenger 😛

//cliente.OnError += new ErrorHandler(cliente_OnError);
static void cliente_OnError(object sender, Exception ex){
    Console.WriteLine(ex.Message.ToString());
    //throw new NotImplementedException();
}

Creo que esta ultima funcion no requiere de mayores explicaciones 🙂

//cliente.OnMessage += new agsXMPP.protocol.client.MessageHandler(cliente_OnMessage);
//recibimos el mensaje
static void cliente_OnMessage(object sender, agsXMPP.protocol.client.Message msg){
    string emisor = msg.From.User;
    string mensaje = msg.Body;
    string correo = nombre+"@"+msg.From.server;
    Console.WriteLine("{0} dice: {1}",msg.From.User,msg.Body); //mostramos el mensaje
    cliente.Send(new agsXMPP.protocol.client.Message(correo,MessageType.chat,msg.From.User+" dice: "+msg.Body)); //lo reenviamos al emisor
}

Esta funcion controla la recepcion y envio de mensajes, para funciones demostrativas devolvera a el emisor el mismo mensaje queha enviado pero aqui podemos pedir una lectura de linea para enviar una respuesta, que no es muy dificil de programar 🙂

static void cliente_OnPresence(object sender, agsXMPP.protocol.client.Presence pres){
    ////obtiene el estado de conexion
    Console.WriteLine(String.Format("Conexion entrande  from:{0} show:{1} status:{2}", pres.From.ToString(), pres.Show.ToString(), pres.Status));
    //En esta parte si tenemos un cliente grafico podemos añadirlo a un listBox o algun componente para saber el estatus de ese cliente y poder conversar con el
}

Por ultimo las funciones de log las cuales son las siguientes y lo que hacen es por cada registro de actividad ir escribiendo un archivo de texto plano sin compresion lo que va sucediendo por el stream de conexion.

static void cliente_OnWriteXml(object sender, string xml){
    StreamWriter sw = File.AppendText(ArchLog);
    eLog(xml,sw);
    //throw new NotImplementedException();
}

static void cliente_OnReadXml(object sender, string xml){
    StreamWriter sw = File.AppendText(ArchLog);
    eLog(xml,sw);
    //throw new NotImplementedException();
}

static void eLog(string mensaje, StreamWriter sw){
    DateTime f = DateTime.Now;
    string fecha = f.ToString("dd/MM/yyyy");
    mensaje = fecha + ";" + mensaje + ";";
    sw.WriteLine(mensaje);
    sw.Close();
}

Hasta aquí la programacion de un cliente basico de chat hay muchas opciones mas y para un cliente grafico una opcion para ir controlando estados de los usuarios es usar Threads, hasta aqui es la programación de un cliente basico de chat conectandonos a servidores gtalk usando como plataforma la librería agsXMPP, para mayor información o dudas les recomiendo ampliamente que descarguen los ejemplos de la pagina de la librería hay muchas cosas y funciones que aqui no se tocan.

Happy coding! 😀

¿Por qué somos malos programadores?

Todos tenemos malos hábitos como programadores y aquí listo una serie de aspectos que debemos reconsiderar para mejorar. Cada vez que abrimos un proyecto que no es nuestro, nos acompaña un pequeño sentimiento de temor que nos hace sentir que caminamos por un sendero lleno de trampas, puertas secretas, codigos secretos y una de esas lineas que si se elimina o modifica hace que se la aplicacion entera se cuelgue y que posiblemente envie gigantescas lineas de error y advertencias.

A pesar de todo siempre terminamos diciendo «como  YO lo hubiera hecho…», respiramos con insatisfaccion, levantamos los animos, nos desenvolvemos en el proyecto y nos preguntamos ¿En que estaba pensando cuando hizo esto?, y ¿Cómo fué capaz de crear este desastre de proyecto?

Nuestro primer instinto de idea es pensar que el que lo desarrolló es un novato o quizá alguien aficionado pero no siempre es el caso, y la teoría del porque somos malos programadores es porque:

  • Un mal codigo es la acumulacion de multiples atajos o redirecciones.
  • En ocasiones no nos tomamos esos minutos extra para analizar el punto 1 y asi evitar acumular esas malas practicas.
  • No se piensa antes de empezar a programar, se debe tener un sólido plan de ataque.
  • No se comenta una sola línea de código. Eso hace el codigo todavía mas confuso,  escribirlo no toma mas de 5 segundos y nos lleva por un mejor camino.
  • Se debe sacrificar claridad por brevedad. Es buena practica el dejar nombres de variables claros y soltar los corchetes.
  • No se sigue un estandar de codificación. Hay que elegir uno y apegarse a el.
  • Existe duplicación de código. Entonces se está haciendo todo mal.
  • No se sigue un patrón de desarrollo; se debe tener una estructura de programación.
  • Se es demasiado inteligente para nuestro propio bien. Muchas veces la solucion mas simple es la mejor opción.
  • Hay que evitar activamente hacer nuestro codigo dificil de entender.
  • Si se deja de aprender los proyectos estarán atrapados en el tiempo en que se decidio hacer.
  • Tratamos de hacer todo por nosotros mismos. Hay que descrubir programadores que tienen un enfoque similar y que tambien den forma a la idea.
  • No se sale de la zona de confort. Hay que atreverse a mirar al siguiente nivel de programación.
  • No se comparte codigo. Hay que discutir nuestro codigo con compañeros programadores.
  • No se tienen proyectos paralelos. Si se quiere entrar en algo nuevo  que es poco o demasiado complicado de poner en un proyecto real, la mejor manera de aprender es conmenzar un nuevo proyecto paralelo que utilice dicha técnica.

Todos somos culpables de estas malas costumbres, la logica nos dice que siempre debemos mejorar y siguiendo esa linea de vision, debemos dejar de hacerlo; aunque no somos perfectos, debemos hacer todo lo que esté a nuestro alcance para acercarnos lo mas posible. Ahora pregunto ¿Cuales son sus manías cuando se trata de codigo de otros desarrolladores?

Filtrar URL PHP

Nuevamente con un nuevo snippet para la programación diaria; avanzando con unas clases para seguridad de las paginas y aumentar los filtros de seguridad en mis paginas y evitar que se malformen los valores como cuando se solicitan valores de tipo ?val1=1&val2=2, e ideando una forma de verificar que la url de redireccion es valida y que no tiene malformaciones investigando ne la documentación de PHP existe una funcion que nos permite saber si la url a la que vamos a actualizar es valida.

Si es una URL simple como http://www.ejemplo.com

el codigo sería el siguiente:

$url = "http://www.example.com";
if(!filter_var($url, FILTER_VALIDATE_URL)){
    //accion si es valido
}
else{
    //todo lo contrario
}

Si es una URL que contiene variables sería de la siguiente forma:

$url = "ejemplo.php?id=37&accion=modificar";
if(!filter_var($url, FILTER_VALIDATE_URL,FILTER_FLAG_QUERY_REQUIRED)){
    //  si no cumple con las condiciones de ser un host y llevar variables con valores
}
 else{
    //la URL es valida
}

La funcion retorna un valor tipo BOOL para validar la información, estas dos formas son las mas comunes hay otros parametros que nos faciltarian mas el trabajo como por ejemplo formatos de email y formatos personalizados.

Happy coding!!!