Como abrir páginas de um menu no centro de sua aplicação

Sorry, this entry is only available in Português.

Muitas aplicações se baseiam em um layout com links na esquerda e com um tabPanel ao centro. Depois de responder alguns posts no fórum brasileiro sobre como abrir itens de um menu em um tabPanel central, estou escrevendo sobre o assunto aqui no blog através de tutorial.

Primeiramente vamos criar uma subpasta abrirPaginaCentro dentro da pasta examples do Ext. Depois disso criar um arquivo index.html com o código abaixo e um arquivo abrirPaginaCentro.js, por enquanto em branco.

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
        <title>Abrindo páginas de menu no centro da aplicação - www.extdesenv.com.br</title>

		<!--css-->
        <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css"/>
        <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
        <link rel="stylesheet" type="text/css" href="../shared/icons/silk.css" />
        <style type="text/css">
            .no-icon {
                display: none;
            }
        </style>

        <!--js-->
        <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
        <script type="text/javascript" src="../../ext-all.js"></script>
        <script type="text/javascript" src="abrirPaginaCentro.js"></script>
    </meta></head>
    <body>
    </body>
</html>

Sua configuração deve estar assim:

  • examples
    • abrirPaginaCentro
      • abrirPaginaCentro.js
      • index.html

Então agora no arquivo JS vou criar definir uma nova classe AbrirPaginaCentro:

var AbrirPaginaCentro = Ext.extend(Ext.util.Observable,{

	constructor: function(){
		//..aqui vai toda definição dos componentes...

		//super
		AbrirPaginaCentro.superclass.constructor.apply(this,arguments);
	}
});

Ext.onReady(function()
{
	new AbrirPaginaCentro();
});

Feito esse esqueleto de classe vamos em 3 passos fazer tudo funcionar:

  1. Crio os componentes: o tabPanel, o viewport para conter os itens, e o menu lateral formado de um painel accordion com treePanels. O seu menu lateral pode ser o que quiser, treePanels, labels, buttons…Não importa o componente, o que importa é que quando clicado dispare um evento.

    //tabPanel
    this.tabPanelCentral = new Ext.TabPanel({
        region		: 'center',
        activeTab	: 0,
        defaults	: {closable: true},
        items		: [{
            title		: 'Portal',
            closable	: false
        }]
    });
    
    //criar layout
    new Ext.Viewport({
    	 layout	: 'border'
    	,items	: [{
    	//menu lateral
    		 region			: 'west'
    		,layout			: 'accordion'
    		,defaultType	: 'treepanel'
    		,width			: 300
    		,split			: true
    		,layoutConfig	: {fill: false, animate:true}
    		,defaults		: {
    			 border		: false
    			,rootVisible: false
    			,listeners:{
    				 scope: this
    				,click: this.onNodeClick
    			}
    		}
    		,items			: [{
    			 title	: 'Cadastros'
    			,iconCls: 'silk-add'
    			,root	: {
    				children: [
    					 {text:'Atendentes'		, leaf:true, iconCls:'no-icon'}
    					,{text:'Solicitantes'	, leaf:true, iconCls:'no-icon'}
    					,{text:'Clientes'		, leaf:true, iconCls:'no-icon'}
    					,{text:'Representantes'	, leaf:true, iconCls:'no-icon'}
    					,{text:'Produtos'		, leaf:true, iconCls:'no-icon'}
    					,{text:'Distribuidores'	, leaf:true, iconCls:'no-icon'}
    					,{text:'Compromissos'	, leaf:true, iconCls:'no-icon'}
    				]
    			}
    		},{
    			 title	: 'Configurações'
    			,iconCls: 'silk-cog'
    			,root	: {
    				children: [
    					 {text:'Feriados'		  ,leaf:true,iconCls:'no-icon'}
    					,{text:'Permissões'		  ,leaf:true,iconCls:'no-icon'}
    					,{text:'Horários'		  ,leaf:true,iconCls:'no-icon'}
    					,{text:'Cargas'			  ,leaf:true,iconCls:'no-icon'}
    					,{text:'Acesso ao sistema',leaf:true,iconCls:'no-icon'}
    				]
    			}
    		},{
    			 title	: 'Relatórios'
    			,iconCls: 'silk-grid'
    			,root	: {
    				children: [
    					 {text:'Tempo Trabalhado por Atendente',leaf:true,iconCls:'no-icon'}
    					,{text:'Vendas por Cliente'			   ,leaf:true,iconCls:'no-icon'}
    					,{text:'Rotas de Distribuição'		   ,leaf:true,iconCls:'no-icon'}
    					,{text:'Performance dos Representantes',leaf:true,iconCls:'no-icon'}
    				]
    			}
    		}]
    	},
    	//tabpanel central
    	this.tabPanelCentral]
    });
  2. Perceba que pouco antes de definir os TreePanels eu associei uma função (listener) ao evento click a cada um deles. Essa função deve ser definida em nossa classe. A documentação do Ext nos diz quais os parâmetros receber nesse listener:

    //...
    ,listeners:{
    	 scope: this
    	,click: this.onNodeClick
    }
    
    //...
    ,onNodeClick: function( node )
    {
    	//aqui vai nossa rotina para criar as abas
    }
    
  3. Por fim, nessa função vou implementar uma regra de negócio. Nela vou tentar procurar uma aba com a mesma descrição do item de menu que foi clicado. Se não existir, eu crio com o método add, se existir eu somente ativo. Isso evita a criação de abas duplicadas.

    ,onNodeClick: function( node )
    {
    	var titulo = node.text;
    	var novaAba = this.tabPanelCentral.items.find(function( aba ){ return aba.title === titulo; });
    
    	if(!novaAba)
    	{
    		novaAba = this.tabPanelCentral.add({
    			  title	: titulo
    			 ,html	: 'nova aba:' +  titulo
    		});
    	}
    
    	this.tabPanelCentral.activate(novaAba);
    }

E pronto! Temos aí links em um menu lateral abrindo novas abas no tabPanel central sem duplicar as abas. Não irei abordar como carregar conteúdo nas abas, mas no código fonte fiz algumas observações que podem guiá-lo nessa tarefa. Além disso temos exemplos mais completos no blog que podem também lhe ajudar, como por exemplo o Crud Avançado e Carregar códig Ext sob demanda

Forte abraço e até a próxima!

server-side.zip

Código Completo

Demo Online

Demo Online

LinkedInDeliciousPinterestTumblrEmailShare