Search code examples
sapui5

Bind Selected Item to Dialog


I am attempting to show data from a table item in the controls of a dialog. Here is a Plunker: https://plnkr.co/edit/MPHT17Hf4xNj3ZuuNXMd?p=preview

And here is the code specifically which gets the item data and sets it in the 'detailItem' JSONModel:

onItemPress: function(evt) {
    var me = this;
    var view = me.getView();
    var item = evt.getSource().getBindingContext('list').getObject();
    view.getModel('detailItem').setData(item);
    var dlg = new sap.m.Dialog({
        title: 'Edit Item',
        type: 'Message',
        content: [
            new sap.m.VBox({
                items: [
                    new sap.m.Label({
                        text: 'Section'
                    }),
                    new sap.m.Input({
                        value: '{detailItem>sectionId}'
                    }),
                    new sap.m.Label({
                        text: 'Cost'
                    }),
                    new sap.m.Input({
                        value: '{detailItem>costId}'
                    })
                ]
            })
        ],
        beginButton: new sap.m.Button({
            text: 'Ok',
            press: function() {
                dlg.close();
            }
        }),
        endButton: new sap.m.Button({
            text: 'Cancel',
            press: function() {
                dlg.close();
            }
        }),
        afterClose: function() {
            dlg.destroy();
        }
    }).open();
}

The Plunker is pretty straight forward. Basically, I want to select an item in the table, open a dialog with a couple input fields allowing the data to be edited. I am trying to bind the input fields to the selected item by setting the data for the 'detailItem' model and attempting to bind the value property of the input fields to the respective data element.


Solution

  • Here is a working example (forked from yours): embed.plnkr.co/ictpCHG0R3H3jtsCmHKW.

    The approach with the relative binding syntax was alright. We don't, however, need a second model, so replace {detailItem> with {list> in your dialog. Then, we can set the given binding context (from the selected item) to the dialog so that the relative bindings inside the dialog can be resolved:

    dialog.setBindingContext(item.getBindingContext("list"), "list")
    

    But that alone isn't enough. The dialog still won't display the selected data because it's not a descendant of the view and thus the "list" model is unknown to it.

    One way to solve this problem is to add the dialog to the dependents aggregation of the view or any other control in the view. By this, the model will be propagated to the dialog. And as a bonus effect, it will be destroyed together when the principal control gets destroyed:

    Special aggregation dependents is connected to the lifecycle management and databinding, but not rendered automatically and can be used for popups or other dependent controls or elements. This allows the definition of popup controls in declarative views and enables propagation of model and context information to them. [src]

    Since all controls provide the aggregation <dependents>, you can also move the dialog definition from the controller to the view.