Comunidad de diseño web y desarrollo en internet online

Generador de menu contextual en Actionscript 3 para Flex

Un menú contextual puede ser de gran ayuda para mejorar la interacción de los usuarios con tu aplicación, brinda acceso directo a funciones que de otra manera llevarían mas pasos, demoras o simplemente ocuparían espacio valioso en la pantalla. A continuación veremos una clase que sirve para generar un menu contextual basado en un array que puede llegar por xml, remoteObject, etc.

En este tip asumiremos que puedes trabajar con una función genérica para procesar las opciones del menú, como por ejemplo devolver un dato al servidor, o enviarlo a un link determinado, eso dependerá de las necesidades de cada uno.

Recuerden: el menú contextual en Flash Player soporta un máximo de 15 items

MenuGenerator.as


Esta clase extiende EventDispatcher y le pasaremos unos parámetros en el constructor, que serán los elementos del menú y el nombre del campo que contendrá el texto a mostrar en cada opción (opcional, por default lo puse como "label")
Este objeto devolverá un evento tipo ResultEvent (solo para no tener que crear un evento propio, pero sientanse libres de hacer uno si lo prefieren) donde irán todos los datos asociados al elemento de menú en que se dio click.

Código :

package utils
{
   import flash.events.ContextMenuEvent;
   import flash.events.EventDispatcher;
   import flash.ui.ContextMenu;
   import flash.ui.ContextMenuItem;
   
   import mx.rpc.events.ResultEvent;

   public class MenuGenerator extends EventDispatcher
   {
      //un HashMap que me sirve para asociar el texto con el indice dentro del Array, para poder referenciar
      private var menuHashMap:Object = {};
      private var _menuContextual:ContextMenu = new ContextMenu();
      
      public function MenuGenerator(elementsArray:Array,_labelField:String = "label")
      {
         //Guardaremos todos los items dentro de un objeto temporal genObj
         var genObj:Object = {};
         //se remueven los items por default, es opcional, pero normalmente se hace
         _menuContextual.hideBuiltInItems();
         _menuContextual.customItems = [];
         //Recorremos todo el array para ir referenciando los elementos en el HashMap y 
         //agregándolos a _menuContextual
         for each (var thisMenu:Object in elementsArray)
         {
            menuHashMap[thisMenu[labelField]] = thisMenu;
            genObj[thisMenu[_labelField]] = new ContextMenuItem(thisMenu[_labelField]);
            genObj[thisMenu[_labelField]].addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,response);
            _menuContextual.customItems.push(genObj[thisMenu[_labelField]]);
         }
      }

      //El getter que devolverá el menu contextual ya construido
      public function get menuContextual():ContextMenu
      {
         return _menuContextual;
      }
      
      //finalmente disparamos el evento que consulta el HashMap para obtener toda la lista de datos
      //asociados al elemento del menú y enviarlo a quien esté escuchando
      private function response(event:ContextMenuEvent):void
      {
         var datos:Object;
         datos = menuHashMap[event.target.caption];
         this.dispatchEvent(new ResultEvent("Selection",false,true,datos));
      }
   }
}

Aplicación


Aquí lo usaré con un Array de ejemplo para mostrar como se aplica dentro de Flex

Código :

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
            creationComplete="application_creationCompleteHandler(event)">
   <fx:Script>
      <![CDATA[
         import mx.controls.Alert;
         import mx.events.FlexEvent;
         import mx.rpc.events.ResultEvent;
         
         import utils.MenuGenerator;
         
         private var menuItemsByArray:Array = [
            {nombre:"item1",label:"Primer Item",data:"first_function"},
            {nombre:"item2",label:"Segundo Item",data:"second_function"},
            {nombre:"item3",label:"Tercer Item",data:"third_function"}
            ];

         //creamos un objeto de tipo MenuGenerator para poder acceder a él dentro de toda la aplicación
         private var menuGenerator:MenuGenerator;

         
         private function application_creationCompleteHandler(event:FlexEvent):void
         {
            //Instanciamos el menuGenerator pasándole la lista de elementos
            menuGenerator = new MenuGenerator(menuItemsByArray);
            //asignamos el menú contextual a nuestra aplicación (this)
            this.contextMenu = menuGenerator.menuContextual;
            //Agregamos un listener para procesar el evento del menú
            menuGenerator.addEventListener("Selection",prueba);
         }
         
         //Aquí decides que hacer con los datos recibidos
         private function prueba(event:ResultEvent):void
         {
            Alert.show("el listener funciona, fué precionado el item con data: "+menuHashMap[event.target.caption].data);
         }
         
      ]]>
   </fx:Script>
</s:Application>

Conclusión


Poder generar un menú contextual a base de un archivo xml estático o generado por un php y llamado por un http service o como lo quieras ingresar puede tener muchas ventajas ya que los cambios en los nombres e incluso en la respuesta se pueden hacer sin tener que modificar el código original.

Esta es una clase sencilla que surgió como una necesidad de hacer las cosas un poco más dinámicas, potencialmente mejorable pero sirve como base para una gran funcionalidad no muy documentada :wink:

Suerte :D

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate