cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic creation of ItemListBox and binding a child node

Former Member
0 Kudos

Hello @all,

I have the following context structure

root

--category

-- --report

-- -- --id

-- -- --name

-- --id

-- --name

the parent node is "category" with attributes "id" and "name" and the child node is "report" with "id" and "name".

Now I want on an onAction-Event of a Button, that for every category an itemListBox will be created with the according report names. the creation of the itemList is not the problem, but the binding of the datasource and/or the descriptivetext.

my code:


public void initItemListBox( )
  {
    //@@begin initItemListBox()
    IWDView view = wdContext.currentContextElement().getSelectView();
    IWDGroup group = (IWDGroup) view.getElement("ItemListGroup");
    if (group.hasChildren())
    {
      group.removeAllChildren();
    }
    for (int i = 0; i < wdContext.nodeCategory().size(); i++)
    {
      ICategoryElement catEl = wdContext.nodeCategory().getCategoryElementAt(i);
      wdContext.nodeCategory().setLeadSelection(i);
      generateItemLists(wdContext.currentContextElement().getSelectView(), wdContext, catEl);
    }
    //@@end
  }

public void generateItemLists( com.sap.tc.webdynpro.progmodel.api.IWDView view, de.mgi.portaldev.bc.mdw.msi.wdp.IPrivateCRSReportView.IContextNode wdContext, de.mgi.portaldev.bc.mdw.msi.wdp.IPrivateCRSReportView.ICategoryElement category )
  {
    //@@begin generateItemLists()
    //    ItemListBox
    IWDGroup group;

    IWDGroup catGroup;
    IWDLabel label;

    String groupId = "group_" + category.getName();
    catGroup = (IWDGroup) view.createElement(IWDGroup.class, groupId);
    IWDMatrixLayout matrLayout = (IWDMatrixLayout) catGroup.createLayout(IWDMatrixLayout.class);

    String labelId = "label_" + category.getName();
    label = (IWDLabel) view.createElement(IWDLabel.class, labelId);
    label.setText(category.getName());
    IWDMatrixData layout = (IWDMatrixData) label.createLayoutData(IWDMatrixData.class);
    layout.setVAlign(WDCellVAlign.TOP);

    String itemListId = "itemList_" + category.getName();
    IWDItemListBox itemListBox = (IWDItemListBox) view.createElement(IWDItemListBox.class, itemListId);
    label.setLabelFor(itemListId);
    IWDMatrixData itemlayout = (IWDMatrixData) itemListBox.createLayoutData(IWDMatrixData.class);
    itemListBox.bindDescriptiveText("crsReporting.category.report.name");

    IWDNodeInfo reportNodeInfo = category.nodeReport().getNodeInfo();
//    itemListBox.bindText(reportNodeInfo.getAttribute("name"));
    itemListBox.setVisibleItems(5);
    IWDMatrixHeadData matrixHead = (IWDMatrixHeadData) itemListBox.createLayoutData(IWDMatrixHeadData.class);

    IWDAction itemListAct = (IWDAction) wdThis.wdGetItemSelectAction();
    itemListBox.setOnLeadSelect(itemListAct);

//    itemListBox.bindDataSource(reportNodeInfo);
    itemListBox.bindDataSource("crsReporting.category.report");

    catGroup.addChild(label);
    catGroup.addChild(itemListBox);
    group = (IWDGroup) view.getElement("ItemListGroup");
    group.addChild(catGroup);

    //    END ITEMLIST
    //@@end
  }

What am I doing wrong? in every ItemListbox there are only the report names of the last category.

thanks.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Is there a workaround for this problem.

any suggestions by solving this problem in another way?

Does the RowRepeater exist in WD for java????

thanks.

Message was edited by:

Claudia Sass

Former Member
0 Kudos

RowRepeater is available in WD Java since NW CE (7.1). With RowRepeater, the solution is trivial and can be done completely by declaration in view designer.

In earlier releases, you can solve it as follows (non-trivial)

- For each category, create a separate context node "Category_i" with an attribute "name"

- Inside each category node, create a non-singleton node "Reports" with an attribute "name"

- Foreach report, add a node element to the reports subnode of its category node <b>element</b>

All this has to be done using the generic context API.

On each change of the data, reset the context and re-create these nodes.

In wdDoModifyView(), check if data have changes and create UI elements programmatically.

- For each category, create a group, bind header text to category name.

- Inside each group, create a ItemListBox, bind "dataSource" to reports sub-node of category (non-singleton!) and bind "text" to text attribute of report node.

Sample code:

To build context structure:


private void createCategories()
  {
    for (int i = 0; i < 3; ++i)
    {
      IWDNodeInfo categoryNodeInfo = wdContext.getNodeInfo().addChild("Category" + i, null, true, CMICardinality.ONE, CMICardinality.ONE, true, null);
      IWDAttributeInfo att = categoryNodeInfo.addAttribute("name", "ddic:com.sap.dictionary.string");
      IWDNode categoryNode = wdContext.getChildNode(categoryNodeInfo.getName(), 0);
      categoryNode.getElementAt(0).setAttributeValue(att.getName(), "Category #" + i);
      
      IWDNodeInfo reportNodeInfo = categoryNodeInfo.addChild("Reports", null, false, CMICardinality.MANY, CMICardinality.ZERO_TO_ONE, true, null);
      IWDAttributeInfo attReportName = reportNodeInfo.addAttribute("name", "ddic:com.sap.dictionary.string");

      IWDNode reportNode = categoryNode.getChildNode("Reports", 0);
      for (int j = 0; j < 5; ++j)
      {
        IWDNodeElement report = reportNode.createAndAddElement();
        report.setAttributeValue("name", "Report #" + j);
      }
    }
  }

To recreate UI:


if (<data_have_changed>)
    {
      IWDTransparentContainer root = (IWDTransparentContainer) view.getRootElement();
      for (int i = 0; i < 3; ++i)
      {
        IWDNode categoryNode = wdContext.getChildNode("Category" + i, 0);
        IWDAttributeInfo attName = categoryNode.getNodeInfo().getAttribute("name");
        IWDGroup group = view.createElement(IWDGroup.class);
        root.addChild(group);
        IWDCaption header = view.createElement(IWDCaption.class);
        group.setHeader(header);
        header.bindText(attName);
        
        IWDNode reportsNode = categoryNode.getChildNode("Reports", 0);
        IWDAttributeInfo attReportName = reportsNode.getNodeInfo().getAttribute("name");
        IWDItemListBox list = view.createElement(IWDItemListBox.class);
        group.addChild(list);
        list.bindDataSource(reportsNode.getNodeInfo());
        list.bindText(attReportName);
      }
    }

Armin

Fixed code tags

Former Member
0 Kudos

Hello Armin,

with a few modifications the code is now running.

Now I want to get within an Action on the ItemListBox the current reportname.

How can this be done?

Thanks.

Former Member
0 Kudos

(**) list.bindText(attReportName);

Create an action "ReportSelected" with a parameter "report" of type IWDNodeElement.

Add the following code after the line above (**):

list.mappingOfOnLeadSelect().addSourceElement("nodeElement", "report");

In the action handler:

void wdOnReportSelectedAction(IWDCustomEvent event, IWDNodeElement report)

{

String reportName = String.valueOf( report.getAttributeValue("name") );

}

Armin

Former Member
0 Kudos

great thanks for your help. Problem is solved.

Claudia

Answers (1)

Answers (1)

Former Member
0 Kudos

no one any idea???

Former Member
0 Kudos

Your idea is sound, but it cannot be done like this. The reason is that it is not possible to bind against node <b>elements</b>.

If you have a RowRepeater available in your release, this could be used for solving the use case.

Armin