quarta-feira, 8 de maio de 2013

Copiar, Colar, Selecionar tudo em um DataGrid ou AdvancedDataGrid

Olá pessoal, após muito tempo sumido, por falta de tempo. Voltei para mais um post.
Hoje vou mostrar algo que tive que implementar em um DataGrid ou AdvancedDataGrid.

Necessidade:
Poder copiar os registros selecionados para o clipboard, também poder adicionar registros vindos de uma tabela  no excel, através do CTRL+C e CTRL+V.

Solução:
Implementar as funções de COPY e PASTE em um datagrid, podendo copiar os itens selecionados, e também adicionar novos itens (desde que estejam com a mesma quantidade de colunas).


Na prática:
Error: Embedded data could not be displayed.
Pode utilizar os atalhos do teclado também.
Você pode colar o texto abaixo em cima do grid:
abc1 cdf2 ghi3 jkl4
mno5 pqr6 stu7 vxz8



Código:
<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="application1_creationCompleteHandler(event)"
               minHeight="600"
               minWidth="955"
               xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:ui="flash.ui.*">
    <fx:Script>
        <![CDATA[
            import flash.desktop.Clipboard;
            import flash.desktop.ClipboardFormats;
            import flash.events.Event;
            
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;
            
            [Bindable]
            private var array:ArrayCollection = null;
            
            private function onEvent(evt:Event):void {
                switch (evt.type) {
                    case "paste":  {
                        var clipboadStr:String = Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT) as String;
                        
                        var arrayItem:Array = clipboadStr.split("\n");
                        
                        for each (var item:String in arrayItem) {
                            if (item.length>0) {
                                var arrayValorItem:Array = item.split("\t");
                                var obj:Object = new Object();
                                var cont:int = 0;
                                
                                for each (var col1:Object in evt.currentTarget.columns) {
                                    obj[col1.dataField] = arrayValorItem[cont];
                                    cont++;
                                }
                                evt.currentTarget.dataProvider.addItem(obj);
                            }
                        }
                        break;
                    }
                    case "cut":  {
                        break;
                    }
                    case "copy":  {
                        if (evt.currentTarget.selectedItems.length>0) {
                            var str:String = "";
                            
                            for each (var itemObj:Object in evt.currentTarget.selectedItems) {
                                for each (var col:Object in evt.currentTarget.columns) {
                                    str += itemObj[col.dataField]+"\t";
                                }
                                str += "\n";
                            }
                            System.setClipboard(str);
                        }
                        break;
                    }
                    case "selectAll":  {
                        var indexArr:Array = [];
                        
                        for (var i:uint = 0; i<evt.currentTarget.dataProvider.length; i++) {
                            indexArr.push(i);
                        }
                        evt.currentTarget.selectedIndices = indexArr;
                        break;
                    }
                    default:  {
                        break;
                    }
                }
            }
            
            private function menuSelect(evt:ContextMenuEvent):void {
                evt.currentTarget.contextMenu.hideBuiltInItems();
            }
            
            protected function application1_creationCompleteHandler(event:FlexEvent):void {
                array = new ArrayCollection();
                
                var obj:Object = new Object();
                obj.coluna1 = "asd1";
                obj.coluna2 = "asd2";
                obj.coluna3 = "asd3";
                obj.coluna4 = "asd4";
                array.addItem(obj);
                
                obj = new Object();
                obj.coluna1 = "qwe1";
                obj.coluna2 = "qwe2";
                obj.coluna3 = "qwe3";
                obj.coluna4 = "qwe4";
                array.addItem(obj);
                
                obj = new Object();
                obj.coluna1 = "zxc1";
                obj.coluna2 = "zxc2";
                obj.coluna3 = "zxc3";
                obj.coluna4 = "zxc4";
                array.addItem(obj);
            
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <mx:VBox>
        <mx:DataGrid id="dgMain"
                     width="100%"
                     height="100%"
                     allowMultipleSelection="true"
                     copy="onEvent(event)"
                     cut="onEvent(event)"
                     dataProvider="{array}"
                     paste="onEvent(event)"
                     selectAll="onEvent(event)">
            <mx:contextMenu>
                <!-- contextMenu: Habilita as opções com o botão direito do mouse -->
                <ui:ContextMenu clipboardMenu="true"
                                menuSelect="menuSelect(event);">
                    <ui:clipboardItems>
                        <ui:ContextMenuClipboardItems copy="true"
                                                      cut="false"
                                                      paste="true"
                                                      selectAll="true"/>
                    </ui:clipboardItems>
                </ui:ContextMenu>
            </mx:contextMenu>

            <mx:columns>
                <mx:DataGridColumn dataField="coluna1"
                                   headerText="Coluna 1"/>

                <mx:DataGridColumn dataField="coluna2"
                                   headerText="Coluna 2"/>

                <mx:DataGridColumn dataField="coluna3"
                                   headerText="Coluna 3"/>

                <mx:DataGridColumn dataField="coluna4"
                                   headerText="Coluna 4"/>
            </mx:columns>
        </mx:DataGrid>
    </mx:VBox>
</s:Application>

Bom pessoal, por hoje é isso, espero que tenham gostado.

Comentem, divulguem, curtam.

5 comentários:

  1. Poderia me ajudar com o seguinte erro: Child elements are not allowed here. ?

    ResponderExcluir
  2. Olá Fábio. Depende do que você está fazendo, onde ocorreu, como ocorreu, qual a versão do sdk que está utilizando... Mas traduzindo o erro, você está tentando colocar algum elemento em um componente que não aceita. Se puder colocar seu código em em algum desses sites de colocar codigo seria mais fácil de te ajudar.

    ResponderExcluir
    Respostas
    1. Estou utilizando SDK 4.6, literalmente copiei o código disponibilizado aqui e busquei executar

      Excluir
    2. A ideia seria ver este código funcionando para migrar para fazer o downgrade para o sdk 3.5, pois trabalho em uma instituição onde toda camada front end é feita com flex e infelizmente os melhores sites de flex "morreram..." quase não acreditei ao encontrar o seu, sinceramente ajudou e muito o que pude pegar de conteudo aqui :)

      Excluir
    3. Olá, o código foi feito no SDK 4.1. Creio que funcione no 3.5 também. Neste momento não tenho como testar o código, por isso acredito que no 4.1 vá funcionar.

      Excluir