Shay Zambrovski
Shay Zambrovski

Reputation: 656

sapui5 sap.m.popover won't open my control

I have a button:

var oButton = new sap.m.Button({
                    text: "Press me",
                    press: function (oEvent) {
                        if (! this._oPopover) {
                            this._oPopover = sap.ui.xmlfragment("sap.my.library.Popover", this);
                            this._oPopover.setModel(true);
                        }
                        var oButton = oEvent.getSource();
                        var oMyControl= this._oPopover.getAggregation('content')[0];
                        oMyControl.setPlaceholder("Hello World");
                        jQuery.sap.delayedCall(0, this, function () {
                            this._oPopover.openBy(oButton);
                        });
                    }
                })

And i have my xml Fragment:

<core:FragmentDefinition
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:d="sap.my.library">
    <Popover>
        <d:myControl value=""/>
        <!--<Input></Input>-->
    </Popover>
</core:FragmentDefinition>

Now, when I click the button, nothing happens, only if I click it many times, my control appears. I can say that for every 10 quick buttons clicks, my control appears maybe once.

Any suggestions? Thanks!

Upvotes: 0

Views: 2714

Answers (2)

Vanquished Wombat
Vanquished Wombat

Reputation: 9525

Could it be that 'this' is not referring to what you expect because your object is created within an anonymous function? See this explanation (ahem)

I believe the preferred pattern is to have the button press call a function in the main view where 'this' refers to the view scope.

I have a working example as follows: in then main view I have a button...

<Button
    press="showDialogue"
/>

and the code of the view controller...

    showDialogue: function(){
        if(!this._oConfirmDialog){
            this._oConfirmDialog = sap.ui.xmlfragment("sapui5.muSample.view.ConfirmDialog", this);
            this.getView().addDependent(this._oConfirmDialog);
        }
        this._oConfirmDialog.open();
    },

Note the use of view.addDependent() which lets the dialogue fragment access the view model AND destroys the dialogue instance in line the main view lifecycle events (according to the docs).

Or...you could create a local variable to capture the 'this' you actually want to refer to...

var contextThis = this;

just before your line starting

var oButton = ...

then change references to this inside the anon function to contextThis if you can't change the pattern.

Upvotes: 0

Ji aSH
Ji aSH

Reputation: 3457

this._oPopover is defined within an anonymous function declared within the button declaration.

IT CANNOT refer to a view field as you probably expect it to.

My suggestion :

var onButtonPress = function (oEvent) {
     if (! this._oPopover) {
         this._oPopover = sap.ui.xmlfragment("sap.my.library.Popover", this);
         this._oPopover.setModel(true);
     }
     var oButton = oEvent.getSource();
     var oMyControl= this._oPopover.getAggregation('content')[0];
     oMyControl.setPlaceholder("Hello World");
     jQuery.sap.delayedCall(0, this, function () {
         this._oPopover.openBy(oButton);
     });
}

var oButton = new sap.m.Button({
    text: "Press me",
    press: this.onButtonPressed.bind(this)
});

[code not tested!]

Upvotes: 2

Related Questions