cancel
Showing results for 
Search instead for 
Did you mean: 

IDs of elements change on page reload in XML Views

former_member190882
Participant
0 Kudos
1,708

Hi Experts,

I have designed couple of SAPUI5 XML views. Due to the requirement that the buttons and other controls should have colors and other CSS properties, which are not part of standard theme, I am modifying the CSS properties using their IDs. But a strange problem has pop up, that the IDs change abruptly on page reload.

For example the ID of a check box control in the second view is __xmlview1--selectStatusComboBox. But when the page is refreshed, the ID changes to __xmlview0--selectStatusComboBox abruptly. Therefore the CSS properties written for that element no longer apply. This is a strange problem I have come across an see no solution. Please help.

Thanks

Maruthi

Accepted Solutions (0)

Answers (3)

Answers (3)

former_member190882
Participant
0 Kudos

I fetched the view ID in the beginning and stored it in a variable. I used the variable to append to the control ID and get the dynamically changing control IDs. This solved my problem. Following is the solution,

viewId = this.getView().sId;

sap.ui.getCore().byId(viewId+"--batchesPanel").setVisible(true);

However I think SAPUI5 should avoid the view IDs being dynamically changed.

Thanks everyone above for patiently reading my issues at various steps and responding quickly and constructively!

Thanks

Maruthi

Qualiture
Active Contributor
0 Kudos

This really is NOT the way to do it, and I would strongly advise anyone against using it this way!

You should never, ever use the view prefix yourself!

Have you even tried the suggestions I gave you? The suggestions I gave you are the framework supported ways of handling fragments, ID's and controllers

Ie

var oDialogFragment = sap.ui.xmlfragment("view.someFragment",this);

will pass the controller to your fragment.

See also sap.ui.xmlfragment

former_member182862
Active Contributor
0 Kudos

+1. (i am with you Robin)

It is very obvious that this is not the right way to do thing.

Best,

-D

former_member190882
Participant
0 Kudos

Robin, I agree with what you and Dennis say. I have tried out each and everything that you have tried to help me with. I completely understand that I should be using the framework supported ways to fetch the ID and use.

However the issue is not only what is reported above. There are other complex issues such as, I need access SAPUI5 controls within a function which is provided by a third party plugin. In this scenario this.getView() or sap.ui.getCore().byId(), none of these can be used. Therefore I just found a temporary work around for that. If you have a smarter solution, please suggest.

Thanks

Maruthi

Qualiture
Active Contributor
0 Kudos

If you need the DOM object rather than the SAPUI5 control, you could use:


var domObj = this.getView().byId("myControl").$();

or


var domObj = sap.ui.getCore().byId("myControl").$();

and pass that (or any of it's properties such as ID's, or DOM siblings, etc) to your 3rd party plugin

Again, I would not mess with the contructed / generated ID's

Qualiture
Active Contributor
0 Kudos

Why not just add a 'class' property to your XML control, and use that class in your CSS?

That way you can also re-use the class, since an ID can only be used once

vladimirs_semikins
Active Contributor
0 Kudos

even though appending custom class is better, there is also other option - using CSS3 [attribute*=value] Selector

Example below will try to find class sapMComboBox which contain string "box0" in id attribute.


.sapMComboBox [id*="box0"]{

     background: red;

}

former_member190882
Participant
0 Kudos

Hi Robin,

Thanks for your response. I tried out that option. But the class gets applied to few controls and does not apply to few other controls.

Thanks

-Maruthi

vladimirs_semikins
Active Contributor
0 Kudos

why then you are trying to use CSS for id? please use generic class, e.g.

all ComboBox background will be red.

.sapMComboBox{

    background: red;

}

former_member190882
Participant
0 Kudos

Hi Vladimir,

The issue is not about setting CSS property like color etc. Combo boxes on different pages have unique properties w.r.t margin, width, etc. They have to be specified using IDs. But if the IDs change on every page refresh, the CSS properties applied are lost.

Thanks

-Maruthi

vladimirs_semikins
Active Contributor
0 Kudos

I do understand your issue, but I don't understand why you cannot select attribute by using *class* or *id contains* CSS selector. For example following CSS selector div[id*="selectStatusComboBox"] will return all div elements __xmlview1--selectStatusComboBox, __xmlview0--selectStatusComboBox, __xmlviewNNNN--selectStatusComboBox since it's return you all div tags which ID contain string *selectStatusComboBox* and ignore generated prefix __xmlviewNNNN.


Regards,

Vladimir

Message was edited by: Vladimirs Semikins

former_member190882
Participant
0 Kudos

Thanks Vladimirs. Your solution works perfectly fine in some cases. I could partly fix some of my issues. Many thanks for that

But there are few cases where it does not seem to help.

1) In CSS: If button[id*="selectStatusBtn"] is used to specify margin or any other property, the property gets applied to selectStatusBtn-inner also and the inner button text also moves and sometimes appears outside the button.

2) In Controller: Here is the main problem. In my xml view based on few conditions I have to make changes to visibility or disable few controls. Those functionalities are written w.r.t. the IDs of those controls. However since the IDs change dynamically, the controls are neither disabled nor their visibility is set to false.

Qualiture
Active Contributor
0 Kudos
  1. That's why I mentioned using the 'class' property earlier And in case it doesn't get applied to all controls, you may need to enhance/cascade (hence the C in CSS) the use of your class in your CSS file for those controls

  2. I would not recommend using CSS to change visibility of enabled status of UI5 controls! Always use the control's properties for that, and use a model to steer these properties
Former Member
0 Kudos

Here in my case the dialog box is getting dynamically created.

Try the following using your combobox instance.

this._valueHelpSelectDialog1.addStyleClass("dialog");

CSS

.dialog .sapMBtn {

  background-color: #b5985a;

}

.dialog .sapMIBar.sapMHeader-CTX {

  background-color: #b5985a;

}

.dialog .sapMIBar.sapMFooter-CTX {

  background-color: black;

}

.dialog>.sapMDialog>header.sapMDialogTitle>.sapMBarMiddle>.sapMBarPH>.sapMLabel

  {

  color: #948e2c;

}

former_member190882
Participant
0 Kudos

Thanks Robin.

1. I am not forte at using CSS. I only know a few basics of it. I will try out what you have suggested.

2. I am not using CSS for UI5 controls. I am using the control's properties itself. I am doing it like this, sap.ui.getCore().byId("__xmlview0--batchesPanel").setVisible(true);

I do not know using a model for this. Please help me with explanation.

Thanks

Maruthi

Qualiture
Active Contributor
0 Kudos

If you're using XML views, you should not use sap.ui.getCore().byId("__xmlview0--batchesPanel")

Instead, use this.getView().byId("batchesPanel") so you don't need to prefix it with the generated id's

former_member190882
Participant
0 Kudos

Thanks Robin. How do we write it for controls in a XML Fragment?

Qualiture
Active Contributor
0 Kudos

Should not make any difference, just call it from the controller the fragment is instantiated from

former_member190882
Participant
0 Kudos

Hi Robin,

It does not work on controls within the fragment! Also there is another issue using it in the views.

  this.getView().byId("batchesPanel").setVisible(true); works fine in other functions. But when used in fnCallbackMessageBox, returns errors like


  • Cannot read property 'byId' of undefined or
  • this.getView() is not a function.

Following is my code,


sap.ui.commons.MessageBox.show("You are not the creator of the batch.\nDo you want to cancel it?",

  sap.ui.commons.MessageBox.Icon.WARNING,

  "Confirm Cancel",

  [sap.ui.commons.MessageBox.Action.YES, sap.ui.commons.MessageBox.Action.NO],

  fnCallbackMessageBox,

  sap.ui.commons.MessageBox.Action.YES);

 

  function fnCallbackMessageBox(bResult) {

  this.getView().byId("batchesPanel").setVisible(true);

  sap.m.MessageToast.show("Batch Cancelled Successfully", {

     duration: 3000,                  // default

     width: "15em",                   // default

     my: "center bottom",             // default

     at: "center bottom",             // default

     of: window,                      // default

     offset: "0 0",                   // default

     collision: "fit fit",             // default

     onClose: null,                   // default

     autoClose: true,                 // default

     animationTimingFunction: "ease", // default

     animationDuration: 1000,         // default

     closeOnBrowserNavigation: true   // default

     });

}

Thanks

Maruthi

Qualiture
Active Contributor
0 Kudos

No, it should work just fine on fragments, except for one exception:

If you use a fragment in a popup such as sap.m.Dialog, then it does not work, since the dialog is obviously not part of the view itself (you will notice the controls in the dialog fragment are not prefixed with __xmlview0 etc).

In that case, just use sap.ui.getCore().byId()

As for the second part, use the debugger to see what object 'this' holds. Apparently it doesn't contain a reference to your controller bet to something else (most likely your messagebox)

former_member190882
Participant
0 Kudos

Right Robin. The controls in the dialog fragment are not prefixed with the view ID. I have to use sap.ui.getCore().byId(). And here the problem arises when the IDs are dynamically changing which ID should I pass as a parameter to the byId() method?

When the dialog opens, this points to Window object.

Thanks

Maruthi

Qualiture
Active Contributor
0 Kudos

If the ID's are changing, then I assume you did not specify ID's for those controls. If you specify an ID, it should not change.

If 'this' points to the windows object, then make sure you pass the reference to your controller instead, and call .getView().byId() from that reference

But this is fairly basic Javascript really

former_member190882
Participant
0 Kudos

Robin,

By IDs are changing, I mean the view IDs are changing and getting prefixed to the control IDs. All the controls have their IDs clearly specified. Therefore when I write sap.ui.getCore().byId("__xmlview1--searchBatchesField"), error is thrown because the new ID now is __xmlview0--searchBatchesField.

Thanks

Maruthi

Former Member
0 Kudos

Here in my case the dialog box is getting dynamically created.

Try the following using your combobox instance.

this._valueHelpSelectDialog1.addStyleClass("dialog");

CSS

.dialog .sapMBtn {

  background-color: #b5985a;

}

.dialog .sapMIBar.sapMHeader-CTX {

  background-color: #b5985a;

}

.dialog .sapMIBar.sapMFooter-CTX {

  background-color: black;

}

.dialog>.sapMDialog>header.sapMDialogTitle>.sapMBarMiddle>.sapMBarPH>.sapMLabel

  {

  color: #948e2c;

}

Qualiture
Active Contributor
0 Kudos

Yes, I understand. But as I said earlier:

  • In your XML views, use this.getView().byId() and reference the control with its ID without the prefix
  • In the specific cases where you use a dialog fragment, the ID's are not prefixed so you can use sap.ui.getCore().byId()
former_member190882
Participant
0 Kudos

I have tried that Robin. I have also posted my code on top. While I am in the dialog fragment I want to access a Panel which is in the view. That is where the problem arises. Since the panel is in the view, its ID is prefixed. Therefore sap.ui.getCore().byId() does not work without actual ID. And this.getView().byId() cannot be used because I am in the Dialog Fragment.

Qualiture
Active Contributor
0 Kudos

Yes, I understand that too, but then my question remains, have you supplied the view's controller to your fragment then?

I.e.:

var oDialogFragment = sap.ui.xmlfragment("view.someFragment",this);

former_member182862
Active Contributor
0 Kudos

HI

You have to set id for your checkbox control. Otherwise, SAPUI5 will generate one for you. and the generated ID can be different everytime.

Thanks

-D

former_member190882
Participant
0 Kudos

Hi Dennis,

Thanks for your response. I have set the id for the checkbox control i.e., selectStatusComboBox. SAPUI5 is appending the view id to it, and that part of the ID is changing on every page reload.

Thanks

-Maruthi

vladimirs_semikins
Active Contributor
0 Kudos

One of this options should work


div[id*="selectStatusComboBox"] {

    background: red;

}


.sapMComboBox[id*="selectStatusComboBox"] {

    background: red;

}


.sapMComboBox.yourAppendedCustomClass{

    background: red;

}

iamsahu
Explorer
0 Kudos

this works for me thank you 🙂