0

I am using splitcontainer in my application. I used two views one for Master page and other one for detail page.

This is my view code: Main.view.xml(which holds Master and detail views)

    <SplitContainer id="idSplitContainer">
            <masterPages>
            <mvc:XMLView id="master" viewName="com.test.view.Master"/>
            </masterPages>
            <detailPages>
            <mvc:XMLView id="detail" viewName="com.test.view.Detail"/>
            </detailPages>
        </SplitContainer>

Master.view.xml:

<ScrollContainer height="35rem" width="100%" horizontal="false" vertical="true" focusable="false">

<Table  id="listTable" inset="false" items="{ path: 'testModel>/testCollection'}" fixedLayout="false">
<columns>
    <Column>
    <Text text=" Number"/></Column>
    <Column>
    <Text text="Description"/>  </Column>
    <Column>
    <Text text="Status"/>
    </Column>
    </columns>
    <items>
    <ColumnListItem  vAlign="Middle" type="Navigation" press="onSelectionChange">                   
    <cells>
    <Text text="{testModel>Number}" wrapping="false"/>
    <Text text="{testModel>Description}" wrapping="false"/>
    <Text text="{testModel>Status}" wrapping="false"/>
    </cells>
    </ColumnListItem>
    </items>
    </Table>

  </ScrollContainer>

Detail.view.xml

<mvc:View controllerName=com.test.controller.Detail" xmlns="sap.m" xmlns:form="sap.ui.layout.form"  xmlns:core="sap.ui.core" xmlns:commons="sap.ui.commons" xmlns:mvc="sap.ui.core.mvc">
<form:Form >
<form:layout>
<form:ResponsiveGridLayout columnsM="1" columnsL="1" labelSpanL="2" labelSpanM="2" emptySpanL="2" emptySpanM="2" />
</form:layout>
<form:formContainers>
<form:FormContainer>
    <form:formElements>
    <form:FormElement>
        <form:fields>
        <Label id="DescriptionLabel" text="Description" />
            <Input value="{testModel>Description}"></Input>
        </form:fields>
    </form:FormElement>
        </form:formElements>
        </form:FormContainer>   
    </form:formContainers>
    </form:Form>

</mvc:View>

Component.js

    routing: {
    config: {
        routerClass: "sap.m.routing.Router",
        viewPath: "com.test.view",
        controlId: "SplitContainer",
        viewType: "XML",
        async: true
        },
        routes: [{
            name: "master",
            pattern: "",
            target: ["master"]
            }, {
            name: "testDetails",
            pattern: "test/:Number:",
            target: ["testDetails"]
            }],
        targets: {
            master: {
            viewName: "Master",
            controlAggregation: "masterPages",
            viewLevel: 0
            },
        testDetails: {
            viewName: "Detail",
            controlAggregation: "detailPages",
            viewLevel: 1
            }
        }
    },
var sampleData = {
        "testCollection": [{
         "Description": "Test Description1",
         "Status": "Completed",
        "Number":10021
        }, {
        "Description": "Test Description2",
        "Status": "Completed",
        "Number":10025
}
]
};
var oModel = new sap.ui.model.json.JSONModel(sampleData);
this.setModel(oModel,"testModel");

I am setting model in component level and i am using in both Master and Detail views.

Master.controller.js

onSelectionChange: function (oEvent) {
   var sNum = oEvent.getSource().getBindingContext("testModel").getObject().Number;
this.getOwnerComponent().getRouter().navTo("testDetails", {
                        Number: sNum
                    }, false);
            }

Detail.controller.js:

onInit: function() {  
this.getOwnerComponent().getRouter().getRoute("testDetails").attachPatternMatched(this._onRouteMatched, this); 
   },
_onRouteMatched: function(oEvent) {
this._sNum = oEvent.getParameter("arguments").Number;
this.getView().bindElement("testModel>/testCollection/"+this._sNum);    
}

Problem:

I am not able to display the details of a selected table row in Detail view.

Please guide me on this. enter image description here

  • any error displayed in the Chrome Dev Tool's console? – Binh Oct 30 '18 at 07:08
  • for the master detail realtionship you should use the flexible comlumn layout please check the designguidelines https://experience.sap.com/fiori-design-web/flexible-column-layout/ – Erch Oct 30 '18 at 07:19
  • @Erch earlier we were using unified SplitContainer , since it is deprecated. We are using m SplitContainer – Venkatesh Machineni Oct 30 '18 at 07:49
  • as I said if you want to follow sap standards you will need to use the flexible column layout, if not there might be less ppl willing to look into the problem – Erch Oct 30 '18 at 08:32
  • Not sure if this was an error from copying an pasting into StackOverflow but there is an error on the first line of your detail view, an unclosed quote for the "controllerName" – O.O Nov 12 '18 at 09:28

2 Answers2

0

The reason mostly is due to the way you are using bindElement. The statement "testModel>/testCollection/"+this._sNum is not clear. Try the following,

In the Master controller's function onSelectionChange do this,

onSelectionChange: function (oEvent) { var sContextPath = oEvent.getSource().getBindingContext("testModel").getPath(); this.getOwnerComponent().getRouter().navTo("testDetails", { Path: sContextPath }, false); }

Next in the Detail controller's function _onRouteMatched do this,

_onRouteMatched: function(oEvent) { this.getView().bindElement({path: oEvent.getParameter("arguments").Path , model: "testModel"}); }

Breakpoint
  • 1,511
  • 1
  • 18
  • 41
0

I got it working with a few changes to Main/Master Views, Sample Data and both controllers. The main issues were in your master view and data. Here is a working Plnkr or see below:

In Manifest.json or your Component.js

"routing": {
  "config": {
    "routerClass": "sap.m.routing.Router",
    "viewPath": "com.test.view",
    "controlId": "rootControl",
    "viewType": "XML",
    "async": true,
    "bypassed": {
      "target": ["master"]
    }
  },
  "routes": [{
    "name": "master",
    "pattern": "",
    "target": ["master"]
  }, {
    "name": "detail",
    "pattern": "testCollection/:detailID:", <<Change
    "target": ["master", "detail"]
  }],
  "targets": {
    "master": {
      "viewName": "Master",
      "controlAggregation": "masterPages",
      "viewLevel": "0"
    },
    "detail": {
      "viewName": "Detail",
      "controlAggregation": "detailPages",
      "viewLevel": "1"
    }
  }
}

In master.view.xml, I would advice you not to use a table as your master but a List instead:

<mvc:View controllerName="com.test.controller.Detail" xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:semantic="sap.m.semantic">
  <semantic:MasterPage id="page" title="Contents">
    <semantic:content>
      <ScrollContainer height="35rem" width="100%" horizontal="false" vertical="true" focusable="false">
        <List id="list" items="{testModel>/testCollection}" mode="SingleSelectMaster" noDataText="No List Found" growing="true" growingScrollToLoad="true" selectionChange="onSelectionChange" updateFinished="onUpdateFinished">
          <items>
            <StandardListItem title="{testModel>Description}" type="Active" press="onSelectionChange" description="{testModel>Number}" />
          </items>
        </List> <!--List instead of a table -->
        </ScrollContainer>
    </semantic:content>
  </semantic:MasterPage>
</mvc:View>

In your Master.controller.js, few changes, mainly by adding the .getSelectedItem() method (does not work on mobile Device):

onInit: function() {
    this.getOwnerComponent().getRouter().getRoute("master").attachPatternMatched(this._onRouteMatched, this);
  },
  _onRouteMatched: function(oEvent) { //<<Inital
    if (!Device.system.phone) {
      this.getOwnerComponent().getRouter()
        .navTo("detail", {
          detailID: 0 
        }, true);
    }
  },
  onSelectionChange: function(oEvent) {
    var sNum = oEvent.getSource().getSelectedItem().getBindingContext("testModel").getProperty("id"); //<<selectedItem using id

    this.getOwnerComponent().getRouter().navTo("detail", {
      detailID: sNum 
    }, false);
  }

In Detail.view.xml, that can stay the same or add a semantic tag:

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:layout="sap.ui.layout" xmlns:form="sap.ui.layout.form" controllerName="com.test.controller.Detail" xmlns:semantic="sap.m.semantic">
  <semantic:DetailPage id="page" title="{i18n>detailTitle}" navButtonPress="onNavBack">
    <semantic:content>
      <form:Form>
        <form:layout>
          <form:ResponsiveGridLayout columnsM="1" columnsL="1" labelSpanL="2" labelSpanM="2" emptySpanL="2" emptySpanM="2" />
        </form:layout>
        <form:formContainers>
          <form:FormContainer>
            <form:formElements>
              <form:FormElement>
                <form:fields>
                  <Label id="DescriptionLabel" text="Description" />
                  <Input value="{testModel>Description}"></Input>
                </form:fields>
              </form:FormElement>
            </form:formElements>
          </form:FormContainer>
        </form:formContainers>
      </form:Form>
    </semantic:content>
  </semantic:DetailPage>
</mvc:View> <!--same but with semanticpage attribute -->

In your Detail.controller.js

onInit: function() {
    this.getOwnerComponent().getRouter().getRoute("detail").attachPatternMatched(this._onRouteMatched, this);
  },
  _onRouteMatched: function(oEvent) {
    this._sNum = oEvent.getParameter("arguments").detailID;
    this.getView().bindElement({
      path: "/testCollection/" + this._sNum,
      model: "testModel"
    });
  }

And a tiny addition to data.json or your Component.js tracking by ID:

{
  "testCollection": [{
    "id": 0, //<<tracked by id 
    "Description": "Test Description1",
    "Status": "Completed",
    "Number": 10021
  }, {
    "id": 1,
    "Description": "Test Description2",
    "Status": "Completed",
    "Number": 10025
  }]
}
O.O
  • 1,389
  • 14
  • 29