Sie sind auf Seite 1von 40

2007

ZDMS_CONTROLE_REVISAO

Workshop WebDynpro Modulo I - Dicas

Manoel Messner

CPMBraxis
22/10/2007

Data:21.10.2007

Verso:00

Pg.: 2/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

ndice
SUGESTES DE BEST PRACTICES WEBDYNPRO ................................... 4
Utilizar o Component Controller para variveis e mtodos globais, ou seja, acessveis a todas as Views do DC. ......................................................................................................................................... 4 Criar um Custom Controller para acesso ao modelo (RFCs) e neste criamos os mtodos para executar cada uma das RFCs do DC. ..................................................................................................... 4 Ns de RFCs: ......................................................................................................................................... 4

DEFININDO APPLICATION PROPERTIES ................................................... 6


Requisito .................................................................................................................................................. 6 Uso ........................................................................................................................................................... 6 Procedimento ........................................................................................................................................... 6 Uso ........................................................................................................................................................... 7 Requisito .................................................................................................................................................. 7 Procedimento ........................................................................................................................................... 9

COMO UM DC CHAMAR OUTRO DC ............................................................ 10


No DC chamado (destino): .................................................................................................................... 10 No DC chamador (origem): ................................................................................................................... 14

EXECUO DE RFCS NO CUSTOM CONTROLLER ............................... 19


Cria o model com todas as RFCs necessrias: ..................................................................................... 19 Cria o Custom Controller: .................................................................................................................. 19 Relaciona o Model ao Custom Controller: ..................................................................................... 20 Cria o(s) mtodo(s) de execuo da RFC no Custom Controller: ...................................................... 20 Implementa o cdigo de execuo das RFCs no Custom Controller: ............................................... 22 Em um Action da View por exemplo, executa o mtodo do Custom Controller: ........................... 22

FILTRAR VALORES EM TABELAS ............................................................... 23


Insere o UI Element Table na View. .................................................................................................. 23 Resultado: .............................................................................................................................................. 27

MATCH CODE ................................................................................................. 28


No Contexto da View crie um n com o atributo para o InputField: ..................................................... 28 Insira na View um InputField e na propriedade value atribua o contexto acima. .............................. 28 Na View crie um mtodo para retornar um SimpleValueSet: ............................................................ 28 Na View crie um mtodo para montar o Match Code do InputField: .................................................... 29 No mtodo wdDoInit da View execute o mtodo acima: ...................................................................... 29

FUNCTIONALITY OF THE NW04S-ADAPTED TABLESORTER CLASS ...... 29


How to apply the TableSorter class ....................................................................................................... 30

CPMBraxis | Sugestes de Best Practices WebDynpro

Data:21.10.2007

Verso:00

Pg.: 3/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

ORDENAO EM TABELAS (TABLESORTER) ........................................... 31


Procedimento: ........................................................................................................................................ 32

UPLOAD / DOWNLOAD DE ARQUIVO .......................................................... 33 CRIA O WINDOW E A EMBED VIEW: ..................................................... 35

CPMBraxis | Sugestes de Best Practices WebDynpro

Data:21.10.2007

Verso:00

Pg.: 4/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Sugestes de Best Practices WebDynpro


Utilizar o Component Controller para variveis e mtodos globais, ou seja, acessveis a todas as Views do DC.
Exemplo: Pode-se criar no Component Controller um mtodo para exibir as mensagens do Message Pool, evitando assim a duplicidade de cdigo, visto que todas as Views podem execut-lo.

Criar um Custom Controller para acesso ao modelo (RFCs) e neste criamos os mtodos para executar cada uma das RFCs do DC.
No Custom Controller podemos iniciar o contexto de cada RFC no wdDoInit:
public void wdDoInit(){ //@@begin wdDoInit() // RFC de pesquisa do Codigo Parceiro para o usuario Zdpnmm028_Input input028 = new Zdpnmm028_Input(); wdContext.nodeZdpnmm028_Input().bind(input028);

Nos mtodos de execuo de cada RFC podemos fazer (utilizar o modelObject):


public void executeZdpnmm028_Input( java.lang.String usuario ) { //@@begin executeZdpnmm028_Input() try { wdContext.currentZdpnmm028_InputElement().modelObject().setI_User(); wdContext.currentZdpnmm028_InputElement().modelObject().execute(); //-----------<< Retorno >>----------wdContext.nodeZdpnmm028_Output().bind( wdContext.currentZdpnmm028_InputElement().modelObject().getOutput()); // Mensagem de Erro if (wdContext.nodeT_Return028().size() > 0) { for (int i=0;i<wdContext.nodeT_Return028().size();i++) ... } } catch (Exception e) { wdComponentAPI.getMessageManager().reportException(e.getMessage(),false); }

Ns de RFCs:
No n de input da RFC selecionar apenas os parmetros/tabelas de entrada para o processamento da RFC e no n de output selecionar o retorno: CPMBraxis | Sugestes de Best Practices WebDynpro 4

Data:21.10.2007

Verso:00

Pg.: 5/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Para possibilitar a Internacionalizao, no colocar mensagens e/ou ttulos de tela ou match code no cdigo do componente (hard code). As mensagens e ttulos de Match Code ou de telas devem ser incluidas no Message Pool do componente:

Obs: Para recuperar do Message Pool:


String titulo = wdComponentAPI.getTextAccessor().getText("titulo");

CPMBraxis | Sugestes de Best Practices WebDynpro

Data:21.10.2007

Verso:00

Pg.: 6/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Definindo Application Properties


Requisito
DC do Tipo Enterprise Application (EAR)

Uso
A API application configuration habilita a definio e uso de sets de propriedades para a aplicao que fica disponvel para os components em tempo de execuo.

Procedimento
Definindo o global application properties:
..

1. Inclua um arquivo Java padro de propriedades chamado sap.application.global.properties no diretrio META-INF da aplicao EAR (neste diretrio j existe o application.xml e o application-j2ee-engine.xml ).

CPMBraxis | Definindo Application Properties

Data:21.10.2007

Verso:00

Pg.: 7/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Conectando o Configuration Manager

Uso
Para abrir uma configurao permitindo a leitura e modificao, deve-se primeiro conectar o Configuration Manager, com o mdulo que gerencia o configuration tree.

Requisito
Para conectar o Configuration Manager, voc deve adicionar a referncia ao Configuration Service no SAP-specific deployment descriptor de sua aplicao que o, application-j2ee-engine.xml.

CPMBraxis | Definindo Application Properties

Data:21.10.2007

Verso:00

Pg.: 8/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

O application-j2ee-engine.xml fico da seguinte forma: <reference reference-type="hard"> <reference-target provider-name="sap.com" target-type="service">configuration</referencetarget> </reference> <provider-name>sap.com</provider-name>

CPMBraxis | Definindo Application Properties

Data:21.10.2007

Verso:00

Pg.: 9/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Procedimento
1. Para acessar o Properties nos components da aplicao utilize::

Context ctx = new InitialContext(); ApplicationConfigHandlerFactory cfgHandler = (ApplicationConfigHandlerFactory)ctx.lookup("ApplicationConfiguration"); java.util.Properties appProps = cfgHandler.getApplicationProperties(); if (appProps==null) { //some reaction if no application properties are available. } else { //extract properties String dir = appProps.getProperty(DIR); } O Properties instance que voc obtem uma cpia do properties da aplicao. Portanto, alguma modificao que voc fizer no afetar outros mtodos que acessem o properties.

CPMBraxis | Definindo Application Properties

Data:21.10.2007

Verso:00

Pg.: 10/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Como um DC chamar outro DC


No DC chamado (destino):
Criar no contexto do Interface Controller um n que vai receber os parmetros do DC chamador, com a propriedade cardinality definida como 1..1 (criao automtica):

Fazer o mapping deste n para o Component Controller e para a View que receber os parmetros:

CPMBraxis | Como um DC chamar outro DC

10

Data:21.10.2007

Verso:00

Pg.: 11/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

CPMBraxis | Como um DC chamar outro DC

11

Data:21.10.2007

Verso:00

Pg.: 12/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

No Interface Views da Window Principal, criar um Outbound Plug chamado Retornar:

Na View principal, criar um action chamado Voltar, incluir um boto (ou LinkToAction) com texto Voltar e ligar este action com este boto. Adicionar no Required Controllers da View principal a Interface View da window principal:

Na Implementation da view, no action Voltar, colocar o seguinte cdigo: wdThis.wdGetZdplpl016WindowInterfaceViewController().wdFirePlugRetornar();

Criar uma Public Part no DC (context menu New Public Part). Inserir o componente na Public Part (context menu Add to Public Part). Realizar as seguintes aes:

CPMBraxis | Como um DC chamar outro DC

12

Data:21.10.2007

Verso:00

Pg.: 13/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

o o o o

Rebuild do DC, verificando a existncia de erros. Build do DC (context menu Development Component -> Build). Deploy do DC (context menu Development Component -> Deploy). Check-in e Ativao da atividade (Perspective DTR).

CPMBraxis | Como um DC chamar outro DC

13

Data:21.10.2007

Verso:00

Pg.: 14/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

No DC chamador (origem):
No context menu de DC MetaData / DC Definition / Used DCs selecionar ADD Used DC e escolher o Public Part do DC que ser chamado:

No Diagram View, selecionar Embed an existing component e clicar na rea Used Web Dynpro Components para escolher a Interface Controller do DC que ser chamado:

Colocar o nome (exemplo: nome da especificao + IC: Zdplpl035IC). Selecionar o componente que ser chamado clicando em Browse.

CPMBraxis | Como um DC chamar outro DC

14

Data:21.10.2007

Verso:00

Pg.: 15/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Obs.: O campo Lifecycle controla se o componente ser criado automaticamente pelo WebDynpro (createOnDemand) ou ser criado manualmente no cdigo da view (manual). Clicar em Finish. Fazer o mapping do n de parmetros da Interface Controller do DC que ser chamado com o contexto da View que ir cham-lo, habilitando assim a passagem dos parmetros.

Criar um novo Embed View selecionando a opo Embed Interface View of a Component instance:

CPMBraxis | Como um DC chamar outro DC

15

Data:21.10.2007

Verso:00

Pg.: 16/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Selecionar a Interface View do DC que ser chamado:

CPMBraxis | Como um DC chamar outro DC

16

Data:21.10.2007

Verso:00

Pg.: 17/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Nas Views dos dois DCs, criar os respectivos Outbound Plug e Inbound Plug:

Ligar os plugs das Views, para habilitar a navegao entre os DCs:

Na View, identificar o lugar aonde o outro DC ser chamado, e utilizar o seguinte cdigo:

//popular o n de parmetro

wdContext.currentParamIn_Zdplpl035Element().setRevisao(wdContext().getRevision() );

CPMBraxis | Como um DC chamar outro DC

17

Data:21.10.2007

Verso:00

Pg.: 18/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

wdContext.currentParamIn_Zdplpl035Element().setStatus(wdContext().getStatus()); wdContext.currentParamIn_Zdplpl035Element().setTipoDocumento(wdContext().getTip _doc()); wdContext.currentParamIn_Zdplpl035Element().setTipoRevisao(wdContext().getTip_re vision());


//Chamar o DC Zdplpl035

wdThis.wdFirePlugZdplpl035Out();

Para que o mtodo wdDoInit do Used DC seja executado toda vez que for chamado, este deve ser criado manualmente:

Na View que chamar o outro DC, habilitar o Component Usage do DC no Required Controllers:

Na View, identificar o lugar aonde o outro DC ser chamado, e utilizar o seguinte cdigo:

//@@begin javadoc:onActionZdplmm005(ServerEvent) /** Executa o DC: Zdplmm005. */ //@@end public void onActionZdplmm005(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent) { //@@begin onActionZdplmm005(ServerEvent) // Cria manualmente o Used DC

CPMBraxis | Como um DC chamar outro DC

18

Data:21.10.2007

Verso:00

Pg.: 19/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

wdThis.wdGetZdplmm005ICComponentUsage().createComponent(); // Seta os parametros wdContext.currentParamNaveg005Element().setSy_tcode(...); wdContext.currentParamNaveg005Element().setGroupCode(...); // Executa o DC Zdplmm005 wdThis.wdFirePlugToZdplmm005Out(); //@@end } //@@begin javadoc:onPlugFromZdplmm005In(ServerEvent) /** Retorno do DC: Zdplmm005. */ //@@end public void onPlugFromZdplmm005In(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent ) { //@@begin onPlugFromZdplmm005In(ServerEvent) if (wdThis.wdGetZdplmm005ICComponentUsage().hasActiveComponent()) wdThis.wdGetZdplmm005ICComponentUsage().deleteComponent(); //@@end }

Execuo de RFCs no Custom Controller


PDF de referncia: Creating a Web Dynpro Application Accessing ABAP Functions.pdf

Cria o model com todas as RFCs necessrias:

Cria o Custom Controller:

CPMBraxis | Execuo de RFCs no Custom Controller

19

Data:21.10.2007

Verso:00

Pg.: 20/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Relaciona o Model ao Custom Controller:

Cria o(s) mtodo(s) de execuo da RFC no Custom Controller:

CPMBraxis | Execuo de RFCs no Custom Controller

20

Data:21.10.2007

Verso:00

Pg.: 21/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

CPMBraxis | Execuo de RFCs no Custom Controller

21

Data:21.10.2007

Verso:00

Pg.: 22/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Inicializa os ns do contexto do Custom Controller:


public void wdDoInit() { // Cria um novo elemento no n "Zdpnmm116_Input" Zdpnmm110_Input input110 = new Zdpnmm110_Input(); wdContext.nodeZdpnmm110_Input().bind(input110); // Cria um novo elemento no n "Zdpnmm116_Input" Zdpnmm116_Input input = new Zdpnmm116_Input(); wdContext.nodeZdpnmm116_Input().bind(input); // Seta o "Embraer Code" e "Part Number" input.setI_Embcode( wdContext.currentZdpnmm116_InputElement().getI_Embcode()); input.setI_Partnum( wdContext.currentZdpnmm116_InputElement().getI_Partnum()); }

Implementa o cdigo de execuo das RFCs no Custom Controller:


public void executeZdpnmm110_Input() { IWDMessageManager messageMgr = wdComponentAPI.getMessageManager(); Zsdp_Matr_Itrelev itRelev = new Zsdp_Matr_Itrelev(); WDCopyService.copyCorresponding(wdContext.currentT_ItensElement(),itRelev); try { wdContext.currentZdpnmm110_InputElement().modelObject().setI_Item(itRelev); wdContext.currentZdpnmm110_InputElement().modelObject().execute(); } catch (Exception e) { e.printStackTrace(); messageMgr.reportException(e.getMessage(), false); } wdContext.nodeZdpnmm110_Output().bind( wdContext.currentZdpnmm110_InputElement().modelObject().getOutput()); }

Em um Action da View por exemplo, executa o mtodo do Custom Controller:


public void onActionPesquisar(com.sap..... wdEvent) { wdThis.wdGetZdplmm001CustController().executeZdpnmm116_Input(); IWDMessageManager message = wdThis.wdGetAPI().getComponent().getMessageManager(); if (wdContext.nodeZdpnmm116_Output().nodeT_Return().size() > 0) { for (int i=0; I < wdContext.nodeT_Return().size(); i++) { message.reportException( wdContext.nodeZdpnmm116_Output().nodeT_Return(). getT_ReturnElementAt(i).getMessage(),false);

CPMBraxis | Execuo de RFCs no Custom Controller

22

Data:21.10.2007

Verso:00

Pg.: 23/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

} } else { wdThis.wdFirePlugToZdplmm001_0110(); } }

Filtrar valores em Tabelas


Insere o UI Element Table na View.
1 Cria o n no contexto da View para o Create Binding da Table, e no mapeia este com o output de retorno da RFC no Custom Controller (n T_RME):

2 Cria um n com os campos que tero filtro na Table (n T_RME_Filter):

CPMBraxis | Filtrar valores em Tabelas

23

Data:21.10.2007

Verso:00

Pg.: 24/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

CPMBraxis | Filtrar valores em Tabelas

24

Data:21.10.2007

Verso:00

Pg.: 25/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

3 Bind os atributos do n de Filtro do contexto com as respectivas colunas na Table:

4 Cria um Action que ir fazer o filtro na Table, obedecendo os valores infomados:

5 Inicializa o contexto da View ligado (bind) na Table, com os valores do n da RFC no Custom Controller (neste caso o n T_Programarme):
public void wdDoInit() { //@@begin wdDoInit() IT_ProgramarmeNode rme = wdThis.wdGetZdplmm016CustController().wdGetContext().nodeT_Programarme(); for (int i=0; i<rme.size(); i++) { IT_RMEElement rmeElement = wdContext.nodeT_RME().createT_RMEElement(); WDCopyService.copyCorresponding(rme.getT_ProgramarmeElementAt(i), rmeElement); rmeList.add(rmeElement); } wdContext.nodeT_RME().bind(rmeList); //@@end } //@@begin others private List rmeList = new ArrayList(); // Collecion para fazer o Bind na Table

CPMBraxis | Filtrar valores em Tabelas

25

Data:21.10.2007

Verso:00

Pg.: 26/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

//@@end

CPMBraxis | Filtrar valores em Tabelas

26

Data:21.10.2007

Verso:00

Pg.: 27/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

7 Codifica o Action que ir fazer o filtro na Table:


//@@begin javadoc:onActionRmeFilter(ServerEvent) /** Filtro da Classificacao RME. */ //@@end public void onActionRmeFilter(com.sap.tc... wdEvent) { //@@begin onActionRmeFilter(ServerEvent) // Inicializa o contexto da Table wdContext.nodeT_RME().invalidate(); // Valores de filtro informados pelo Usurio String cap = (wdFilterElement.getNum_Cap_Rme() == null ? "" : wdContext.currentT_RME_FilterElement().getNum_Cap_Rme().trim()); String sub = (wdFilterElement.getNum_Sucp_Rme() == null ? "" : wdContext.currentT_RME_FilterElement().getNum_Sucp_Rme().trim()); String sca = (wdFilterElement.getNum_Scao_Rme() == null ? "" : wdContext.currentT_RME_FilterElement().getNum_Scao_Rme().trim()); String dsc = (wdFilterElement.getDescricaoen() == null ? "" : wdContext.currentT_RME_FilterElement().getDescricaoen().trim()); if (cap.equals("") && sub.equals("") && sca.equals("") && dsc.equals("")) { // Usurio no informou valores (Refaz a Table com todos os valores) wdContext.nodeT_RME().bind(rmeList); } else { // Usurio informou valores (Refaz a Table com os valores vlidos) IT_RMEElement rmeElement = null; for (int i=0; i < rmeList.size(); i++) { rmeElement = (IT_RMEElement)rmeList.get(i); int pos = 0; if (!cap.trim().equals("")) pos = rmeElement.getNum_Cap_Rme().indexOf(cap); if (pos >= 0 && !sub.trim().equals("")) pos = rmeElement.getNum_Sucp_Rme().indexOf(sub); if (pos >= 0 && !sca.trim().equals("")) pos = rmeElement.getNum_Scao_Rme().indexOf(sca); if (pos >= 0 && !dsc.trim().equals("")) pos = rmeElement.getDescricaoen().indexOf(dsc); if (pos >= 0) wdContext.nodeT_RME().addElement(rmeElement); } } //@@end }

Resultado:

CPMBraxis | Filtrar valores em Tabelas

27

Data:21.10.2007

Verso:00

Pg.: 28/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Match Code
No Contexto da View crie um n com o atributo para o InputField:
Ex: + Campos - UnidadeProjeto

Insira na View um InputField e na propriedade value atribua o contexto acima. Na View crie um mtodo para retornar um SimpleValueSet:
//@@begin javadoc:simpleValueSet() /** * Cria Ajuda de Pesquisa (Match Code). * @param atributo Atributo do contexto ligado a um InputField * @param titulo Titulo do Match Code * @param node Nome do N dos atributos * @return IModifiableSimpleValueSet ValueSet do Match Code */ //@@end public com.sap.typeservices.IModifiableSimpleValueSet simpleValueSet(java.lang.String atributo, java.lang.String titulo) { //@@begin simpleValueSet() ICamposNode camposNode = wdContext.nodeCampos(); IWDAttributeInfo attributeInfo = camposNode.getNodeInfo().getAttribute(atributo); ISimpleTypeModifiable attributeType = attributeInfo.getModifiableSimpleType(); attributeType.setFieldLabel(titulo); IModifiableSimpleValueSet valueSet = attributeType.getSVServices().getModifiableSimpleValueSet(); valueSet.clear(); return valueSet; //@@end }

CPMBraxis | Match Code

28

Data:21.10.2007

Verso:00

Pg.: 29/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Na View crie um mtodo para montar o Match Code do InputField:


//@@begin javadoc:montaUnProjetoMC() /** Monta Match Code do campo UNIDADE PROJETO. */ //@@end public void montaUnidadeProjetoMC( ) { //@@begin montaUnProjetoMC() // Executa RFC que retornar os dados para o Match Code wdThis.wdGetZdplmm016CustController().executeZdpnmm061_Input(); IModifiableSimpleValueSet valueSet = simpleValueSet("UnidadeProjeto", "Unidade Projeto"); for (int i=0; i < wdContext.nodeT_UnProject().size(); i++) valueSet.put(wdContext.nodeT_UnProject().getT_UnProjectElementAt(i).getMsehi(), wdContext.nodeT_UnProject().getT_UnProjectElementAt(i).getMsehl()); //@@end }

No mtodo wdDoInit da View execute o mtodo acima:


wdThis.montaUnidadeProjeto(); // Monta o Match Code do campo Unidade Projeto

Functionality of the NW04s-adapted TableSorter class


Adapted to SAP NetWeaver 04s the enhanced TableSorter class provides the following functionality:

Adapted Table UI element event binding:

In NW04 the TableSorter implements the functionality to display the sort icons in the column headers and to store the sort state for each column. In NW04s this functionality is generically provided by the Table-UIElement itself. The new TableSorter is now based on the new onSort-event of the Table UI element instead of the onAction-event of the TableColumn UI element. The sort a and sort order icons are automatically displayed for sortable tables.

Restricted sorting to a subset of columns: In order to restrict sorting to a subset of


table columns in NW04, the onAction-event of the corresponding TableColumn UI elements was bound to the action Sort. In NW04s the interaction model between the table and the TableSorter class is completely based on the table's onSort-event and the event parameters 'selected column' and 'sort direction'. Within an additional constructor method TableSorter(IWDTable table, IWDAction sortAction, Map comparators, String[] sortableColumns) a subset of sortable table columns can be specified. The TableSorter class sorts all columns by default.

CPMBraxis | Functionality of the NW04s-adapted TableSorter class

29

Data:21.10.2007

Verso:00

Pg.: 30/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Definition of custom comparators:

The new TableSorter uses a java.util.Map to define alternative comparators instead of an Array because this solution is more flexible for further enhancements. As key for the map, the column ID is used.

Support of grouped columns: The new TableSorter can deal with GroupedColumns, which
were added in NW04s.

Language specific sorting : Strings are compared with the


language specific sorting.

java.text.Collator class to allow

Support of non-singleton child node attributes:

The previous TableSorter could only sort those olumns which were directly bound to an attribute of the table's root context node. Attributes of non-singleton child nodes of this node, which were displayed in the same table, were not sortable. The NW04sTableSorter can now sort these columns too.

How to apply the TableSorter class


Adid the TableSorter class to the new package folder src/packages/com/sap/tc/webdynpro/tests/utils

1.

Declare a new context attribute TableSorter of type com.sap.tc.webdynpro.tests.utils.TableSorter within the view controller context. Declare a new action with name Sort (or SortCustomers in this example) and with the associated action event handler onActionSort() to the view controller. Implement the following source code in the wdDoModifyView()-hook-method of the view controller:
public static void wdDoModifyView() { //@@begin wdDoModifyView if (firstTime) {

2.

3.

CPMBraxis | Functionality of the NW04s-adapted TableSorter class

30

Data:21.10.2007

Verso:00

Pg.: 31/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

IWDTable table = (IWDTable) view.getElement("CustomerTable"); wdContext.currentContextElement().setCustomerTableSorter( new TableSorter(table, wdThis.wdGetSortCustomersAction(), null, new String[] { "CustomerTable_Name" })); } //@@end }

4.

Organize imports within the view controller class so that import com.sap.tc.webdynpro.tests.utils.TableSorter; is added. Implement the following source code in the action event handler onActionSort() (or onActionSortCustomers in this example).
//@@begin javadoc:onActionSortCustomers(ServerEvent) /** Declared validating event handler. */ //@@end public void onActionSortCustomers(...) { //@@begin onActionSortCustomers(ServerEvent) wdContext.currentContextElement().getCustomerTableSorter().sort( wdEvent, wdContext.nodeCustomers()); //@@end }

5.

Ordenao em Tabelas (TableSorter)


Para ordenar a tabela basta clicar na coluna desejada (clicando pela segunda vez na mesma coluna inverte a ordenao crescente, decrescente):

Ordem Crescente

CPMBraxis | Ordenao em Tabelas (TableSorter)

31

Data:21.10.2007

Verso:00

Pg.: 32/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Ordem Decrescente

Procedimento:
1 - Copie a classe TableSorter.java para o "src/packages" na estrutura de diretrio: com.sap.tc.webdynpro.tests.utils
Obs: Crie a estrutura de diretrios acima na aba Navigator. Em cima do src/packages, selecione no context menu New / Other / Simple / Folder.

2 - No contexto da View crie um atributo chamado TableSorter:

Na aba Properties altere a propriedade: CPMBraxis | Ordenao em Tabelas (TableSorter) 32

Data:21.10.2007

Verso:00

Pg.: 33/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

type: com.sap.tc.webdynpro.tests.utils.TableSorter 3 - Crie um Action que ir ordenar as colunas da Table:


//@@begin javadoc:onActionSort(ServerEvent) /** "Table Sorter" da tabela de Fornecedores. */ //@@end public void onActionSort(com.sap.tc.webdynpro wdEvent ) { //@@begin onActionSort(ServerEvent) wdContext.currentContextElement().getTableSorter().sort(wdEvent, wdContext.nodeT_Forpar()); //@@end }

4 - No mtodo wdDoModifyView faa:


if (firstTime) { // Recupera o UI Element Table da View. IWDTable table = (IWDTable)view.getElement("tblFornecedor"); // Cria o "Table Sorter" e armazena no Contexto da View. wdContext.currentContextElement().setTableSorter( new TableSorter(table, wdThis.wdGetSortAction(), null)); }

Upload / Download de arquivo


//@@begin javadoc:executaRfcUpload() /** * RFC que executa o Upload no SAP R/3. * @param conteudo Array de Bytes do arquivo * @param filename Nome do Arquivo */ //@@end public boolean executaRfcUpload(byte[] conteudo, java.lang.String filename) { //@@begin executaRfcUpload() boolean rfc_ok = true; try { //--- Upload para o servidor WEB (NT) // Caso o usurio queira visualizar o arquivo antes de ser anexado no R3 if (conteudo.length > 0) { File file = new File("D:/usr/sap/download/" + filename); FileOutputStream out = new FileOutputStream(file); out.write(conteudo); out.flush(); out.close(); } else { rfc_ok = false; wdComponentAPI.getMessageManager().reportWarning("Arquivo Vazio!"); } //--- Upload para o servidor SAP R/3 (Unix) if (rfc_ok) { Zdpnmm141_Input inputUpload = new Zdpnmm141_Input(); wdContext.nodeZdpnmm141_Input().bind(inputUpload); Rcgrepfile repFile; ByteArrayInputStream byteArray = new ByteArrayInputStream(conteudo); byte[] buf = new byte[2550]; int nbytes = 0; while ((nbytes = byteArray.read(buf)) != -1) {

CPMBraxis | Upload / Download de arquivo

33

Data:21.10.2007

Verso:00

Pg.: 34/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

byte[] bufx = new byte[nbytes]; System.arraycopy(buf, 0, bufx, 0, nbytes); repFile = new Rcgrepfile(); repFile.setOrblk(bufx); wdContext.currentZdpnmm141_InputElement().modelObject().addT_Data(repFile); } byteArray.close(); wdContext.currentZdpnmm141_InputElement().modelObject().setI_Process("U"); wdContext.currentZdpnmm141_InputElement().modelObject().setI_File( "/usr/sap/tmp/" + filename); wdContext.currentZdpnmm141_InputElement().modelObject().setI_Leng( conteudo.length); wdContext.currentZdpnmm141_InputElement().modelObject().execute(); wdContext.nodeZdpnmm141_Output().bind( wdContext.currentZdpnmm141_InputElement().modelObject().getOutput()); if (wdContext.nodeT_Return().size() > 0) { rfc_ok = false; // EXIBE MSG ERRO } // Mensagem de Erro

} } catch (Exception e) { rfc_ok = false; wdComponentAPI.getMessageManager().reportException(e.getMessage(), false); } return rfc_ok; //@@end }

No contexto da view deve-se criar um n chamado File com dois atributos: - Binary do tipo binary - Filename do tipo String Inserimos um UI Element FileUpload na view e setamos as seguintes propriedades: - data = File.Binary - fileName = File.Filename No mtodo wdDoInit inicializamos o contexto File:
IPrivateZdplmm016_0110View.IFileElement fileElement = wdContext.createFileElement(); wdContext.nodeFile().bind(fileElement); IWDAttributeInfo attInfo = wdContext.nodeFile().getNodeInfo().getAttribute("Binary"); ISimpleTypeModifiable type = attInfo.getModifiableSimpleType(); IWDModifiableBinaryType binaryType = (IWDModifiableBinaryType) type;

No action de confirmao do Upload:


//@@begin javadoc:onActionConfirmaUpload(ServerEvent) /** Confirma Upload de Arquivo MSDS. */ //@@end public void onActionConfirmaUpload(com.sap.tc.webdynpro.progmodel.api.IWDCustomEvent wdEvent) { //@@begin onActionConfirmaUpload(ServerEvent) //--- RFC que faz o upload do arquivo para o Servidor SAP (Unix) boolean upl = wdThis.wdGetZdplmm016CustController().executaRfcUpload( wdContext.currentFileElement().getBinary(), wdContext.currentFileElement().getFilename());

CPMBraxis | Upload / Download de arquivo

34

Data:21.10.2007

Verso:00

Pg.: 35/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

if (upl) . //@@end }

Cria o Window e a Embed View:

Na View principal, cria no contexto um n e um atributo do tipo (IWDWindow Java Native Type) para guardar a instncia do window e poder fech-lo posteriormente:

CPMBraxis | Cria o Window e a Embed View:

35

Data:21.10.2007

Verso:00

Pg.: 36/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Na View Principal:

- Inicializa o contexto no mtodo wdDoModifyView:


public static void wdDoModifyView(...) { //@@begin wdDoModifyView if (firstTime) { IPopupNode popupNode = wdContext.nodePopup(); IPrivateZdplmm023_0110View.IPopupElement popupElement = popupNode.createPopupElement(); popupNode.addElement(popupElement); } //@@end }

- Cria um Action para exibir o window e este pode ser ligado ao evento onAction de algum elemento UI da view:
public void onActionShowOMRME(...) { //@@begin onActionShowOMRME(ServerEvent)

CPMBraxis | Cria o Window e a Embed View:

36

Data:21.10.2007

Verso:00

Pg.: 37/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

// Encontra o "window" IWDWindowInfo windowInfo = (IWDWindowInfo)wdComponentAPI. getComponentInfo().findInWindows("Zdplmm023WindowOMRME"); // Cria o "window" IWDWindow window = wdComponentAPI.getWindowManager().createWindow(windowInfo,true); // Seta o posicionamento do "window" window.setWindowPosition(500,130); // Exibe o "window" window.open(); // Salva a instncia do "Window" no contexto wdContext.currentPopupElement().setWindowInstance(window); //@@end }

No Component Controller: - Cria-se dois eventos para avisar a View Principal de que um item foi selecionado na Window ou que esta simplesmente foi fechada (Aba Events):

CPMBraxis | Cria o Window e a Embed View:

37

Data:21.10.2007

Verso:00

Pg.: 38/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

Eventos criados no exemplo: OMRMEClosedEvent e OMRMESelectedEvent Criaremos um mtodo para cada evento no Component Controller (Aba Methods):
public void fireOMRMESelectedEvent( ) { //@@begin fireOMRMESelectedEvent() wdThis.wdFireEventOMRMESelectedEvent(); //@@end } public void fireOMRMEClosedEvent( ) { //@@begin fireOMRMEClosedEvent() wdThis.wdFireEventOMRMEClosedEvent(); //@@end }

Obs.: Estes mtodos sero chamados na View do window criado. Na View Principal: - Criaremos dois Event Handler para serem executados quando a view do window chamar os eventos criados no Component Controller, avisando que um item foi selecionado ou que a window foi fechada (Aba Methods com Event Hander selecionado):

CPMBraxis | Cria o Window e a Embed View:

38

Data:21.10.2007

Verso:00

Pg.: 39/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

public void handleOMRMESelectedEvent(...) { //@@begin handleOMRMESelectedEvent(ServerEvent) seta o contexto... // Pega o window "Zdplmm023Window0MRME" e fecha-o IWDWindow window = wdContext.currentPopupElement().getWindowInstance(); window.destroy(); //@@end } public void handleOMRMEClosedEvent(...) { //@@begin handleOMRMEClosedEvent(ServerEvent) // Pega o window "Zdplmm023Window0MRME" e fecha-o IWDWindow window = wdContext.currentPopupElement().getWindowInstance(); window.destroy(); //@@end }

Na View do Window criado: - Criamos dois Action para chamarem os eventos criados no Component Controller

CPMBraxis | Cria o Window e a Embed View:

39

Data:21.10.2007

Verso:00

Pg.: 40/40

WorkShop WebDynpro (DICAS)

Elaborado por:

Manoel Luiz Miranda Messner

public void onActionOMRMESelected(...) { //@@begin onActionOMRMESelected(ServerEvent) wdThis.wdGetZdplmm023CompController().fireOMRMESelectedEvent(); //@@end } public void onActionOMRMEClosed(...) { //@@begin onActionOMRMEClosed(ServerEvent) wdThis.wdGetZdplmm023CompController().fireOMRMEClosedEvent(); //@@end }

O Action onActionOMRMESelected pode ser ligado ao evento onLeadSelect de um Table ou onAction de um Button. E o Action onActionOMRMEClosed pode ser ligado a um Button ou LinkToAction para fechar o window. Obs.: Para que a View possa utilizar os mtodos pblicos fire... citados acima, o Component Controller deve estar disponvel para a View. Caso ainda no esteja, v na aba Properties da View (ao lado da aba Layout) e selecione-o na window Required Controllers.

CPMBraxis | Cria o Window e a Embed View:

40