Está en la página 1de 31

HTML 5 Storage.

Comunicacin entre
ventanas
El almacenamiento en local proporcionado por HTML 5, denominado Local Storage,
puede tambin servirnos como modo de guardado para intercambio de informacin
entre aplicaciones e incluso que eso se haga de forma automatizada e instantnea.
A modo de gua, en el presente artculo, trataremos:
Almacenamiento de sesin y local en HTML 5.
Seguimiento y escucha de eventos.
El Storage Event Object.
El proyecto de aplicacin base de trabajo con almacenamiento local y escucha de
eventos.
La correspondiente segunda aplicacin de gestin de almacenamiento y escucha
de eventos.
Veremos cmo ambas intercambian la informacin modificada en cualquiera de
ellas.
Almacenamiento de sesin y local en HTML 5
Los dos modos de almacenamiento tipo Web Storage que nos proporciona como
novedad HTML 5, se recogen en la tabla que sigue. En el presente artculo damos por
supuesto que se conocen las bases del trabajo con l y usaremos tanto el
almacenamiento de un tipo como el de otro, dado que lo tratado es aplicable para ambos
casos.
Mtodo Descripcin
sessionStorage
Almacenar el nombre y valor de una clave durante el tiempo que dure
una sesin.
Toma como parmetro el nombre de la clave que va a ser almacenada.
Se le asigna el valor de la clave.
localStorage
Almacenar el nombre y valor de una clave de forma permanente.
Toma como parmetro el nombre de la clave que va a ser almacenada.
Se le asigna el valor de la clave.

Para ms informacin acerca del almacenamiento en HTML 5, sugerimos acuda a
nuestro artculo Almacenamiento de datos en HTML 5. WebStorage:
http://msdn.microsoft.com/es-es/library/dn194486.aspx
Slo recordaremos que los modos de asignacin son del estilo:
sessionStorage['sValue'] = valor;
Siendo:
sValue: el nombre de la clave
valor: el valor de la clave, en forma de cadena de caracteres
Para su recuperacin, emplearemos una codificacin del estilo:
var valor = sessionStorage['sValue'];
Tambin pueden emplearse las sintaxis de punto vase el artculo referenciado- y los
mtodos setItem(key, valor) y var valor=getItem(key). Todo esto tanto para
sessionStorage como para localStorage.

Herramientas utilizadas
Si se cargan directamente los ejemplos en un explorador de Internet, no se ejecutarn
correctamente las acciones de Web Storage, se precisa sean subidas desde un servidor,
no por carga directa tngase siempre muy presente-.
Por tanto, hemos utilizado herramientas que facilitan la ejecucin desde un servidor
lanzado desde el propio entorno de desarrollo de forma totalmente transparente para
nosotros, tales como WebMatrix 3.0 o Visual Studio 2013 incluidas las versiones
Express-.
Desde ellos, a la vista del cdigo fuente el editor de cdigo-:
En WebMatrix: Pulsaremos el botn derecho del ratn sobre el nombre del
archivo y en el men emergente seleccionaremos Iniciar en Explorador.
En Visual Studio: Pulsaremos el botn derecho del ratn en un rea libre del editor
y en el men emergente seleccionaremos Ver en Explorador.



Seguimiento escucha- de eventos
Cuando se modifica el Web Storage se produce un evento que puede seguirse con los
mtodos habituales de escucha de eventos de JavaScript.
Para una informacin general de la gestin del seguimiento de eventos, acdase a la
siguiente direccin URL:
https://developer.mozilla.org/es/docs/DOM/elemento.addEventListener
En nuestro caso concreto, que se trata un evento surgido del almacenamiento local
HTML 5, se puede obtener la informacin devuelta en el parmetro Storage Event
Object, vase ms adelante.
La tabla que sigue recoge el mtodo a implementar y la funcin de respuesta a codificar
para dichas labores.
Mtodo Descripcin
addEventListener
Crear una funcin de escucha de eventos en general.
Toma como parmetros:
El tipo de eventos a seguir, se especifica con una constante que los
identificar
La referencia de la funcin de respuesta que codificaremos
Un tercer parmetro opcional que si es true indica que ser el
usuario el que controlar el evento antes de ser emitido al
destinatario
function
respuesta(evt)
La funcin de respuesta contiene de parmetro un objeto de tipo
Storage Event Object y es la llamada cuando se produce un evento
del tipo capturado.
Nos ocuparemos ms debajo de ese tipo de objeto y de la
informacin que nos proporciona.

En esencia, un cdigo de captura de evento del Web Storage debera ser algo as como
lo recogido en el Listado 1.
Listado 1: Cdigo a insertar para la escucha y seguimiento de eventos del Web Storage
de HTML 5.
Copiar
<script>
function reportStorage(evt) {
alert("El `Storage` fue modificado");
}
window.onload = function () {
window.addEventListener('storage', reportStorage, false);
}
</script>

El Storage Event Object
Este objeto que es transferido a la funcin de respuesta tiene numerosos mtodos y
propiedades, que no es de inters inminente tratar en detalle, nos interesarn
especialmente las propiedades recogidas en la tabla que sigue:
Propiedad Descripcin
key La clave que ha sido cambiada y es objeto del evento.
newValue El antiguo valor de.
oldValue El nuevo valor.
timeStamp
La hora del evento en formato timestamp, que son los milisegundos
trascurridos desde el 1 de enero de 1970.
url La direccin desde la cual se ha emitido el evento de cambio.

Para una informacin completa de los mtodos y propiedades del Storage Event Object,
puede acudir a la siguiente direccin URL:
http://msdn.microsoft.com/en-us/library/windows/apps/hh465809.aspx
La propiedad timeStamp es la nica que merece una atencin especial, para pasarla a un
modo que sea significativo para nosotros, normalmente una fecha en nuestro calendario
de uso local, codificaremos algo similar a:
(new Date(evt.timeStamp)).toLocaleString('es-ES')
En donde:
evt: seria el parmetro pasado a la funcin de respuesta
es-ES: determina la localizacin de la fecha y hora a mostrar cmbiese para
cada caso particular-
Nuestro proyecto
Se trata de implementar la comunicacin entre dos documentos HTML a travs del
almacenamiento de Web Storage que nos proporciona HTML 5. As, almacenaremos
datos en l desde un documento, que sern ledos desde otros y viceversa; a la par,
implementaremos funciones de escucha de eventos para actualizar las pginas, cuando
se modifiquen algunos de los datos en una u otra.
Podramos decir que se trata de dos aplicaciones corriendo en paralelo:
La primera aplicacin, podramos llamarla la principal, ser la que lleve el peso de
los contenidos a intercambiar, sin ms.
La segunda aplicacin, o aplicacin complementaria, slo gestionar parte de los
contenidos intercambiados y ser como un modificador de la primera, por el resto,
su cdigo de gestin es similar.
Ntese que es necesario trabajar con el Local Storage para la intercomunicacin entre
aplicaciones, ya que es la que abarca a todo el sistema y no se restringe a la sesin de
navegacin de una nica aplicacin.
Puede comprobarlo al final de nuestra exposicin, cambiando todas las referencias de
localStorage por sessionStorage.

La aplicacin principal (o primera)
Se trata de una mimetizacin de un breve cuestionario de entrada de un nombre y un
alias que en vez de ser guardados en una base de datos o enviados por email, sern
guardados en el Local Storage.
El cdigo correspondiente se muestra en el Listado 2. Lo que contiene y las acciones
que se llevan a cabo son, en resumen:
Los siguientes elementos funcionalmente significativos:
Una caja de entrada de texto identificada como Nombre que servir de contenedor y
entrada de un supuesto nombre de usuario.
Una caja de entrada de texto identificada como Alias que servir de contenedor y
entrada de un supuesto alias de dicho usuario.
Un botn de comando etiquetado Guardar para enviar al Local Storage los valores
actuales de las cajas de entrada de nombre y alias.
Se ha codificado una funcin de seguimiento escucha- de los eventos del Web
Storage, similar al que hemos implementado en el ejemplo anterior
window.onload() -.
Al arranque de la aplicacin, tambin codificado en window.onload() con una
llamada a la funcin paste(), se cargarn desde el Local Storage el valor del
nombre y el alias previamente almacenados en el sistema.
Esas cargas darn lugar a dos llamadas a la funcin de escucha de eventos del
Web Storage, antes de emitirse la correspondiente alerta JavaScript programada
en la funcin paste().
Al pulsar el botn Guardar se llama sucesivamente a las funciones nombre() y
alias() que guardarn el nombre y el alias que contienen las cajas de entrada
correspondientes en el Local Storage del sistema.
Esas acciones darn lugar a dos llamadas a la funcin de escucha de eventos del
Web Storage, antes de emitirse las correspondientes alertas JavaScript
programadas en las funciones nombre() y alias().
Cada vez que se produzca una alteracin del Local Storage, ser llamada la
funcin de escucha y se recargarn los valores de nombre y alias, por si hubieran
sido cambiados.
Tambin se recargar la pgina para asegurarnos de que se muestran los valores
actualizados convenientemente.
Listado 2: Cdigo fuente de la aplicacin primera del sistema de escucha e intercambio
de informacin.
Copiar
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>localStorage con addEventListener 1</title>
<style>
#B {
background-color: lightgray;
}
#C {
background-color: lightblue;
}
</style>
<script>
var flag1 = 'off';
function reportStorage(evt) {
alert("El `Storage` fue modificado desde: " + evt.url);
alert("Se ha actualizado: " + evt.key);
// Actualizamos el valor del alias y del nombre
if (flag1 == 'off') {
paste();
window.location.reload(true);
}
}
window.onload = function () {
window.addEventListener('storage', reportStorage, false);
paste();
}
function alias() {
var valor = document.getElementById("C").value;
localStorage['aValue'] = valor;
alert('Alias: ' + valor);
}
function nombre() {
// Tomamos la referencia del nombre a copiar
var valor = document.getElementById("B").value;
localStorage['sValue'] = valor;
alert('Nombre: ' + valor);
}
function paste() {
// Recuperamos el valor del nombre y el alias
var localValue = localStorage['sValue'];
var localValueAlias = localStorage['aValue'];
// Pegamos el valor del nombre y el alias
document.getElementById("B").value = localValue;
document.getElementById("C").value = localValueAlias;
alert('ACTUALIZADOS en 1');
}
</script>
</head>
<body>
<p>Nombre</p>
<div>
<input id="B" type="text" value="" />
</div>
<p>Alias</p>
<div>
<input id="C" type="text" value="" />
</div>
<hr />
<input type="button" onclick="flag1 = 'on'; alias(); nombre();
flag1 = 'off'" value="Guardar" />

<hr />
<footer style="width: 230px">

<a href="http://www.w3.org/html/logo/">
<img src="http://www.w3.org/html/logo/badge/html5-badge-h-
css3-semantics.png" width="165" height="64" alt="HTML5 Powered with
CSS3 / Styling, and Semantics" title="HTML5 Powered with CSS3 /
Styling, and Semantics">
</a>
<br />
<a href="http://jigsaw.w3.org/css-validator/check/referer">
<img style="border: 0; width: 88px; height: 31px"
src="http://jigsaw.w3.org/css-validator/images/vcss-
blue"
alt="CSS Vlido!" />
</a>

</footer>
Jaime Pea Tresancos, 2013
</body>
</html>



La aplicacin complementaria (o segunda)
El cdigo correspondiente se muestra en el Listado 3. Lo que contiene y las acciones
que se llevan a cabo son, en resumen:
Una mimetizacin reducida del dilogo de la primera aplicacin.
Con los siguientes elementos funcionalmente significativos:
Una etiqueta identificada como Nombre que servir de contenedor de un supuesto
nombre de usuario.
Una caja de entrada de texto identificada como Alias que servir de contenedor y
entrada de un supuesto alias de dicho usuario.
Un botn de comando etiquetado Guardar alias para enviar al Local Storage el valor
actual de la caja de entrada de alias.
Se ha codificado una funcin de seguimiento escucha- de los eventos del Web
Storage, similar al que hemos implementado en la aplicacin anterior
window.onload() -.
Al arranque de la aplicacin, tambin codificado en window.onload() con una
llamada a la funcin paste(), se cargarn desde el Local Storage el valor del
nombre y el alias previamente almacenados en el sistema.
Esas cargas darn lugar a dos llamadas a la funcin de escucha de eventos del
Web Storage, antes de emitirse la correspondiente alerta JavaScript programada
en la funcin paste().
Al pulsar el botn Guardar alias se llama a las funcin alias() que guardar el
alias que contiene las caja de entrad correspondiente en el Local Storage del
sistema.
Cada vez que se produzca una alteracin del Local Storage, ser llamada la
funcin de escucha y se recargarn los valores de nombre y alias, por si hubieran
sido cambiados.
Tambin se recargar la pgina para asegurarnos de que se muestran los valores
actualizados convenientemente.
Listado 3: Cdigo fuente de la aplicacin segunda del sistema de escucha e intercambio
de informacin.
Copiar
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>localStorage con addEventListener 2</title>
<style>
#B {
background-color: lightgray;
}
#C {
background-color: lightblue;
}
</style>
<script>
var flag2 = 'off';
function reportStorage(evt) {
alert("El `Storage` fue modificado desde: " + evt.url);
alert("Se ha actualizado: " + evt.key);
// Actualizamos el valor del alias y del nombre
if (flag2 == 'off') {
paste();
window.location.reload(true);
}
}
window.onload = function () {
window.addEventListener('storage', reportStorage, false);
paste();
}
function alias() {
var valor = document.getElementById("C").value;
localStorage['aValue'] = valor;
alert('Alias: ' + valor);
}
function paste() {
// Recuperamos el valor del alias y el nombre original
var localValueAlias = localStorage['aValue'];
var localValue = localStorage['sValue'];
// Pegamos el valor del alias y el nombre original
document.getElementById("C").value = localValueAlias;
document.getElementById("B").textContent = localValue;
alert('ACTUALIZADOS en 2');
}
</script>
</head>
<body>
<h2>Desea cambiar el alias?</h2>
<p>Nombre</p>
<div>
<label id="B"></label>
</div>
<p>Alias</p>
<div>
<input id="C" type="text" value="" />
</div>
<hr />
<div>
<input type="button" onclick="flag2 = 'on'; alias(); flag2 =
'off'" value="Guardar alias" />
</div>

<hr />
<footer style="width: 230px">

<a href="http://www.w3.org/html/logo/">
<img src="http://www.w3.org/html/logo/badge/html5-badge-h-
css3-semantics.png" width="165" height="64" alt="HTML5 Powered with
CSS3 / Styling, and Semantics" title="HTML5 Powered with CSS3 /
Styling, and Semantics">
</a>
<br />
<a href="http://jigsaw.w3.org/css-validator/check/referer">
<img style="border: 0; width: 88px; height: 31px"
src="http://jigsaw.w3.org/css-validator/images/vcss-
blue"
alt="CSS Vlido!" />
</a>

</footer>
Jaime Pea Tresancos, 2013
</body>
</html>




Conclusiones
En el presente artculo hemos visto cmo implementar un sistema de escucha de
modificaciones en el Local Storage y a partir de l cmo intercambiar informacin entre
aplicaciones que se ejecutan simultneamente.
Esperamos que lo aqu expuesto les haya servido de ayuda en su trabajo y no dejen de
preguntar cualquier duda que les pudiese surgir. Hasta la prxima, tengan unas
provechosas sesiones de programacin.





[ASP.NET MVC] Cargando datos con
WebAPI y JSRender
Hace algn tiempo, realice algunos post sobre las Microsoft jQuery Templates
(mralos ac: post I, post II, post III) y en resumen lo que podamos realizar era obtener
datos de alguna fuente como puede ser un servicio y mostrarlos en el cliente, todo esto
utilizando JavaScript, lamentablemente ese proyecto se ha quedado atrs y ahora
tenemos una nueva y muy buena alternativa, JSRender, JSRender tiene la misma
filosofa de las jQuery Templates pero con mejores caractersticas, as que quiero
mostrarles un pequeo ejemplo de como lo podemos usar en conjunto con WebAPI..
como ya sabrn WebAPI esta muy de moda y no des para menos, realmente es muy
bueno y me ha gustado bastante, as que manos a la obra:
El modelo
Como primera medida vamos a crear una clase Cliente que va a actuar como el modelo:
C#
Copiar
public class Cliente
{
public int ClienteId { get; set; }
public string Nombre { get; set; }
public string Email { get; set; }
public bool Activo { get; set; }
}
El controlador
En este caso vamos a crear un controlador WebAPI, recuerden que WebAPI no solo
esta disponible para ASP.NET MVC, tambin es posible utilizarla con ASP.NET Web
Forms. Aadimos un nuevo tem de tipo Web API Controller y como nombre le damos
ClienteController, y all para este ejemplo solo vamos a tener una funcin llamada
GetAll la cual retornar todos los clientes existentes.
C#
Copiar
public class ClienteController : ApiController
{
private readonly List<Cliente> clientes = new List<Cliente>()
{
new Cliente{ ClienteId = 1, Nombre = "Julio", Email =
"email1@contoso.com", Activo = true},
new Cliente{ ClienteId = 2, Nombre = "Juan", Email =
"email2@contoso.com", Activo = true},
new Cliente{ ClienteId = 3, Nombre = "Nathalia", Email =
"email3@contoso.com", Activo = false},
new Cliente{ ClienteId = 4, Nombre = "Julio", Email =
"email1@contoso.com", Activo = true},
new Cliente{ ClienteId = 5, Nombre = "Juan", Email =
"email2@contoso.com", Activo = true},
new Cliente{ ClienteId = 6, Nombre = "Nathalia", Email =
"email3@contoso.com", Activo = false},
new Cliente{ ClienteId = 7, Nombre = "Julio", Email =
"email1@contoso.com", Activo = true},
new Cliente{ ClienteId = 8, Nombre = "Juan", Email =
"email2@contoso.com", Activo = true},
new Cliente{ ClienteId = 9, Nombre = "Nathalia", Email =
"email3@contoso.com", Activo = false}
};

public IEnumerable<Cliente> GetAll()
{
return clientes;
}
}
Configurando WebAPI
Una vez que tenemos listo el controlador, lo que necesitamos hacer es configurar el
ruteo para poder llamar a los mtodos del controllador, as que lo primero que haremos
es crear una clase con un mtodo esttico y luego llamarlo en el evento
Application_Start de el Global.asax:
C#
Copiar
public class RouteConfig
{
public static void RegisterRoutes()
{
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Y en el Global.asax:
Script
Copiar
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes();
}
Creando el HTML
Una vez que tenemos todo listo, vamos a crear una pgina para mostrar los datos:
Script
Copiar
<div>
<h1>Listado de clientes</h1>
<hr />
<table id="tblData">
<thead>
<tr>
<th>Cliente Id</th>
<th>Nombre</th>
<th>Email</th>
<th>Estado</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
Para el ejemplo tenemos definida una tabla en la cual mostraremos los datos.
Referenciando Scripts
Ahora, vamos a aadir referencias a dos archivos JavaScript, uno ser jQuery y le otro
jsrender, sin embargo ac quiero dejar claro que a diferencia de muchos plugin jsrender
NO necesita de jQuery, simplemente lo he aadido ya que me facilita el acceso al DOM
y a eventos del lado del cliente:
Script
Copiar
<script src="Scripts/jquery-1.8.2.js"></script>
<script src="Scripts/jsrender.js"></script>
Creando la plantilla
Ahora es tiempo de crear la plantilla que usar jsrender para mostrar los datos:
Script
Copiar

<script type="text/x-jsrender" id="DataTemplate">

<tr><td>{{:ClienteId}}</td><td>{{:Nombre}}</td><td>{{:Email}}</td><td>
{{:Activo}}</td></tr>
</script>
Lo primero que se debe tener presente es que el tipo del script debe ser text/x-jsrender,
y le debemos definir un id para luego poder referenciarla, el cuerpo de la plantilla
simplemente es una pequea parte del body de una tabla (recuerdan que en el HTML
definimos una tabla, paso 4), y con la sintaxis: {{:NOMBRE_CAMPO}} es que se
define cual es el dato que se desea mostrar.
Enlazando datos:
Finalmente, llego la hora de enlazar la plantilla con los datos proporcionados por
WebAPI, para este trabajo nos apoyaremos en jQuery y su facilidad para llamar
servicios:
Script
Copiar
<script type="text/javascript">
$(document).on("ready", function () {
$.getJSON("/api/cliente",
function (data) {
$("#tblData
tbody").html($("#DataTemplate").render(data));
});
})
</script>
Como el servicio nos devuelve los datos en formato JSON por brevedad se hace uso de
$.getJSON, como primer parmetro le pasamos la URL que debe llamar, y en segundo
lugar la funcin de callback, en dicha funcin lo que hacemos es cargarle un HTML al
cuerpo de la tabla, pero como en este caso es una plantilla lo primero es referenciarla
por medio de su ID y luego le decimos los datos a cargar con render(data).
Ahora si ejecutamos la aplicacin tenemos:

Espero les sea de utilidad, les dejo el cdigo con el ejemplo.


Internet Explorer 10. Diseo
multicolumna en CSS3

El uso de hojas de estilo en cascada en su versin 3 (CSS3) nos facilita sustancialmente
el trabajo con multicolumna en los documentos HTML. El uso de documentos con
multicolumna permite una mejor lectura de aquellas partes de textos amplios; el
presente artculo se enmarca en el mbito de la programacin de interface de usuario
para la implementacin de aplicaciones Web.
En cuanto a la edicin del cdigo podremos emplear Visual Studio, WebMatrix, el Bloc
de notas de Windows, o cualquier otro editor de cdigo HTML y CSS. No es adecuado
un generador de cdigo que trabaje solamente en modo WYSIWYG modo diseo-,
deber ser uno que nos permita tener el control total y la escritura directa de las fuentes
de HTML y CSS.
El cdigo aqu expuesto es totalmente compatible con Microsoft Internet Explorer 10, el
resto de los exploradores del mercado o bien precisan de cdigos especficos del
vendedor, como webkit, o bien no contemplan todas las capacidades de trabajo aqu
expuestas, fundamentalmente en lo relativo a los prrafos multicolumna.
Concretamente, en el presente artculo trataremos:
Formateo de secciones en multicolumna con CSS3
Espaciados y separadores entre columnas
Insercin de imgenes en columnas
Textos multicolumna
Fijar el ancho y el nmero de columnas
Mediante CSS3 disponemos de tres propiedades que nos permiten fijar una presentacin
multicolumna de los contenidos de una seccin:
Fijando directamente cuntas columnas deseamos sean presentadas
Fijando un ancho de columna, de modo que Internet Explorer divida el rea
disponible en columnas que cumplan la condicin
Fijando el nmero y ancho de columna, de forma que debera marcarse un nmero
de columnas de un ancho determinado. En la prctica Internet Explorer acata el
nmero de columnas preferentemente
Propiedad Descripcin
column-count Nmero de columnas
column-witdh Ancho de cada columna
Columns Ambos valores

Si slo fijamos en nmero de columnas, se repartir el texto homogneamente en
horizontal, vase por ejemplo la cuarta y quinta de las figuras, pero no siempre ocurre
as de una manera totalmente uniforme y puede que la ltima sea notoriamente menor,
para ajustarse a prrafos, imgenes, o bien no llegue a crearse si el texto es escaso.
Si fijamos slo el ancho, se crearn automticamente las columnas mximas posibles
segn el ancho total de la ventana de Internet Explorer, descontando los bordes y el
espaciado entre columnas.
Si se fijan los dos valores de nmero de columnas y ancho simultneamente,
tericamente el ajuste sera tratando de acomodar ambos valores. En la prctica pesa
ms el valor del nmero de columnas.
En cuanto a la distribucin del texto, Internet Explorer trata de mantener al lmite las
imposiciones de las reglas de nmero de columnas.
Listado 1: Ejemplo de texto multicolumna mediante CSS3.
HTML
Copiar
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Multicolumnas en CSS3. Ej. column-count</title>
<style>
div.columnas {
/* Definicin de las columnas */
column-count: 3;
}
</style>
</head>
<body>
<h2>Don Quijote</h2>
<div class='columnas'>
<h3>Y con esto,</h3>
entr en el aposento, y todos tras l, y hallaron a don Quijote
en el ms extrao traje del mundo. Estaba en camisa, la cual no
era nada cumplida, que por delante le acabase de cubrir los muslos,
y por detrs tena seis dedos menos; las piernas eran muy largas y
flacas, llenas de vello y no nada limpias; tena en la cabeza un
bonetillo colorado, grasiento, que era del ventero.<br />
En el brazo
izquierdo tena revuelta la manta de la cama, con quien tena ojeriza
Sancho, y l saba bien el porqu, y en la derecha, desenvainada
la espada, con la cual daba cuchilladas a todas partes, diciendo
palabras como si verdaderamente estuviera peleando con algn
gigante.<br />
Y es lo bueno que no tena los ojos abiertos, porque estaba durmiendo
y soando que estaba en batalla con el gigante; que fue tan intensa
la imaginacin de la aventura que iba a fenecer, que le hizo soar
que ya haba llegado al reino de Micomicn, y que ya estaba en la
pelea con su enemigo. Y haba dado tantas cuchilladas en los cueros,
creyendo que las daba en el gigante, que todo el aposento estaba
lleno de vino.
</div>
</body>
</html>


Espaciado entre columnas
Se definen los espaciados personalizados mediante la propiedad column-gap que tiene
tres valores predefinidos: inherit, initial y normal equivalente en la prctica a 1em,
tambin es el valor por defecto- y puede darse en unidades de medida estndar como px,
em,
En el ejemplo que sigue hemos realizado una mnima modificacin al anterior,
introduciendo un espaciado mayor entre columnas, de valor 3em.
Listado 2: Definicin de un ancho de columna mediante CSS3.
HTML
Copiar
<style>
div.columnas {
/* Definicin de las columnas */
column-count: 3;
/* Espaciado entre columnas */
column-gap: 3em;
}
</style>



Propiedad column-rule
En el espacio entre columnas cabe la posibilidad de disponer un separador column
rule- en forma de lnea de apariencia personalizable mediante las propiedades descritas
seguidamente en la tabla adjunta.
Propiedad Descripcin
column-rule-
style
Estilo del separador. Acepta los mismos valores que para los estilos de
bordes propiedad border-style-
column-rule-
width
Ancho del separador
column-rule-
color
Color del separador
column-rule Los tres valores

La propiedad column-rule es independiente de la propiedad column-gap, de manera que
si la primera es mayor que la segunda, se sobrepondr sobre el texto de las columnas, no
quedar restringida a la separacin dada entre ellas, lo que puede ser un inconveniente o
una oportunidad de crear efectos atractivos.
Listado 3: Inclusin de separadores entre columnas en CSS3.
HTML
Copiar
<!DOCTYPE html>

<html lang="es">
<head>
<meta charset="utf-8" />
<title>Multicolumnas en CSS3. Ej. 0</title>
<style>
div.columnas {
/* Definicin de las columnas */
column-count: 3;
/* Espaciado entre columnas */
column-gap: 1.5em;
/* Un poco de adorno del separador */
column-rule-style: solid;
column-rule-width: 2px;
column-rule-color: #ff0000;
/* Estilos complementarios */
border: 1px solid;
border-radius: 10px 10px;
padding: 20px 20px;
background-color: #f5dc96;
color: #0000aa;
font-style: italic;
}
</style>
</head>
<body>
<h2>Don Quijote</h2>
<div class='columnas'>
<h3>Y con esto,</h3>
entr en el aposento, y todos tras l, y hallaron a don Quijote
en el ms extrao traje del mundo. Estaba en camisa, la cual no
era nada cumplida, que por delante le acabase de cubrir los muslos,
y por detrs tena seis dedos menos; las piernas eran muy largas y
flacas, llenas de vello y no nada limpias; tena en la cabeza un
bonetillo colorado, grasiento, que era del ventero.<br />
En el brazo
izquierdo tena revuelta la manta de la cama, con quien tena ojeriza
Sancho, y l saba bien el porqu, y en la derecha, desenvainada
la espada, con la cual daba cuchilladas a todas partes, diciendo
palabras como si verdaderamente estuviera peleando con algn
gigante.<br />
Y es lo bueno que no tena los ojos abiertos, porque estaba durmiendo
y soando que estaba en batalla con el gigante; que fue tan intensa
la imaginacin de la aventura que iba a fenecer, que le hizo soar
que ya haba llegado al reino de Micomicn, y que ya estaba en la
pelea con su enemigo. Y haba dado tantas cuchilladas en los cueros,
creyendo que las daba en el gigante, que todo el aposento estaba
lleno de vino.
</div>
</body>
</html>



Insercin de imgenes
Insertar una imagen en un texto multicolumnas se realiza exactamente lo mismo que en
un texto normal de una nica columna.
Pero podemos encontrarnos con un pequeo y desagradable tropiezo, si la imagen es
ms ancha que la columna, ser truncada al ancho de la columna. La buena noticia es
que la solucin es simple y adems ms sutil que lo que se pensara de antemano.
Mediante la propiedad max-width asociada a la etiqueta de imagen, como ilustramos en
el ejemplo que sigue, ajustaremos el tamao de la imagen a la proporcin deseada del
ancho de la columna usualmente nos interesar el 100%-. Pero, adems, al
redimensionar la ventana de Internet Explorer y reacomodarse las columnas, tambin se
readaptar automticamente la imagen a la nueva situacin, como se aprecia en las
figuras adjuntas.
Listado 4: Insercin de imgenes en columnas CSS3.
HTML
Copiar
<!DOCTYPE html>

<html lang="es">
<head>
<meta charset="utf-8" />
<title>Multicolumnas en CSS3. Ej. 1</title>
<style>
div.columnas {
/* Definicin de las columnas */
column-count: 3;
/* Espaciado entre columnas */
column-gap: 1.5em;
/* Un poco de adorno del separador */
column-rule-style: solid;
column-rule-width: 2px;
column-rule-color: #ff0000;
/* Estilos complementarios */
border: 1px solid;
border-radius: 10px 10px;
padding: 20px 20px;
background-color: #f5dc96;
color: #0000aa;
font-style: italic;
}

.figura {
max-width: 100%;
}
</style>
</head>
<body>
<h2>El mensajero del miedo</h2>
<div class='columnas'>
Mientras todo el pas sigue la campaa electoral que lleva a la
eleccin
del candidato a la presidencia, un militar lucha contra el tiempo para
poner
al descubierto una conspiracin que hara tambalearse la
democracia.<br />

<img class="figura" alt="Cartel" src="el-mensajero-del-miedo.jpg"><br
/>

El comandante del Ejrcito de Tierra de Estados Unidos Bennett Marco
(Washington) no consigue conciliar el sueo, pero tampoco quiere
hacerlo.
Marco se pasa la vida dando conferencias acerca de la emboscada que
sufri
su pelotn en el desierto kuwait y de la heroicidad del sargento
Raymond
Shaw (Schreiber) que recibi la Medalla de Honor por salvar a los
hombres
de Marco. Pero, de noche, las imgenes que Marco recuerda de ese
fatdico
da se convierten en terribles y siniestras pesadillas. Marco empieza
a
preguntarse si los dos soldados que murieron en el fuego cruzado no
sufrieron una suerte ms oscura de la que indican los expedientes
oficiales
y si Shaw es realmente el hroe glorioso al que todos aclaman.<br />

Empujado por su madre, la controvertida senadora Eleanor Prentiss Shaw
(Streep), Shaw se convierte en candidato a la vicepresidencia y Marco
no
tiene ms remedio que hacer caso a sus crecientes sospechas. A pesar
de los
obstculos - el ejrcito empieza a cuestionar su cordura y la
seguridad
alrededor de Shaw es cada vez mayor - Marco se lanza a una carrera
contra
el tiempo para demostrar la asombrosa e inimaginable verdad antes de
que
puedan hacerse con la Casa Blanca
</div>
</body>
</html>




Textos multicolumna
No hay un modo verstil de manejar textos que abarquen mltiples columnas, slo
disponemos de la propiedad column-span.
La propiedad column-span slo puede tomar los valores none o all, de manera que o
bien un texto determinado ocupa una columna o bien las ocupa todas. Obsrvese el
listado y la figura que siguen, en dnde se ha aplicado el estilo de multicolumna a un
prrafo con los crditos de los actores.
Listado 5: Un rea de texto multicolumna en CSS3.

HTML
Copiar
<!DOCTYPE html>

<html lang="es">
<head>
<meta charset="utf-8" />
<title>Multicolumnas en CSS3. Ej. 2</title>
<style>
div.columnas {
/* Definicin de las columnas */
column-count: 4;
/* Espaciado entre columnas */
column-gap: 1.5em;
/* Un poco de adorno del separador */
column-rule-style: solid;
column-rule-width: 2px;
column-rule-color: #ff0000;
/* Estilos complementarios */
border: 1px solid;
border-radius: 10px 10px;
padding: 20px 20px;
background-color: #f5dc96;
color: #0000aa;
font-style: italic;
}

.figura {
max-width: 100%;
}
.actores {
column-span: all;
border: 1px solid;
background-color: #f7eded;
color: #000000;
font-style: normal;
font-size: x-large;
text-align: center;
}
.titulo {
text-shadow: 2px 2px;
font-style: italic;
}
</style>
</head>
<body>
<h1 class="titulo">El mensajero del miedo</h1>
<div class='columnas'>
Mientras todo el pas sigue la campaa electoral que lleva a la
eleccin
del candidato a la presidencia, un militar lucha contra el tiempo para
poner
al descubierto una conspiracin que hara tambalearse la
democracia.<br />

<img class="figura" alt="Cartel" src="el-mensajero-del-miedo.jpg"><br
/>

El comandante del Ejrcito de Tierra de Estados Unidos Bennett Marco
(Washington) no consigue conciliar el sueo, pero tampoco quiere
hacerlo.
Marco se pasa la vida dando conferencias acerca de la emboscada que
sufri
su pelotn en el desierto kuwait y de la heroicidad del sargento
Raymond
Shaw (Schreiber) que recibi la Medalla de Honor por salvar a los
hombres
de Marco. Pero, de noche, las imgenes que Marco recuerda de ese
fatdico
da se convierten en terribles y siniestras pesadillas.

<p class="actores">Meryl Streep & Denzel Washington</p>

Marco empieza a
preguntarse si los dos soldados que murieron en el fuego cruzado no
sufrieron una suerte ms oscura de la que indican los expedientes
oficiales
y si Shaw es realmente el hroe glorioso al que todos aclaman.<br />
Empujado por su madre, la controvertida senadora Eleanor Prentiss Shaw
(Streep), Shaw se convierte en candidato a la vicepresidencia y Marco
no
tiene ms remedio que hacer caso a sus crecientes sospechas. A pesar
de los
obstculos - el ejrcito empieza a cuestionar su cordura y la
seguridad
alrededor de Shaw es cada vez mayor - Marco se lanza a una carrera
contra
el tiempo para demostrar la asombrosa e inimaginable verdad antes de
que
puedan hacerse con la Casa Blanca
</div>
</body>
</html>


Esperamos que lo aqu expuesto les haya servido de ayuda en su trabajo y no dejen de
preguntar cualquier duda que les pudiese surgir. Hasta la prxima, tengan unas
provechosas sesiones de programacin.









Subiendo un archivo a un servidor FTP
con un FileUpload
Hace poco me preguntaban en el blog sobre como era posible subir un archivo a un
servidor FTP utilizando el FileUpload de ASP.NET, esto se dio ya que tenia un post en
el cual mostraba como poder usar ese control (mira el post ac), as que en esta entrada
deseo responder a esa pregunta.
Lo primero a tener en cuenta es que el control fileupload no funciona nativamente con
el protocolo FTP, sino con el HTTP, as que debemos realiza algunos pequeos cambios
y usar alguna clase de .net que nos permita trabajar con FTP; as que manos a la obra, lo
primero es disear una interfaz para la seleccin del archivo, y tres campos de texto para
el ingreso de:
Servidor FTP
Usuario
Clave
Entonces el HTML de nuestra pgina sera:
HTML
Copiar
<h1>Subir archivo a un servidor FTP</h1>
<hr />
<fieldset>
<legend>Configuracin FTP</legend>
<table>
<tr>
<td><b>Servidor:</b></td>
<td><asp:TextBox ID="txtServidor" runat="server"
Width="300px"></asp:TextBox></td>
</tr>
<tr>
<td><b>Usuario:</b></td>
<td><asp:TextBox ID="txtUsuario" runat="server"
Width="300px"></asp:TextBox></td>
</tr>
<tr>
<td><b>Clave:</b></td>
<td><asp:TextBox ID="txtClave" runat="server"
Width="300px"></asp:TextBox></td>
</tr>
<tr>
<td><b>Archivo:</b></td>
<td><asp:FileUpload ID="fileUpload1" runat="server" /></td>
</tr>
<tr>
<td colspan="2">
<asp:Button Text="Subir Archivo FTP" runat="server"
ID="btnSubirArchivo" onclick="btnSubirArchivo_Click" />
</td>
</tr>
</table>
</fieldset>

Y ahora el cdigo del evento clic del botn:
C#
Copiar
if (fileUpload1.HasFile)
{
var server = String.Format("{0}files/{1}", txtServidor.Text,
fileUpload1.FileName);
var user = txtUsuario.Text;
var pass = txtClave.Text;
var request = WebRequest.Create(server);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(user, pass);

var sourceStream = new StreamReader(fileUpload1.FileContent);
var fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
var response = (FtpWebResponse)request.GetResponse();
lblEstado.Text = response.StatusDescription;
response.Close();
}
Y listo, estamos tomando el archivo del fileupload, pero en este caso utilizamos
fileupload1.FileContent.

También podría gustarte