0
votes

I built this JSON (tested as valid) (.. don't mind that men and women are named the same here :-)):

{
    "staff": {
        "berlin": [{
            "male": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ],
            "female": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ]
        }],
        "paris": [{
            "male": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ],
            "female": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ]
        }],
        "oslo": [{
            "male": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ],
            "female": [
                {"firstName": "Lasse", "lastName": "Larsson"},  
                {"firstName": "Gerrit", "lastName": "Gartner"}
            ]
        }]
    }
}

In my controller I set the JSON model to the whole view like this:

// init instance of JSON model
this.staffData = new sap.ui.model.json.JSONModel();
// load JSON file into model
this.staffData.loadData("ajax-dummy/staff.json");
// bind model to whole view 
this.getView().setModel(this.staffData);

In my XML view I would now like to dynamically build a (nested) DropdownBox which should make me select e.g. berlin->male->lastName So I need 3 levels of ListItems.

The first problem is: I could generate this with JS (build one Listitem for each key in the staff object etc.) but I have no idea how to deal with this in the XML view. It looks like this at the moment:

<content>
<DropdownBox id="dd-locations" editable="true">
<core:ListItem text="{/staff/berlin}"></core:ListItem>
</DropdownBox>
</content> 

And it displays (of course) just "{object ..}" in den DropdownBox, because it IS an object.

Is this even possible to build within the XML view with data binding? Or is there a better way to structure the JSON? I know the ListItems need an array... And finally: How can I nest the ListItems? Is there a better Control then DropdownBox I should use?

EDIT: What I want to have is "just" nesting Listitems like I could in HTML. I tried e.g.:

<ComboBox>
                            <items>
                                <core:ListItem key="key2" text="text2"/>
                                <core:ListItem key="key3" text="text2">
                                    <ComboBox>
                                        <items>
                                            <core:ListItem key="key4" text="text3"/>
                                            <core:ListItem key="key5" text="text3"/>
                                            <core:ListItem key="key6" text="text3"/>
                                         </items>
                                    </ComboBox>
                                </core:ListItem>
                                <core:ListItem key="key4" text="text2"/>
                             </items>
                        </ComboBox>

But hen an error occurs which says:

Uncaught Error: Cannot add direct child without default aggregation defined for control sap.ui.core.ListItem

How can I define an item aggregation for a ListItem? Would that work?

Thanks a lot, ho

1

1 Answers

2
votes

Not sure if it is a desirable approach in your case, but given the hierarchical nature of your model, maybe this example of a "Table - Breadcrumb" is what you're looking for: https://sapui5.hana.ondemand.com/sdk/explored.html#/sample/sap.m.sample.TableBreadcrumb/preview
It allows you to 'drill deeper' into your model hierarchy, and step back up if needed too

But I'm not sure if it can be adapted to a 'multi-level dropdownbox' though...

EDIT: I had a more thorough look at your JSON, and it seems the structure is not correct. To supply data to multiple dropdowns, the data should be in Array format, not Object format. Right now, your JSON contains a property staff with multiple properties berlin, paris, etc, whereas it should be an array of cities. I have modified your JSON so the staff property contains an array of objects, which contains a gender property containing an array of objects, which contains a person property containing an array of objects.

Furthermore, in order to supply the correct binding to the "child" dropdowns, you could set the binding to the correct path upon selecting a entry from the dropdown.

See the below working snippet for the restructured model (an array of cities, an array of genders and an array of people), and the rebinding of dropdowns:

sap.ui.controller("view1.initial", {
    onInit : function(oEvent) {
        var oModel = new sap.ui.model.json.JSONModel();
        oModel.setData({
            "staff": [
                {
                    "city" : ""
                },
                {
                    "city" : "berlin",
                    "genders" : [
                        { 
                            "gender" : "male", 
                            "people" : [
                                {"firstName": "Lasse", "lastName": "Larsson"},  
                                {"firstName": "Gerrit", "lastName": "Gartner"}
                            ]
                        },
                        { 
                            "gender" : "female", 
                            "people" : [
                                {"firstName": "Paris", "lastName": "Hilton"},  
                                {"firstName": "Kate", "lastName": "Upton"}
                            ]
                        },
                    ]
                },
                {
                    "city" : "paris",
                    "genders" : [
                        { 
                            "gender" : "male", 
                            "people" : [
                                {"firstName": "Lasse", "lastName": "Larsson"},  
                                {"firstName": "Gerrit", "lastName": "Gartner"}
                            ]
                        },
                        { 
                            "gender" : "female", 
                            "people" : [
                                {"firstName": "Lasse", "lastName": "Larsson"},  
                                {"firstName": "Gerrit", "lastName": "Gartner"}
                            ]
                        },
                    ]
                },
                {
                    "city" : "oslo",
                    "genders" : [
                        { 
                            "gender" : "male", 
                            "people" : [
                                {"firstName": "Lasse", "lastName": "Larsson"},  
                                {"firstName": "Gerrit", "lastName": "Gartner"}
                            ]
                        },
                        { 
                            "gender" : "female", 
                            "people" : [
                                {"firstName": "Lasse", "lastName": "Larsson"},  
                                {"firstName": "Gerrit", "lastName": "Gartner"}
                            ]
                        },
                    ]
                },
            ]
        });
        this.getView().setModel(oModel);

    },

    handleStaffSelect : function(oEvent) {
        var oGender = this.byId("selGender");
        var oTemplate = new sap.ui.core.ListItem({ key : "{gender}", text : "{gender}"})
        oGender.bindItems(oEvent.getParameter("selectedItem").getBindingContext().getPath() + "/genders", oTemplate);
    },

    handleGenderSelect : function(oEvent) {
        var oGender = this.byId("selPerson");
        var oTemplate = new sap.ui.core.ListItem({ key : "{lastName}", text : "{lastName}"})
        oGender.bindItems(oEvent.getParameter("selectedItem").getBindingContext().getPath() + "/people", oTemplate);
    }
});

sap.ui.xmlview("main", {
    viewContent: jQuery("#view1").html()
})
.placeAt("uiArea");
<script id="sap-ui-bootstrap"
    src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
    data-sap-ui-theme="sap_bluecrystal"
    data-sap-ui-xx-bindingSyntax="complex"
    data-sap-ui-libs="sap.m"></script>

<div id="uiArea"></div>

<script id="view1" type="ui5/xmlview">
    <mvc:View 
      controllerName="view1.initial"
      xmlns="sap.m"
      xmlns:core="sap.ui.core"
      xmlns:mvc="sap.ui.core.mvc">
        <Select id="selStaff" items="{/staff}" change="handleStaffSelect">
            <core:ListItem key="{city}" text="{city}" />
        </Select>
        <Select id="selGender" change="handleGenderSelect" />
        <Select id="selPerson" />
    </mvc:View>
</script>