sexta-feira, 20 de maio de 2011

Salvar tamanho e posição das colunas em um DataGrid

Hoje surgiu um problema aqui na @PontoSistemas, onde teríamos que salvar a posição e o tamanho da coluna de acordo com o que o cliente preferir, como cada pessoa organiza a tela de um jeito diferente. Tudo isso porque toda vez que o DataGrid é construído novamente, ele volta ao estado inicial.

A idéia:
Ao organizar ou alterar os tamanhos das colunas de um DataGrid/AdvancedDataGrid salve as posições e os tamanhos das colunas.

A solução:
Altere o tamanho e/ou a ordem das colunas, e recarregue a página. Elas irão voltar na mesma ordem e tamanho que você as deixou.


Clique com o botão direito em cima do DataGrid, depois em "view source" para visualizar o código fonte.
ou

SalvarColunas.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application viewSourceURL="srcview/index.html"
               xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:s="library://ns.adobe.com/flex/spark">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.controls.DataGrid;
            import mx.events.FlexEvent;
            import mx.utils.ObjectUtil;
            
            /* salvar ordem das colunas */
            public function reordenarColunas(event:Event, nomeSharedObj:String):void {
                var grid:* = event.currentTarget;
                
                if (grid is DataGrid||grid is AdvancedDataGrid) {
                    var colunas:ArrayCollection = null;
                    
                    //le informações salvas
                    var shared:SharedObjectHelper = new SharedObjectHelper(nomeSharedObj);
                    
                    if (shared.getObjects()) {
                        if (shared.getObjects().length>0) {
                            if (shared.getObjects()!=null) {
                                colunas = shared.getObjects();
                            }
                        }
                    }
                    
                    if (colunas==null) { //se nao tiver nada salvo, salva, e nao faz nada.
                        salvarOrdemColunas(event, nomeSharedObj);
                        return;
                    }
                    var colunasAtual:Array = grid.columns.slice(0, grid.columns.length); //pega as colunas atual
                    
                    if (colunasAtual.length!=colunas.length) { //se sao colunas diferentes salva as novas.
                        salvarOrdemColunas(event, nomeSharedObj);
                        return;
                    }
                    
                    var colunasNovo:Array = new Array();
                    var i:int = 0;
                    
                    while (colunas.length>0) { //enquanto tiver colunas a serem alteradas
                        if (colunasAtual[i]!=null) { //se ja foi alterado a coluna é setado como nula.
                            if (colunasAtual[i].dataField.toString()==colunas.getItemAt(0).datafield.toString()) { //verifica se a atual é igual a coluna a ordenada
                                colunasAtual[i].width = colunas.getItemAt(0).width; //seta o tamanho da coluna
                                colunasNovo.push(colunasAtual[i]); //adiciona a coluna na ultima possição (para deixar na ordem)
                                
                                //remove o que ja foi verificado
                                colunas.removeItemAt(0);
                                colunasAtual[i] = null;
                                
                                i = -1; //zera o contador para reavaliar todas as colunas
                            }
                        }
                        i++;
                    }
                    
                    grid.horizontalScrollPolicy = "on"; //atribui o Scroll horizontal por causa dos Widths setados na mao
                    grid.columns = colunasNovo; //seta as novas colunas no grid
                    grid.validateProperties(); //atualiza o grid para aparecer as novas colunas
                }
            }
            
            public function salvarOrdemColunas(event:Event, nomeSharedObj:String):void {
                var grid:* = event.currentTarget;
                
                if (grid is DataGrid||grid is AdvancedDataGrid) {
                    
                    var shared:SharedObjectHelper = new SharedObjectHelper(nomeSharedObj);
                    shared.clear();
                    
                    var obj:Object = null;
                    
                    for each (var i:Object in grid.columns) {
                        obj = new Object();
                        obj.datafield = i.dataField;
                        obj.width = i.width;
                        shared.addObject(obj);
                    }
                }
            }
        ]]>
    </fx:Script>

    <!--
        columnStretch = ao redimencionar as colunas.
        headerShift = ao trocar as colunas de posição.
    -->
    <mx:AdvancedDataGrid columnStretch="salvarOrdemColunas(event,'nomeDoObjetoSalvo')"
                         creationComplete="reordenarColunas(event,'nomeDoObjetoSalvo')"
                         headerShift="salvarOrdemColunas(event,'nomeDoObjetoSalvo')">
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="a"/>

            <mx:AdvancedDataGridColumn dataField="b"/>

            <mx:AdvancedDataGridColumn dataField="c"/>

            <mx:AdvancedDataGridColumn dataField="d"/>

            <mx:AdvancedDataGridColumn dataField="e"/>
        </mx:columns>
    </mx:AdvancedDataGrid>
</s:Application>

SharedObjectHelper.as
package {
    import flash.net.SharedObject;
    
    import mx.collections.ArrayCollection;
    
    public class SharedObjectHelper {
        private var _sharedObject:SharedObject;
        
        private var _dadosSharedObject:ArrayCollection;
        
        private var _nomeArquivoSharedObject:String;
        
        /**
         * Construtor
         */
        public function SharedObjectHelper(valor:String) {
            inicializaHelper(valor);
        }
        
        /**
         * Limpa objeto dentro do SharedObject
         */
        public function clear():void {
            _dadosSharedObject.removeAll();
            _sharedObject.flush();
        }
        
        /**
         * @private
         * Responsavel por recuperar a instancia do SharedObject baseado no
         * parametro.
         *
         */
        private function inicializaHelper(valor:String):void {
            _dadosSharedObject = new ArrayCollection();
            _nomeArquivoSharedObject = valor;
            _sharedObject = SharedObject.getLocal(_nomeArquivoSharedObject);
            
            if (getObjects()) {
                _dadosSharedObject = getObjects();
            }
        }
        
        /**
         * Retorna todos um array de dados que está armazendo no SharedObject
         * @return ArrayCollection
         */
        public function getObjects():ArrayCollection {
            return _sharedObject.data[_nomeArquivoSharedObject];
        }
        
        /**
         * Adiciona um dado ao array de dados.
         * @param Object
         */
        public function addObject(o:Object):void {
            _dadosSharedObject.addItem(o);
            updateSharedObjects();
        }
        
        /**
         * @private
         * Vincula o array de dados a um SharedObject.
         */
        private function updateSharedObjects():void {
            _sharedObject.data[_nomeArquivoSharedObject] = _dadosSharedObject;
            _sharedObject.flush();
        }
    }
}

Da maneira que foi implementado, as definições da posição e do tamanho das colunas são salvas na memória do FlashPlayer (como se fosse os cookies das páginas web), ao limpar esse "cookie" as configurações voltam ao estado original.

Por hoje é isso. Em breve novas dicas.

Comentem!!!

Um comentário: