2

My dialog is defined as document:

  onOpenDialog : function () {
     var oView = this.getView();
     var oDialog = oView.byId("helloDialog");
     // create dialog lazily
     if (!oDialog) {
        // create dialog via fragment factory
        oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.wt.view.HelloDialog");
        oView.addDependent(oDialog);
     }


     oDialog.open();
  }

Let's say this dialog has many Input/Select/ComboBox and so on, user inputs in it, close, nav to another master item and detail page, open this dialog instance again, and the information is still here. What if I want to clear the information/inputs every time user closes it?

Is destroy this dialog after close the only way to solve this?

Tina Chen
  • 2,010
  • 5
  • 41
  • 73
  • About the [error](https://stackoverflow.com/questions/46484467/how-to-clear-dialog-xmlfragment-content-after-close#comment80305043_46484550) *"Cannot read property 'setInitialFocusId' of null"* --> see https://stackoverflow.com/a/54215118/5846045 – Boghyon Hoffmann Jan 06 '21 at 13:08

3 Answers3

4

Dialog XML

<Dialog afterClose="dialogAfterclose" >
    <beginButton>
        <Button text="yes" press="confirmOk"/>
    </beginButton>
    <endButton>
        <Button text="no" press="confirmCancel"/>
    </endButton>
</Dialog>

Create the Dialog

if(!this._oDialog){
    this._oDialog = sap.ui.xmlfragment("idFragment","Path_to_your_Dialog", this);           
}

You need to use destroy() of the sap.ui.core.Element.

dialogAfterclose: function(oEvent) {
    this._oDialog.destroy();
}

As per your code

onOpenDialog : function () {
  var oView = this.getView();
  if (!this._oDialog) {
      this._oDialog = sap.ui.xmlfragment(oView.getId(), "sap.ui.demo.wt.view.HelloDialog");
      oView.addDependent(this._oDialog);
  }
  this._oDialog.open();
},     
dialogAfterclose: function(oEvent) {//function called after Dialog is closed
   this._oDialog.destroy();//destroy only the content inside the Dialog
},
confirmOk: function(oEvent) {
    this._oDialog.close();//Just close the Dialog, Dialog afterClose() will be called and destroy the Dialog content.
}

Ref: sap.ui.core.Element - destroy()

santhosh
  • 463
  • 4
  • 15
Inizio
  • 2,226
  • 15
  • 18
  • It returns `adding element with duplicate id` when reopen – Tina Chen Oct 10 '17 at 09:09
  • `duplicate ID` of Dialog?. If yes then you have to create the Dialog only once and use the same Dialog instance. – Inizio Oct 10 '17 at 09:24
  • Duplicate Id of **element** in Dialog, https://stackoverflow.com/a/25301932/5238583 it seems destory() did not clear the dialog? – Tina Chen Oct 10 '17 at 09:26
  • 1
    `destroy()` will clear the content of the dialog not the Dialog. As per the link you have shared, you need to follow the same way to use the same Dialog instance. Save the dialog instance using controller like `this._oDailog`. – Inizio Oct 10 '17 at 09:43
  • But how to clear data/content using the same Dialog instance? So I should abandon `destroy` ? – Tina Chen Oct 10 '17 at 09:45
  • Thanks very much! Is call `destroy()` in both `confirmOk` and `confirmCancel ` the same effect as call `destroy()` in `afterClose`? – Tina Chen Oct 10 '17 at 12:46
  • I still have two questions, since I still need to call `close()` in confirm functions to fire `afterClose` event, why not directly call `destory()` in confirm functions. And the second is, after destory() the dialog can no longer be used in the UI as the doc says. How to reopen? Since this._oDialog is not set to null by destory(), the open() call will results an error. – Tina Chen Oct 10 '17 at 14:11
  • `this._oDialog= undefined;` need to be added after `this._oDialog.destroy();` – Tina Chen Oct 10 '17 at 14:17
  • Use `if(this._oDialog) this._oDialog.destroy();` thats enough – Inizio Oct 10 '17 at 14:30
  • The code `this._oDialog= undefined;` is not required. Your are assigning the dialog to controller - `this._oDialog = sap.ui.xmlfragment("idFragment","Path_to_your_Dialog", this);` so that no need to create the dialog again. If you use `this._oDialog= undefined;` after `this._oDialog.destroy();` the dialog has to be create again. – Inizio Oct 10 '17 at 14:42
  • If not recreate the dialog, `Uncaught TypeError: Cannot read property 'setInitialFocusId' of null` will occur. – Tina Chen Oct 11 '17 at 01:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156445/discussion-between-inizio-and-tina). – Inizio Oct 11 '17 at 09:30
2

I found that my error is caused by two reasons:

1. Forgot to set undefined after destory()

confirmCancel = function() {
   this._oAddAssignDialog.destroy();    
   this._oAddAssignDialog = undefined;
}

2. This dialog is used in table that is reused in different views, the tableview id should set to different.

//view 1
<mvc:XMLView id="modifyTableView" viewName="xxx.view.AssignTable"/>
//view 2
<mvc:XMLView id="detailTableView" viewName="xxx.view.AssignTable"/>

So that oView.getId() won't generate the same id in different controller.

Tina Chen
  • 2,010
  • 5
  • 41
  • 73
-1
/***********************************/
onOpenAddEmployeeDialog: function () {
    var oView = self.getView()
    var oDialog = oView.byId('addEmployeeFragment');

    if ((oDialog = !null)) {
       var oDialog = sap.ui.xmlfragment(oView.getId(), 'sap.ui.view.AddEmployeeFragment'
       oView.addDependent(oDialog);
    }

    var dialogModel = new JSONModel();
    oDialog.setModel(dialogModel, 'dialog');
    oDialog.open();

},
/***********************************/           


/***********************************/
 dialogAfterClose: function () {
    var oView = self.getView()
    var oDialog = oView.byId('addEmployeeFragment');

    //clear dialog Data
    var oDialogData = oDialog.getModel('dialog').getData();
    Object.getOwnPropertyNames(oDialogData).forEach(function(d) {
         oDialogData[d] = 
     });

   dialogModel.setData(oDialogData);
   oDialog.close();
   oDialog.destroy();
},
/***********************************/

*AddEmployee.fragment.xml

<core:FragmentDefinition
  xmlns:core="sap.ui.core" xmlns:m="sap.m"
  xmlns="sap.ui.layout.form"
  xmlns:l="sap.ui.layout">
  <m:Dialog id="addEmployeeFragment"  afterClose="dialogAfterClose" title="Add Employee" contentWidth="500px" contentHeight="600px">
    <m:content>
      <Form editable="true">
        <FormContainer>
            <FormElement label="Actual Entrance Time">
              <fields>
                <m:TimePicker
                  id="empAEDTP1"
                  value="{dialog>/actualStartTime}"
                  valueFormat="HH:mm"
                  minutesStep="5"
                  displayFormat="HH:mm"
                  change="handleChange"/>
              </fields>
            </FormElement>
            <FormElement label="Actual Exit Time">
              <fields>
                <m:TimePicker
                  id="empAEDTP2"
                  value="{dialog>/actualEndTime}"
                  valueFormat="HH:mm"
                  displayFormat="HH:mm"
                  minutesStep="5"
                  change="handleChange"/>
              </fields>
            </FormElement>
            <FormElement label="Note">
              <fields>
                <m:Input value="{dialog>/note}"></m:Input>
              </fields>
            </FormElement>
          </formElements>
        </FormContainer>
        <layout>
          <ResponsiveGridLayout/>
        </layout>
      </Form>
    </m:content>
    <m:endButton>
      <m:Button type="Accept" text="Save" icon="sap-icon://add" press="onSaveEmployee" />
    </m:endButton>
    <m:beginButton>
      <m:Button type="Reject" text="Cancel" icon="sap-icon://cancel" press="dialogAfterClose" />
    </m:beginButton>
  </m:Dialog>
</core:FragmentDefinition>
kafkas
  • 475
  • 1
  • 4
  • 11