5

I am trying to make a custom dialog to show some text and link in the footer along with buttons. I don't know how to change the existing rendering for this, so I wrote a simple renderer to check the behavior. This is my code:

sap.m.Dialog.extend("EnhancedDialog",{

  metadata:{
    properties:{
      footerLabelText:{type:"string",defaultValue:null},
      footerLinkText:{type:"string",defaultValue:null},
      footerLinkHref:{type:"string",defaultValue:null}
    },
    aggregations:{
      _label:{type:"sap.m.Label",multiple:false,visibility:"hidden"},
      _link:{type:"sap.m.Link",multiple:false,visibility:"hidden"}
    },
    events:{}
  },

  init:function(){
    this.getAggregation("_label", new sap.m.Label({text:"Check"}));
    this.getAggregation("_link",new sap.m.Link({text:"Link"}));
  },

  setFooterLabelText:function(oLabelText){
    this.setProperty("footerLabelText",oLabelText,true);
    this.getAggregation("_label").setText(oLabelText);
  },

  setFooterLinkText:function(oLinkText){
    this.setProperty("footerLinkText",oLinkText,true);
    this.getAggregation("_link").setText(oLinkText);
  },

  setFooterLinkHref:function(oLinkHref){
    this.setProperty("footerLinkHref",oLinkHref,true);
    this.getAggregation("_link").setHref(oLinkHref);
  },

  renderer:{
    render:function(oRM,oControl){
      oRM.write("<div");
      oRM.writeControlData(oControl);
      oRM.writeClasses();
      oRM.write(">");
      oRM.renderControl(oControl.getAggregation("_label"));
      oRM.renderControl(oControl.getAggregation("_link"));
      oRM.write("</div");   
    }
  }
});

var enhancedDialog=new EnhancedDialog();
var btn=new sap.m.Button({
  text:"Click Here!",
  press: function(){
    enhancedDialog.open();
  }
});

But I am getting the error

Dialog.js:6 Uncaught TypeError: Cannot read property 'setInitialFocusId' of undefined

when I am clicking the button.

Can someone point out what I am doing wrong?

And how to change the existing renderer behavior to show text in the footer?

This is what I want to make:
Dialog with some text in the footer

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170

2 Answers2

4

The error you are seeing is because you have overwritten the init() method and not called the overwritten init() of Dialog. So the internal popup and other stuff does not get initialized. You have to call the base.init() this way:

  init:function(){
    sap.m.Dialog.prototype.init.apply(this,arguments);
    this.getAggregation("_label", new sap.m.Label({text:"Check"}));
    this.getAggregation("_link",new sap.m.Link({text:"Link"}));
  },

However you will need to copy most of the DialogRenderers code to get a fully functional dialog.

Alternatively you could use the unmodified DialogRender and overwrite the Dialog._createToolbarButtons() method to add your Label and Link to the beginning:

  _createToolbarButtons:function () {
    Dialog.prototype._createToolbarButtons.apply(this,arguments);
    var toolbar = this._getToolbar();
    var toolbarContent = toolbar.getContent();
    toolbar.removeAllContent();
    toolbar.addContent(this.getAggregation("_label"));
    toolbar.addContent(this.getAggregation("_link"));
    // insertContent is not implemented correctly...
    toolbarContent.forEach(function(control){toolbar.addContent(control)});
  },
  renderer:DialogRenderer

Full example on Plunker.

schnoedel
  • 3,918
  • 1
  • 13
  • 17
  • 1
    And i have a warning, too: The `_createToolbarButtons` Method is declared as private. So it is not part of the official API. You are not supposed to overwrite it. When the UI5 implementation of the Dialog changes your code could break. But on the other hand - the renderer depends on private aggregation `_toolbar` too, so copying that implementation could also break in future. So take the quick and dirty solution i've provided you above or create a new dialog from scratch. The sap.m.Dialog is not implemented in a way that allows you to enhance it with your requirement. – schnoedel May 23 '16 at 08:42
  • Thanks for the information, @schnoedel! So, to prevent the code from breaking, would you recommend copying all the code from Dialog.js to my custom control file and then make necessary changes into that? – AlacritousQueller May 23 '16 at 12:10
  • 1
    Yes, you could do that. You would have to copy the `DialogRenderer` and the `AssociativeOverflowToolbar` (which is undocumented and probably subject to change) and possibly further classes and css and themes?... And you would have another problem: You won't get fixes and updates to the original Dialog until you merge them manually into your copies. So my recommendation: Make it quick and dirty by overwriting `_createToolbarButtons()` and fix it later, if you ever need to. – schnoedel May 23 '16 at 13:33
  • Applications can now add custom footer toolbar without having to extend `sap.m.Dialog`: https://stackoverflow.com/a/74797724/5846045 – Boghyon Hoffmann Dec 14 '22 at 11:40
1

[...] show some text and link in the footer along with buttons.

Having a customizable Dialog footer is now supported since UI5 1.110. Simply define sap.m.Toolbar in the new <footer> aggregation of your sap.m.Dialog. For example:

<Dialog xmlns="sap.m" title="Title" initialFocus="okButton">
  <!-- ... -->
  <footer> <!-- Since UI5 1.110: -->
    <Toolbar>
      <Text text="Some text!" />
      <ToolbarSpacer />
      <Button id="okButton" text="OK" type="Emphasized" />
      <Button text="Cancel" />
    </Toolbar>
  </footer>
</Dialog>

Sample demo:

globalThis.onUI5Init = () => sap.ui.require([
  "sap/ui/core/mvc/XMLView",
], async (XMLView) => {
  "use strict";
  
  const control = await XMLView.create({
    definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
      xmlns="sap.m"
      displayBlock="true"
      height="100%"
    >
      <App autoFocus="false">
        <dependents>
          <Dialog id="myDialog"
            class="sapUiResponsiveContentPadding sapUiResponsivePadding--header sapUiResponsivePadding--content sapUiResponsivePadding--footer"
            initialFocus="okButton"
            title="Title"
            draggable="true"
            resizable="true"
          >
            <Text text="Content ..." />
            <footer>
              <Toolbar>
                <Text text="Some text in the footer!" />
                <ToolbarSpacer />
                <Button id="okButton" text="OK" type="Emphasized" />
                <Button text="Cancel" />
              </Toolbar>
            </footer>
          </Dialog>
        </dependents>
      </App>
    </mvc:View>`,
    afterRendering: function () {
      this.byId("myDialog").open();
    }
  });
  control.placeAt("content");
})
<script id="sap-ui-bootstrap"
  src="https://sdk.openui5.org/nightly/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core,sap.m,sap.ui.unified,sap.ui.layout"
  data-sap-ui-async="true"
  data-sap-ui-oninit="onUI5Init"
  data-sap-ui-theme="sap_horizon"
  data-sap-ui-compatversion="edge"
  data-sap-ui-excludejquerycompat="true"
  data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170