2
votes

I have a menu system set up in a panel which needs to be dynamically created. I have created a mock static menu which the client likes but the menu categories and items will need to be loaded via JSON from a store.

Here is what I have for the first few menu items set statically:

Ext.define('SimpleSearch.view.FacetSDL' ,{
extend: 'Ext.panel.Panel',
alias : 'widget.facetsdl',  //alias is referenced in MasterList.js
requires: ['SimpleSearch.store.SDLResults', 'FacetData' ],
title: 'Facet Search',
html: null,
frame: true,
layouts: 'fit',

items: [
  {
    id: 'group-menu',
    title: 'Browse',
    xtype: 'menu',
    plain: true,
    floating: false, 
    layouts: 'fit',
    items: [
      {
        text: 'Security',
        listeners:
          {
            click: function() { 
                     var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
                     groupmenu.hide() 
                     var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
                     securitymenu.setPosition(0,-groupmenu.getHeight(),false);
                     securitymenu.show()
                   }
          },
        menu: {        // <-- submenu by nested config object
          items: [
            {
              text: 'Classification',
              listeners:
              {
                click: function() { 
                     var groupmenu = Ext.ComponentQuery.query('#group-menu')[0];
                     groupmenu.hide() 
                     var securitymenu = Ext.ComponentQuery.query('#security-menu')[0];
                     var classificationmenu = Ext.ComponentQuery.query('#classification-menu')[0];
                     classificationmenu.setPosition(0,-groupmenu.getHeight() - securitymenu.getHeight(),false);
                     classificationmenu.show()
                }

I was thinking that maybe creating a class that loads all of the necessary data and then iterating through that class for the "items" field may be the way to go, but I am not sure if that will work.

3
I ended up dynamically loading the panel menu by doing a for loop through the JSON data, doing an add to the view for each new element. It looks a lot better than the tree and allows me to customize things easier.Elwar

3 Answers

0
votes

You should look at using a Tree and TreeStore. Then make use of the ui:'menu' or viewConfig { ui: 'menu' } config properties to differentiate it from a regular tree. Then style it however your client wants.

This way you have all the mechanisms in place for free to handle the data dynamically and all your submenus, you'll just have to get a little creative on the CSS side of things.

0
votes

I got it working like this:

var scrollMenu = Ext.create('Ext.menu.Menu');

    for (var i = 0; i < store.getCount(); ++i){
        var rec = store.getAt(i);

        var item =  new Ext.menu.Item({
            text: rec.data.DISPLAY_FIELD,
            value:rec.data.VALUE_FIELD,
            icon: 'js/images/add.png',
            handler: function(item){
                myFunction(item.value);  //Handle the item click
            }
        });

        scrollMenu.add(item);
    }

Then just add scrollMenu to your form or container. Hope this helps!

-1
votes

This menu is created dynamically with ExtJs, the data is loaded from Json.

Create a dynamic menu from Json using ExtJs

See my demo with the code.

Demo Online: https://fiddle.sencha.com/#view/editor&fiddle/2vcq

Json loaded: https://api.myjson.com/bins/1d9tdd

Code ExtJs:

//Description:  ExtJs - Create a dynamical menu from JSON
//Autor:        Ronny Morán <[email protected]>

Ext.application({
    name : 'Fiddle',
    launch : function() {

        var formPanelFMBtn = Ext.create('Ext.form.Panel', {
                bodyPadding: 2,
                waitMsgTarget: true,
                fieldDefaults: {
                    labelAlign: 'left',
                    labelWidth: 85,
                    msgTarget: 'side'
                },
                items: [
                    {
                         xtype: 'container',
                         layout: 'hbox',
                         items: [

                         ]
                      }
                ]
        });

        var win = Ext.create('Ext.window.Window', {
                title: 'EXTJS DYNAMICAL MENU FROM JSON',
                modal: true,
                width: 680,
                closable: true,
                layout: 'fit',
                items: [formPanelFMBtn]
            }).show();

    //Consuming JSON from URL using method GET
    Ext.Ajax.request({
        url: 'https://api.myjson.com/bins/1d9tdd',
        method: 'get',
        timeout: 400000,
        headers: { 'Content-Type': 'application/json' },
        //params : Ext.JSON.encode(dataJsonRequest),
        success: function(conn, response, options, eOpts) {
                var result = Ext.JSON.decode(conn.responseText);
                //passing JSON data in 'result'
                viewMenuDinamical(formPanelFMBtn,result);
            },
        failure: function(conn, response, options, eOpts) {
                //Ext.Msg.alert(titleAlerta,msgErrorGetFin);
        }
    });

    }
});

//Generate dynamical menu with data from JSON
//Params:   formPanelFMBtn  - > Panel
//          result          - > Json data
function viewMenuDinamical(formPanelFMBtn,result){

    var resultFinTarea          = result;
    var arrayCategoriaTareas    = resultFinTarea.categoriaTareas;
    var containerFinTarea       = Ext.create('Ext.form.FieldSet', {
                                        xtype: 'fieldset',
                                        title: 'Menu:',
                                        margins:'0 0 5 0',
                                        flex:1,
                                        layout: 'anchor',
                                        //autoHeight: true,
                                        autoScroll: true,
                                        height: 200,
                                        align: 'stretch',
                                        items: [

                                        ]
    });
    var arrayMenu1              = [];

    //LEVEL 1
    for(var i = 0; i < arrayCategoriaTareas.length; i++)
    {
        var categoriaPadre          = arrayCategoriaTareas[i];
        var nombrePadre             = categoriaPadre.nombreCategoria;
        var hijosPadre              = categoriaPadre.hijosCategoria;
        var arrayMenu2              = [];

            //LEVEL 2
            for(var j = 0; j<hijosPadre.length; j++)
            {
                var categoriaHijo           = hijosPadre[j];
                var nombreHijo              = categoriaHijo.nombreHijo;
                var listaTareas             = categoriaHijo.listaTareas;
                var arrayMenu3              = [];

                    //LEVEL 3
                    for(var k = 0; k < listaTareas.length; k++)
                    {
                        var tarea = listaTareas[k];
                        var nombreTarea = tarea.nombreTarea;
                        var objFinLTres =
                        {
                            text: nombreTarea,
                            handler: function () {
                                alert("CLICK XD");
                            }
                        };
                        arrayMenu3.push(objFinLTres);
                    }

                var menuLevel3          = Ext.create('Ext.menu.Menu', {
                    items: arrayMenu3
                });

                var objFinLDos;
                    if(arrayMenu3.length > 0)
                    {
                        objFinLDos = {
                            text: nombreHijo,
                            menu:menuLevel3
                        };
                    }
                    else
                    {
                        //without menu parameter If don't have children
                        objFinLDos = {
                            text: nombreHijo
                        };
                    }

                arrayMenu2.push(objFinLDos);
            }
            var menuLevel2          = Ext.create('Ext.menu.Menu', {
                items: arrayMenu2
            });

            var objFinLUno;
            if(arrayMenu2.length > 0)
            {
                objFinLUno = {
                    text: nombrePadre,
                    menu:menuLevel2
                };
            }
            else
            {
                //without menu parameter If don't have children
                objFinLUno = {
                    text: nombrePadre
                };
            }

            arrayMenu1.push(objFinLUno);
    }

    var mymenu      = new Ext.menu.Menu({
                        items: arrayMenu1
                    });


    containerFinTarea.add({
            xtype: 'splitbutton',
            text: 'Example xD',
            menu: mymenu
        });

    formPanelFMBtn.add(containerFinTarea);
}