Editor de texto enriquecido jHtmlArea (WYSIWYG) para ASP.NET y jQuery

Los editores de texto enriquecidos o mejor conocidos como editores WYSIWYG (What You See is What You Got – Lo que ves es lo que obtienes) son de bastante utilidad para cierto tipo de desarrollos, como lo es cuando el usuario quiere modificar el mismo los estilos de lo que escribe, agregar listados o agregar hipervinculos, etc, sin que tenga que aprender HTML para realizarlo.

Buscando un buen rato por alguno sencillo, ligero y que se integrara rapidamente a ASP.NET/Mono, me encontre con jHtmlArea, un plugin para jQuery aun en desarrollo pero lo bastante estable como para poder utilizarlo en el proyecto que estoy desarrollando.

Editor WYSIWYG jHtmlArea

Configurarlo y usarlo es realmente sencillo:

  • Descarga el archivo del sitio web del proyecto.
  • Descarga jQuery.
  • Los archivos javascript agregarlos a una carpeta (js por ejemplo) y los CSS lo mismo (puede llamarse css el folder :P ).
  • Agregar las referencias de los archivos en el código:
    <head>
    	<script src="/js/jquery-1.3.2.min.js" type="text/javascript"></script>
    	<script src="/admin/js/jHtmlArea.ColorPickerMenu-0.7.0.min.js" type="text/javascript"></script>
    	<script src="/admin/js/jHtmlArea-0.7.0.min.js" type="text/javascript" ></script>
    
    	<link rel="stylesheet" type="text/css" href="/admin/css/jHtmlArea.css" />
    
    	<script type="text/javascript">
    		$(document).ready(function(){
    			$("textarea").htmlarea();
    		});
    	</script>
    </head>
  • Agregar un elemento <textarea> simple o un textbox multilinea de asp.net.
    <asp:TextBox runat="server" id="txtContenido" TextMode="MultiLine" Width="680" Height="300" ></asp:TextBox>

Con esto automaticamente cada elemento textarea aparecera con las opciones del editor, existen otras configuraciones como agregar o eliminar elementos de la barra de botones tal y como lo indica el autor en su sitio.

Tip, instalar librerías de VB.NET en Mono

Últimamente he estado hablando mucho de Mono, pero es que me he metido bastante ahora que puedo desarrollar proyectos por mi cuenta, aplicando todo lo que se de .NET pero en Mac/Linux, así seguirá por un rato, mientras les traigo este otro tipo que es de bastante ayuda.

En Mono cuando quieres ejecutar un programa o usar una dll que llame contenga librerias de VB.NET, te puede dar un error como el siguiente:

Could not load file or assembly 'Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.

Para solucionarlo lo único que se tiene que hacer es correr en la consola el siguiente comando:

sudo apt-get install libmono-microsoft-visualbasic8.0-cil

Si no haz actualizado apt-get te aconsejo que lo hagas antes de que corras el comando, ya que te puede marcar algún error.

Y listo, con esto las librerías necesarias para interpretar VB se instalan en tu equipo y puedes correr esas aplicaciones que te daban problemas.

Tip: Solución a Failed to find or load the registered .Net Framework Data Provider ‘MySql.Data.MySqlClient’

Este error me ocurrió el día de hoy cuando intentaba usar una dll de acceso a datos que me paso un amigo para un proyecto en el cual estamos trabajando juntos, estamos usando Mono en Mac y como servidor de pruebas Ubuntu 9.4 con Mono, MySQL en ambos.

El mensaje de error que me dio al intentar probar las conexiones con la base de datos fue:

Failed to find or load the registered .Net Framework Data Provider 'MySql.Data.MySqlClient'

La solución la encontre en las listas de Mono-dev, y fue simplemente agregar las referencias exactas para el ensamblado de MySQL, en el archivo Web.Config o App.Config hay que agregar lo siguiente dentro de las etiquetas <configuration> … </configuration>

  	<system.data>
        <DbProviderFactories>
			<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL"  type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=5.2.1.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
		</DbProviderFactories>
	</system.data>

Cabe notar que en la maquina donde estoy trabajando, tengo instalado MySQL y agregue como referencia la dll del conector de MySQL (MySql.Data.dll).

Ojalá a alguien le sirva.

DropDownList en cascada con jQuery y ASP.NET

Como usar DropDownList o Selects en cascada con ASP.NET y jQuery?, es una de las dudas que mas se generan en los foros de discusión al momento de realizar cosas con AJAX y .NET sin el UpdatePanel.

Voy a explicar como realizo esta tarea para que sea un proceso sencillo.

Crearemos un nuevo proyecto web y nos aseguraremos de configurarlo para que pueda usar jQuery.

En la pagina Default.aspx agregaremos dos DropDownList y quedara algo como el siguiente codigo:

<%@ Page Language="C#" Inherits="EjemploDropDownList.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head runat="server">
	<title>Ejemplo DropDownList</title>
	<script src="js/jquery-1.4.2.min.js" type="text/javascript" ></script>
</head>
<body>
	<form id="form1" runat="server">
		<asp:DropDownList runat="server" id="ddlPrincipal" ></asp:DropDownList>

		<br />

		<asp:DropDownList runat="server" id="ddlSecundario" > </asp:DropDownList>
	</form>
</body>
</html>

Lo unico que hace este código es agregar la referencia de jQuery (la 1.4.2) y dos DropDownList, sin ningún otro control ni tampoco código que tenga que ser procesado aun por el servidor.

Enseguida vamos a llenar el primer DropDownList (ddlPrincipal) con algunos datos, en este caso seran continentes, esto lo vamos a colocar en el evento Load de la pagina Default.aspx:

private void Page_Load(object sender, System.EventArgs e)
		{
			ListItem elemento;

			elemento = new ListItem("America", "1");
			ddlPrincipal.Items.Add(elemento);

			elemento = new ListItem("Africa", "2");
			ddlPrincipal.Items.Add(elemento);

			elemento = new ListItem("Europa", "3");
			ddlPrincipal.Items.Add(elemento);
		}

Corremos el proyecto y nos debe mostrar algo como esto:

Ejemplo de DropDownList

Ahora es tiempo de meter un poco de código JavaScript en nuestra aplicación, para eso insertaremos el siguiente código entre las etiquetas <head> de Default.aspx :

<script type="text/javascript">
		$(document).ready(function(){

		// Configuracion de jQuery y AJAX
		$.ajaxSetup({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: "{}",
            dataFilter: function(data) {
                var msg;

                if (typeof (JSON) !== 'undefined' &&
                    typeof (JSON.parse) === 'function')
                  msg = JSON.parse(data);
                else
                  msg = eval('(' + data + ')');

                if (msg.hasOwnProperty('d'))
                  return msg.d;
                else
                  return msg;
            }
        });

			// Solo se ejecuta cuando seleccionamos alguna opcion.
			$('#<%=ddlPrincipal.ClientID %>').change(function(){
				$.ajax({
					url: "Default.aspx/obtenerPaises",
					data: "{'continente':'" + $("#<%=ddlPrincipal.ClientID %>").val() + "'}",
					success: function(msg) {
						$('#<%=ddlSecundario.ClientID %>').html(msg);
					},
					error: function(XMLHttpRequest, textStatus, errorThrown) {
				       alert('Error: ' + textStatus + ", " + errorThrown);
				   }
				});
			});

		});
	</script>

Este código hace dos cosas:

  1. Configura jQuery para usar AJAX y JSON como nosotros necesitamos y nos evita un pequeno malestar respecto a las “d” en los .NET frameworks anteriores a 3.5.
  2. Captura el evento Change del DropDownList Principal que ocurre cuando se selecciona cualquier opción del DropDownList y va a buscar el código que se ejecutara por .NET para traer lo que haga falta.

Como nota especial, si observan estoy pidiendo la información de la misma pagina “Default.aspx” y no de un WebService que es como comúnmente se hacen estas peticiones, a esto se le llama usar WebMethods.

Enseguida veremos el código que en .NET dependiendo de la opción seleccionada traerá una respuesta diferente, para lo cual agregaremos al archivo Default.aspx.cs el siguiente codigo debajo de Load_Page :

[WebMethod()]
		public static string obtenerPaises(string continente)
		{
			List<ListItem> elementos = new List<ListItem>();
			ListItem elemento;
			string resultado = "";

			// Usaremos simples 'if' para hacer sencillo el ejemplo.
			if (continente == "1") {
				elemento = new ListItem("Mexico", "1");
				elementos.Add(elemento);
				elemento = new ListItem("EUA", "2");
				elementos.Add(elemento);
			}

			if (continente == "2") {
				elemento = new ListItem("Kenia","1");
				elementos.Add(elemento);
				elemento = new ListItem("Congo","2");
				elementos.Add(elemento);
			}

			if (continente == "3") {
				elemento = new ListItem("Francia","1");
				elementos.Add(elemento);
				elemento = new ListItem("Italia","2");
				elementos.Add(elemento);
			}

			foreach (ListItem item in elementos) {
				resultado = resultado + "<option value='" + item.Value + "'>";
				resultado = resultado + item.Text;
				resultado = resultado + "</option>,";
			}

			return resultado;
		}

Este código como verán es bastante sencillo y lo unico que hace es recibir como parametro el “continente” y en base al que se selecciono agregar a un listado ciertos elementos y al final regresar una cadena de <options> de un select de HTML.

Segunda nota: el nombre de la variable que recibe el parametro debe ser el mismo que el que pasamos en el javascript (data: “{‘continente’: … )

Y listo, ahora hay que correr el proyecto y esto nos permitira realizar DropDownList en cascada.

Predicciones al futuro de la programacion

Andando un poco en Stackoverflow me encontre con esto y me hizo bastante gracia!

My predictions for the future of programming:

  • Every 2 years there will be a great hot new language that you just have to use.
  • Every 5 years Microsoft will come up with a completely new way to create GUIs.
  • Every 10 years someone will come up with a great new software development methodology.
  • Every 20 years someone will come up with a great new programming paradigm.
  • Until the heat death of the universe, there will still be more installed and running legacy Cobol code than everything else put together.

Bastante gracioso! :P