viernes, 2 de octubre de 2009

Lineas diagonales con css

El otro día encontré en un blog (fourshapes.com) el modo de hacer lineas diagonales con HTML utilizando un sólo div. Se basa en el modo en que se pintan los border en HTML.
The explanation of this effect is when the black, bottom, border pushes against the invisible (white) border, the the diagonal edge is created.

jueves, 1 de octubre de 2009

Herramientas de UML

Buscando herramientas para creación de diagramas UML, he dado con una web para crearlos online. La verdad es que se está convirtiendo en una de mis favoritas a la hora de crear diagramas de un modo rápido y, dicho sea de paso, divertido: http://www.yuml.me/

En está página se pueden crear, a día de hoy, tres tipos de diagramas:
  • Casos de uso
  • Diagramas de actividad
  • Diagramas de clase
Permite añadir notas y, aunque tiene algunas limitaciones, es bastante eficaz a la hora de pintar los diagramas. En caso de que no os guste como ha colocado un diagrama determinado, podéis probar a recolocar el orden en que habéis definido los elementos.

martes, 29 de septiembre de 2009

Eliminar todos los hijos de un nodo

Un código muy simplón para eliminar todos los hijos de un nodo sin que pueda dar ningún tipo de fallo:
var container = document.getElementById('id_del_nodo');
while (container.hasChildNodes()){
container.removeChild(container.lastChild);
}

lunes, 28 de septiembre de 2009

XMLHttpRequest: Enviando POST y esperando callback

Cuando necesitamos hacer una petición y ejecutar una función al recibir la respuesta, podemos emplear la siguiente función:

function getDataFromServer(queryString,callbackFunctionName){
XMLHttpRequestObject.open('POST', '/mi/url', true);
XMLHttpRequestObject.onreadystatechange = callbackFunctionName;
XMLHttpRequestObject.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
XMLHttpRequestObject.send(queryString);
}

El objeto XMLHttpRequest específico del navegador, se puede recuperar como se vió en este post.

XMLHttpRequest: Recuperando el objeto correcto

En ocasiones es necesario realizar una llamada AJAX manualmente desde javascript. Para ello, lo primero es obtener el objeto XMLHttpRequest específico de cada navegador. En la siguiente función, vamos a recuperarlo y devolverlo:
function getXMLHttpRequestObject(){
 if (window.XMLHttpRequest)
 {
  //El explorador implementa el interfaz de forma nativa
  return new XMLHttpRequest();
 }
 else if (window.ActiveXObject)
 {
  //El explorador permite crear objetos ActiveX
  try {
   return new ActiveXObject("MSXML2.XMLHTTP");
  } catch (e) {
   try {
    return new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {}
  }

 }
 alert('XMLHttpRequest no disponible');
}

viernes, 25 de septiembre de 2009

Expresiones regulares

A menudo me encuentro con la necesidad de incluir diversos patrones para procesar cadenas de texto. Por supuesto, la opción evidente es el uso de expresiones regulares que tienen soporte en prácticamente cualquier lenguaje. Este uso generalizado tiene un pequeño inconveniente: cada lenguaje presenta pequeñas modificaciones sobre su sintaxis. Afortunadamente, en la página de regular-expressions.info mantiene un bastante información y tutoriales para muchos lenguajes.

Además, incluye una herramienta de test online para expresiones regulares en javascript que puedes encontrar aquí.

martes, 22 de septiembre de 2009

Javascript aborted (otro caso)

En otras ocasiones me ha ocurrido que al insertar una imagen creada o alterada dinámicamente, se produce una carga abortada seguida de una petición correcta. Esto se debe a que al crear un elemento imagen y asignarle una src (o, simplemente, al reasignar la src), el navegador comprueba que la imagen es la más reciente. Asímismo, al incluirla en el DOM (vía appendChild o insertBefore), se repite la petición de nuevo.

Para evitar estos inconvenientes, siempre que sea posible es aconsejable seguir una lógica similar a la siguiente:

var imgCuerpo = document.createElement('img');
imgCuerpo.style.width = '739px';
imgCuerpo.style.height = '375px';
cuerpo.insertBefore(imgCuerpo,cuerpo.childNodes[0]);
imgCuerpo.src = '/path/to/img.png';


Este problema, aparece principalmente en versiones antiguas de IExplorer (versión 6 y anteriores).

Añadiendo nodos al árbol DOM del documento

En ocasiones es necesario incluir nodos en posiciones concretas del árbol DOM. Para ello contamos con las funciones appendChild e insertBefore. Su funcionamiento es el siguiente:
  • AppendChild añade un nodo como último hijo del nodo padre.
    Ejemplo: document.getElementById('contenedor').appendChild(nuevoElemento);
  • InsertBefore añade un nodo como hijo del nodo padre, antes del hijo indicado. Ejemplo:
    var contenedor = document.getElementById('contenedor');
    var hijo = contenedor.childNodes[0];
    var nuevoElemento = document.createElement('div');
    contenedor.insertBefore(nuevoElemento, hijo);

lunes, 21 de septiembre de 2009

IExplorer y hasLayout

En IExplorer, en algunos casos hay elementos de HTML que no parecen comportarse correctamente respecto a los estilos. Esto puede deberse a que al elemento en cuestión IE no le asigna un layout. En esos casos, basta con añadir una propiedad (un estilo) que asigne un layout.

Por defecto, los siguientes elementos tienen layout:
  • html, body
  • table, tr, th, td
  • img
  • hr
  • input, button, select, textarea, fieldset, legend
  • iframe, embed, object, applet
  • marquee
Para elementos que no tiene layout por defecto, basta con asignarles
height: 1% 
que se convertirá en
height: auto
salvo que el parent tenga una height propia.

Para evitar problemas con futuras versiones, podemos utilizar comentarios condicionales de explorer para distinguir IE6 de IE7+ y asignar la clase gainlayout a los elementos que nos interese:

<!--[if lt IE 7]><style>
/* style for IE6 + IE5.5 + IE5.0 */
.gainlayout { height: 0; }
</style><![endif]-->

<!--[if gte IE 7]><style>
.gainlayout { zoom: 1; }
</style><![endif]-->

En este caso, utilizamos la propiedad zoom para simular el mismo efecto sobre IE7+.

Para más información sobre comentarios condicionales, http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx

Mantener los iconos en su sitio (Icon Keeper)

Cuando se trabaja con portatiles, es habitual conectarse en algún momento a algún proyector. A mi me gusta tener los iconos en pantalla con un cierto orden, y estos cambios de resolución suelen perturbarlo en mayor o menor medida. Un compañero me comento un programilla que almacena la "posicion favorita" de los iconos y permite restaurarlo todo con un solo clic: Icon Keeper


miércoles, 16 de septiembre de 2009

Creación de elementos dinámicamente con Javascript

Podemos crear elementos dinámicamente con javascript en tiempo de ejecución. Para ello, basta con utilizar el objeto document. En el siguiente ejemplo vamos a crear un div, añadirle un estilo y contenido y añadirlo al final del body:
var d= document.createElement("div");
d.className= 'miEstilo';
d.innerHTML= 'Contenido';
document.getElementsByTagName("body")[0].appendChild(d); 

Parámetros de depuración para la JVM

Para activar la depuración remota en cualquier servidor J2EE y, en general, en cualquier proceso dependiente de una JVM, se deben pasar los siguientes parámetros:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7896

Se puede configurar el puerto indicando el que se desea en address.

martes, 15 de septiembre de 2009

Evaluación dinamica de funciones en XSL

Para usar evaluación dinámica de funciones en XSL hay que utilizar la extensión (ver EXSLT) dynamic. Para ello, se deben seguir los siguientes pasos:
  1. Declaración:
    xmlns:dyn="http://exslt.org/dynamic" extension-element-prefixes="dyn" 
  2. Uso:
    <xsl:variable name="set" select="dyn:evaluate($selector)"/>
Este ejemplo almacena en la variable set el NodeSet que se define en la variable selector (para que esto tenga sentido, el selector debe venir definido en el xml).

Uso de java en XSL (xalan)

Desde Xalan (apache), podemos invocar objetos java para el uso en un determinado punto de la hoja xsl. Por ejemplo, vamos a utilizar la clase SimpleDateFormat para dar formato a fechas en el xsl.Para ello:
  1. Declaración en la cabecera:
    xmlns:dateparser="xalan://java.text.SimpleDateFormat"  extension-element-prefixes="dateparser"
  2. Creación de una instancia:
    <xsl:variable name="dateformatter" select="dateparser:new('yyyyMMdd')"/>
  3. Uso del objeto:
    <xsl:value-of select="dateparser:format($dateformatter,$date)/>

Expresión regular para capturar el host de URL

Para obtener el host para cualquier tipo de URL, podemos utilizar la expresión regular siguiente (incluye barras de escape para el caracter especial '.'):
^(ftp|http|https)?:?(//)?[a-zA-Z0-9@\\.]*\\.[a-zA-Z0-9@\\.]*:?[0-9]*/

Con esta expresión se captura el protocolo, usuario, contraseña, host, puerto y primera barra de la url.

Carga de scripts dinamica

Para cargar un script de modo dinámico, basta hacer lo siguiente:
var s = document.createElement("script");
s.src = 'script-location/script-name.js';
s.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(s); 
Este código lo carga al final del head.

Si el script no carga (o si aparece la petición como abortada), puede deberse al modo en que se ha invocado. Si, por ejemplo, se hace la petición en un anchor:
<a href='location' onclick='cargaScript()'>cargar</a>
al iniciar la carga del script, se ejecuta inmediatamente el href. Si el href no hace referencia al propio documento (es decir, es una url, un javascript inline o algo que no sea '#' o similar), se aborta la operación y el script no carga.

Funciones de evento para componentes

Para crear funciones que lancen eventos tal y como ocurre con la función click de IE para todos los navegadores basta con hacer lo siguiente (ejemplo con mouseover sobre un anchor con id 'anchor'):
if(typeof HTMLElement!='undefined'&&!HTMLElement.prototype.mouseover){
document.getElementById('anchor').mouseover=function(){
var evt = this.ownerDocument.createEvent('MouseEvents');
evt.initMouseEvent('mouseover', true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
this.dispatchEvent(evt);
}
}
else{
document.getElementById('anchor').mouseover = function(){
this.fireEvent('onmouseover');
}
}

Si se quiere alterar el prototype para navegadores non-IE, basta con hacer HTMLElement.prototype.mouseover=function(){. Esto lanzaría eventos de moudeover sobre cualquier elemento invocando la función mouseover() sobre él.
Nota: En caso del iexplorer, los valores de posición son correctos, pero no así en el resto, que serán cero.