margenn

YUI 2.8 vs. Dojo 1.6 (I) - Calendario

Posted on March 19, 2011 by

A little bit about me

Me encanta Javascript! Mi compañero y socio Jano es quien mejor conoce cuánto me gusta. Ya desde mis inicios en el desarrollo web allá por 2006 cuando empezaba la revolución AJAX vi el potencial de dicho lenguaje para crear aplicaciones web altamente interactivas e incluso one-page-apps como Gmail. Además de tener potencial, el lenguaje me gustaba y era divertido jugar con él modificando una página, actualizando parte del contenido “por arte de magia” sin que la página sufriera un refresco, etc…

En dicha época (2005-2006) afortunadamente surgieron muchos proyectos cuyo objetivo era dotar a los desarrolladores de Javascript de herramientas que nos hicieran la vida más fácil a la hora de añadir interactividad y experiencia de usuario a una página o aplicación web.

Cuando por primera vez conocí jQuery, me pareció horrible…no era el javascript que yo conocía…me parecía alienígena y en un primer momento lo dejé de lado.

Un tiempo más tarde, jQuery no sólo ya no me parecía alienígena sino que lo consideraba fundamental para desarrollar un proyecto cross-browser y en una cuarta parte del tiempo.

Con el tiempo surgieron muchos frameworks, más de cien…pero eran menos de diez los favoritos y realmente buenos. De estos diez, dos llamaron mi atención: YUI y Dojo.

YUI y Dojo eran entonces y son hoy mucho más que una librería para manipular el DOM y realizar llamadas asíncronas con facilidad. Ofrecían y siguen ofreciendo un parque temático de widgets muy amplio y útil además de otras niceties como gestión de dependencias o internacionalización. Son Javascript frameworks con los que puedes construir una aplicación web de principio a fin sin utilizar librerías o plugins adicionales. No era ni es el caso de jQuery.

No quiero que se me entienda mal, me encanta jQuery pero para lo que fue concebido, ser la navaja suiza del DOM y aún sigue siendolo.

De modo que alucinado por lo que ofrecían tanto YUI como Dojo en aquel tiempo y la potencia de jQuery para manipular el DOM, tomé dos decisiones:

  • jQuery era (y sigue siendo) la mejor herramienta para manipular el DOM, mientras que YUI y Dojo ofrecían soluciones más pobres de modo que jQuery tenía que estar en mi arsenal.
  • YUI vs. Dojo: La decisión más difícil…probé ambos durante un tiempo y me convenció YUI por diferentes motivos:
    - Yahoo! 
    - Mejor documentación y organización
    - Comunidad mayor
    - Muy estable

Así que tenía dos herramientas sobre la mesa, jQuery y YUI y vi que ambas se complementaban. jQuery lo usaría para manipulación del DOM y gestión de los eventos y YUI para todo lo demás. So far, so good.

He pasado los últimos años utilizando esta solución mixta y con muy buenos resultados y experiencias pero desde el lanzamiento de Dojo 1.5 y la firme apuesta de Dojo por mejorar la documentación me he vuelto a replantear la pregunta ¿Qué herramienta(s) debo utilizar para el front-end development? Dojo 1.5 y esa pregunta han producido que escriba esta serie de artículos.

Como jQuery está para mi en otra liga distinta a la de YUI y Dojo, la cuestión es clara, ¿cuál elijo entre YUI y Dojo? y si elijo Dojo…¿podrá sustituir también a jQuery y convertirse en mi única herramienta? Si seguis esta serie conocereis mi decisión final.

Bien…y ¿cómo voy a comparar YUI y Dojo?

De la única manera posible, utilizando ambos head to head valorando qué ofrece cada uno y cuál resulta más productivo para las mismas tareas.

Hey…y ¿qué pasa con YUI 3?

YUI 3 lamentablemente está aún hoy bastante verde (incompleto y beta en su mayoría) como para ser comparado con YUI 2.8 o Dojo 1.6.

Se que YUI 2.x puede ser utilizado con YUI 3 para cubrir las carencias de este último pero no considero este hecho relevante ya que YUI 3 no es más que un rewrite completo de YUI 2, es decir, más de lo mismo pero con arquitectura, rendimiento y flexibilidad mejorados.

El calendario

En este primer artículo de la serie voy a comparar un widget que he utilizado bastante en los proyectos, el famoso calendario.

Os pondré en contexto, el objetivo del test o demo es asociar un calendario a un campo de texto de un formulario en el que el usuario debe introducir una fecha, de tal forma que cuando el usuario vaya a introducir la fecha, se despliegue un calendario para hacerle más cómoda la selección.

Sin más preámbulos echad un ojo al código fuente de la magnífica demo que he creado  :) y juguetead con ambas implementaciones del calendario antes de continuar leyendo.

Notas del desarrollo con Dojo:

  • Con 4 lineas de código terminado. 
  • El resultado es genial
  • HTML, CSS, comportamiento, localización (i18n), validación y advertencias visuales y localizadas en caso de fechas imposibles 100% automatizados.
  • He tardado 2 minutos
<form> 
    <fieldset> 
        <legend>Dojo calendar input</legend> 
        <label>Select a date:</label> 
        <input type="text" name="dojocalendar" data-dojo-type="dijit.form.DateTextBox" data-dojo-props="name:'dojocalendar',type:'text'"> 
        <input type="submit" value="Send"> 
    </fieldset> 
</form>          
dojo.require("dijit.form.DateTextBox");

Notas del desarrollo con YUI:

  • He necesitado crear HTML adicional (para poder mostrar el calendario) y asignar el atributo autocomplete=”off” al input para que el navegador no muestre un listado de fechas introducidas anteriormente por el usuario.
  • He necesitado crear estilos CSS adicionales.
  • He necesitado implementar todos los eventos de interacción del usuario con el campo de texto (focus porque no hay un indicador visual de que existen valores seleccionables, click para mostrar y ocultar el calendario y keyup para actualizar el calendario si el usuario escribe o cambia la fecha manualmente) y el documento (ocultar el calendario al hacer click tanto fuera del campo de texto como del calendario) para igualar el comportamiento de Dojo.
  • He necesitado localizar el calendario a mi idioma traduciendo las cadenas de texto del mismo e indicando aspectos como qué día de la semana es el primero en aparecer en cada semana de un calendario (Lunes, no Domingo).
  • He necesitado formatear la fecha devuelta por el calendario de dos formas: una de un modo humano y localizado para mostrarsela al usuario y otra en el formato literal date en SQL (como Dojo).
  • He necesitado bastantes más lineas de código.
  • El resultado es bueno, pero no tan bueno como el de Dojo ya que este incluso valida la fecha introducida por un usuario y si es una fecha imposible le alerta visual y descriptivamente además de en su localización. Para igualar el mismo comportamiento en YUI necesitaría un icono, rutina de comprobación de fecha válida, el widget para crear tooltips, el mensaje localizado a mostrar y más HTML y CSS.
  • He necesitado más de 30 minutos.
<form> 
    <fieldset> 
        <legend>YUI calendar input</legend> 
        <label>Select a date:</label> 
        <div class="yuicalendar-popup-wrapper"> 
            <input type="text" id="yuicalendarinput" autocomplete="off"> 
            <input type="hidden" id="yuicalendarhiddeninput" name="yuicalendar"> 
            <div id="yuiCalendarContainer"></div> 
        </div> 
        <input type="submit" value="Send"> 
    </fieldset> 
</form>  
(function(y){
    var initYUI = function(){
        var yue = y.util.Event,
            yud = y.util.Dom,
            yuiCalContainer = yud.get('yuiCalendarContainer'),
            yuiCalInput = yud.get('yuicalendarinput'),
            yuiCalHiddenInput = yud.get('yuicalendarhiddeninput'),
            
            setDate = function(type, args, obj) {
                var date = args[0][0], 
                    year = date[0], 
                    month = date[1], 
                    day = date[2],
                    userDate = (day < 10 ? "0" + day : day) + "/" + (month < 10 ? "0" + month : month) + "/" + year;

                yuiCalInput.value = userDate;
                updateInputDate(userDate);
                yuiCalendar.hide();
            },
            
            getDateFields = function(userDate){
                return userDate.split("/");
            },
            
            updateInputDate = function(userDate){
                var dateFields = getDateFields(userDate);
                yuiCalHiddenInput.value = dateFields[2] + "-" + dateFields[1] + "-" + dateFields[0];
            },
            
            updateCalendar = function(e){
                var month, year, dateFields, userDate = this.value;

                if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(userDate)) {
                    dateFields = getDateFields(userDate);
                    month = dateFields[1];
                    year = dateFields[2];
                    updateInputDate(userDate);
                    yuiCalendar.cfg.setProperty("selected", userDate, false);
                    yuiCalendar.cfg.setProperty("pagedate", month + "/" + year, false);
                    yuiCalendar.render();
                }
            },
            
            yuiCalendar = new y.widget.Calendar("yuiCalendarContainer", { 
                locale_weekdays: "1char",
                navigator: {
                    strings : { 
                        month: "Selecciona un Mes", 
                        year: "Introduce un Año", 
                        submit: "Hecho", 
                        cancel: "Cancelar", 
                        invalidYear: "Por favor, introduce un año válido" 
                    }
                },
                start_weekday: 1,
                MDY_DAY_POSITION: 1,
                MDY_MONTH_POSITION: 2,
                MDY_YEAR_POSITION: 3,
                MONTHS_LONG: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
                WEEKDAYS_1CHAR: ["D", "L", "M", "M", "J", "V", "S"]
            });
         
        yuiCalendar.selectEvent.subscribe(setDate);
        yuiCalendar.render();
        
        yue.on("yuicalendarinput", "keyup", updateCalendar);
        
        yue.on("yuicalendarinput", "focusin", function(e) {
            this.className = "focused";
            yuiCalendar.show(); 
        });
        
        yue.on("yuicalendarinput", "click", function(e) {
            if (this.className == "focused") {
                this.className = "";
                return;
            }
            
            if (yuiCalContainer.style.display == "block") {
                yuiCalendar.hide();
            } else {
                yuiCalendar.show();
            }
        });
        
        yue.on(document, "click", function(e) {
            var el = yue.getTarget(e);

            if (el != yuiCalInput && el != yuiCalContainer && !yud.isAncestor(yuiCalContainer, el)) {
                yuiCalendar.hide();
            }
        });
    };
    
    (new y.util.YUILoader({
        require: ["calendar"],
        loadOptional: false,
        onSuccess: initYUI,
        timeout: 10000,
        combine: false
    })).insert();
}(YAHOO));

Bueno, esas son mis notas de desarrollo…sin duda alguna Dojo ofrece muuuchas más ventajas sobre YUI en este escenario tan real y típico como la vida misma. Dojo cubre de forma automatizada y productiva todas las necesidades típicas en este escenario y por ello le doy un 10.

Por último he comparado las opciones que nos da cada framework en cuanto a usos del calendario más allá del típico (flexibilidad):

  • Con YUI podemos crear grupos de calendarios (Multi-Page)
  • Con YUI podemos seleccionar varias fechas en un mismo calendario (Multi-Select)
  • Todo lo demás puede hacerse con ambos frameworks de un modo u otro.

Tanto el Multi-Page como el Multi-Select de YUI me parecen de bastante poca utilidad la verdad. No he encontrado hasta la fecha un escenario donde haya necesitado dichas soluciones.

Conclusión

YUI 0 - 1 Dojo

Dojo ha demostrado ser mejor en todos los aspectos en esta comparación, dejando por los suelos a YUI.

¿Y vosotros qué opinais? ¿Con cuál os quedariais?

Espero que os haya gustado mi análisis y la demo, en el próximo combate entre YUI y Dojo analizaré otro widget, el autocomplete.

Stay tuned!!

Tags: yui dojo calendar calendario javascript framework widget

Estamos siendo testigos de un revuelo considerable en torno a EllisLab, la compañía de Oregon que desarrolla los CMS comerciales ExpressionEngine y MojoMotor, los cuales corren sobre su framework de código libre CodeIgniter.

En poco menos de dos meses hemos visto cómo empleados de EllisLab, que llegaron desde la comunidad de CodeIgniter, abandonan la compañía por falta de motivación. Como es el caso de Derek Allard o más recientemente de Dan Horrigan.

Se ha hecho patente el hastío de relevantes seguidores de ExpressionEngine y su frustrante relación con EllisLab, condensado en el artículo A Plea to EllisLab, el cual recibió respuesta oficial por parte del presidente Leslie Camacho, I Hear You.

En escasas dos semanas tras la tormenta de ExpressionEngine se abre otro frente, esta vez contra CodeIgniter, representado una vez más por varios destacados miembros de la comunidad y catalizado por el artículo What happens next? de Phil Sturgeon, en respuesta al comunicado de Derek Jones, CTO de EllisLab, What’s Happening Now?.

Con todo ésto, ya hubo quien no dudó en anunciar el declive y muerte de CodeIgniter. Una oleada de agoreros lo promulgaba en twitter.

La comunidad

¿Ha muerto? No. De hecho está mejor que nunca. ¿Morirá? No a corto plazo. En mi opinión, tiene exactamente las mismas expectativas de vida que cualquier otro framework popular. Y si lo hiciera, más bien sería una reencarnación, al estilo del nuevo framework que se está gestando, FuelPHP, o como ocurriera hace ya hace más de dos años con Kohana.

CodeIgniter es sinónimo de simplicidad, rendimiento y flexibilidad. Además de tener una excelente documentación y comunidad. Tiene la virtud de haber bajado la barrera de entrada a los frameworks MVC, al igual que lo hiciera PHP como lenguaje de programación web. Incluso Rasmus Lerdorf, creador de PHP, no dudó en destacar esas cualidades frente a otros frameworks.

Todo ésto ha atraído cada vez a más gente hasta convertirlo en mainstream. Y aquí es donde la compañía EllisLab ve la oportunidad…

La compañía

EllisLab depende de CodeIgniter. Ahora es la base de sus productos. Ya no es un mero subproducto de ExpressionEngine, un experimento. Ahora CodeIgniter es la base de su estrategia, para bien o para mal. Han invertido muchos recursos en reescribir enteramente ExpressionEngine 2.0 sobre CodeIgniter (algo que según Joel Spolsky nunca deberías hacer).

Por un lado EllisLab está interesada en la comunidad de desarrolladores a la que poder atraer hacia sus productos y en el ecosistema de desarrolladores y proveedores de soluciones para sus productos. Pero por otro lado no quiere perder ni un ápice de control sobre lo que sustenta sus productos, CodeIgniter.

En esa encrucijada se encuentra.

Si ya cuando CodeIgniter no era la base de sus productos era difícil que aceptaran contribuciones ahora se plantea aún más complicado.

Por un lado desean una comunidad de desarrolladores en torno a sus productos, pero por otro lado desconfían del valor que puedan aportar a la mejora y extensión del mismo. No es una relación bidireccional. No hay comunicación. Sin comunicación no hay confianza, y sin confianza no hay expectativas ni relación posible.

Entendámonos, hablemos

Éso es lo que quería decir con “EllisLab 2.0”. Una comunicación más transparente y fluida entre compañía y comunidad. Y unos mecanismos que garanticen la participación.

El cambio que demanda la comunidad.

Y en esa dirección han empezado a dar algún pequeño y tímido paso, con el nuevo ExpressionEngine Forecast.

Veamos como gestionan el crecimiento y su comunidad.

Suerte.

Tags: codeigniter expressionengine mojomotor framework php ellislab

CodeIgniter 2.0 Ya! No esperes más.

Posted on October 20, 2010 by

Vale, parece ser que a nadie le pilla por sorpresa que la publicación de CodeIgniter 2.0 no se haya realizado todavía. Al fin y al cabo, EllisLab no se ha caracterizado precisamente por la filosofía de “Release early, release often”.

A fecha de hoy, la última versión estable 1.7.2 fue publicada hace ya más de un año (septiembre 2009). Pero eso no es nada comparado con el enorme retraso que sufrió el anticipado anuncio de ExpressionEngine 2.0 (CMS de EllisLab desarrollado sobre CodeIgniter) en febrero de 2008, según el cual estaría disponible para el verano de 2008, pero no llegaron a publicar una versión estable hasta julio de 2010. Nada menos que dos años por encima de lo previsto.

Con estos antecendentes podría parecer que CodeIgniter 2.0 queda todavía muy lejos y que por tanto no deberíamos considerarlo para código de producción.

¡Nada de eso!

CodeIgniter 2.0 a pesar de no estar oficialmente lanzado es de hecho más estable que la actual versión 1.7.2. Cabe destacar que los dos productos comerciales de EllisLab, ExpressionEgine y MojoMotor, están desarrollados sobre CodeIgniter 2.0.

En palabras de Phil Sturgeon (miembro destacado de la comunidad de CodeIgniter):

I’ll mention that every bug noticed in 1.7.2 is fixed in 2.0. That means in many ways 2.0 is actually more stable than 1.7.2, even if it is not a “final release”.


Si finalmente te decides a dar el paso visita el repositorio de CodeIgniter para descargar el código fuente o para clonarlo. Y no dejes de echar un vistazo a los siguientes artículos:

¿A qué esperas?

Tags: codeigniter development desarrollo php framework