cancel
Showing results for 
Search instead for 
Did you mean: 

Nested subnodes/AdvancedListPanes: Bug in UI Designer?

former_member201819
Participant
0 Kudos

Dear All,

I'm currently facing a problem with an addon solution.

  • Built a custom BO with 3 [0,n] subnodes nested into each other, here's the data model:

  • When creating an instance via the QA User Interface (and thereby new (sub)node items), these implicit parent-child relations work wonderfully out-of-the-box: When you select a row, the respective entries in the table bound to the subordinate node will be displayed therein.

  • BUT: When you save, close and reopen the same instance, no content of the subnodes beneath level 1 will be displayed anymore:

  • Double checked with a query to make sure these subnode items actually exist in the database, they do:

Some strange facts about this:

  • I have another (very simple) UI here which was created by a student of mine, also with 3 subnodes where this works fine, also when opening a saved BO instance
  • Spent AGES fiddling around with UI Designer properties and SADL queries by parent node ID crashing for no reason (by the way: it is sooooo awful not to be able to debug this unholy silverlight blackbox!), no improvement.
  • Then I re-bound all lists and data fields (to backend nodes and elements) and it worked! For 10 minutes. Then, when testing the UI, although I hadn't changed anything in the meanwhile, I ran into a silverlight exception(which provided no valuable information at all, as usual). Afterwards it stopped working and never worked again !?

Now my questions:

  • Has anyone had any similar problems and found a solution?
  • Is there something particular to consider here?

Appreciate all hints and comments!

Kind Regards

Pablo

Accepted Solutions (0)

Answers (6)

Answers (6)

former_member201819
Participant
0 Kudos

Finally, the reason for this erroneous behaviour could be detected.

It was caused by a script which is used to initially query the data in the list of "Subnode Level 1" (employees who belong to a specific payroll group) after the user selected a specific value in a dropdown.

This script is executed from within an event handler that is bound to an "OnValueChanged" event of the dropdown-list "Payroll Group".

The strange thing is that this event handler is called immediately after opening the screen (coming from the edit-inport), although the value of the dropdown wasn't changed but just loaded from the database.


To my understanding, this is a wrong behaviour. The event "OnValueChanged" should only be triggered if the value is actually changed by a user or another script!

What do you think?

Kind Regards

Pablo

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

I do not know the exact UI logic, but I can imagine that the initial value was space and the data binding changed that to "something" on data load.

Therefore the event handler must be fired.

Also: Imagine the value would be set to "A" and the event handler would not be fired. Then the value is changed to "B" (event handler fired) and changed back to "A" (again event handler is fired).

Based on the event handler the UI looks now different from the initial one even as the value is (again) "A".

This would also raise issues.

HTH,

   Horst

ludger_bunger
Participant
0 Kudos

Hi Pablo,

the "OnValueChanged" is a UI event, thus it is not bound to the BO field but to the UI Model field.

This field ("obviously") also changes on loading a BO (if the BO's field content is not initial).

So this is actually my expected behavior - but I might be influenced due to having worked with the UI-Designer for over 5 years.

Best regards,

Ludger

former_member201819
Participant
0 Kudos

OK guys, might also be a philosophical question.

Yes, from a logical point of view the UI-field is changed from "empty" to "something" when you open an instance created and persisted beforehand.

But on the other hand, it is cumbersome to work with if your aim is just to trigger some action scripts after something was actually changed by a user working with the UI, because you always would have to do cross checks if that field was filled upon opening an istance or if it was actually changed by a user...how can you check that?

Would be much easier to have that built in as the BO-engine "knows" when it loading an instance and when it doesnt. So ideally maybe there would be an event "ValueChangedManually" and "ValueChangedOnLoad"...

Cheers

Pablo

ludger_bunger
Participant
0 Kudos

Hi Pablo,

yes, you are right, this is more philosophical.

You could try and file an incident but I believe this will not be changed since changing this would pretty sure break existing implementations depending on the current behavior.

That said, in my career I encountered all three use cases:

  1. OnInitialLoading
  2. OnAnyChange
  3. OnAfterChangeWithoutLoad

I used the behavior combining both cases actually the most.

This use case includes computation of "UI transient fields" defining the UI behavior depending on BO state which needs to be triggered on loading as well as any change (to avoid slow/evil AfterLoading on Application Server Layer).

Here is how I usually implemented your use case:

  1. Create an additional EventHandler
  2. Add A Condition Operation
  3. Bind the condition to the NodeID/UUID of the Business Object
  4. add a condition checking for the constant " " (contains a single space!) with no event handler triggered in this case
  5. add a default condition triggering your original event handler

The logic of this is as follows: If the UUID is empty, no Bo has been loaded -> no event handler is triggered in all other cases -> the original event handler is triggered.

Best regards,

Ludger

former_member201819
Participant
0 Kudos

Hi Ludger,

firstly, regarding your three cases, I would say it shouldn't break existing implementations if they just kept 2(OnAnyChange) which is the current behaviour and added 1(OnInitialLoading) and 3(OnAfterChangeWithoutLoad) which would be additional events.

But I will definitely not file an incident anyway as the way cloud support handles incidents would probably cost me another week to explain the request and the use case over and over again. Maybe you can talk about that SAP-internally if you will.

Secondly, thank you for your suggestion.

Your approach is good if you want to distinguish between "create new" and "edit existing" with no regard to the moment the field is changed. Though checking against an empty space is a bit fuzzy, where does this space even come from? hehe. Maybe one could use the $System.IsPersistent or $System.Saved context-variables for this use case (though I don't actually know their exact meaning as documentation is poor).


But what I need is to distinguish between the moments "onOpenScreen" vs. "onUserEdit", which is the same in your conditional logic regarding the "edit existing"-case as the UUID/NodeID already exists when the OnValueChanged-event of my data field is executed during "OnInitialLoading".

So I tried the following:

  • use the "Condition"-logic, but with another unbound data field that I called "bool_loadingComplete" with default value "false"
  • append another Operation (of type DataOperation) to the "EditHandler" and "EditHandlerSysPTP" after the "Read"-Operation where I assign "true" to "bool_loadingComplete".

But this doesn't work either as it seems the data is not completely loaded when you put another operation in line after the read-operation.

Then I tried to use the backend-"AfterLoading"-Script like:

  • create a [Transient] element LoadingComplete of type Indicator
  • create a data field "LoadingComplete" in UI Designer and bind this to the transient element
  • set it to false with an UI-operation of type "assignConstant" before the Read-Operation in both edit handlers
  • finally use the backend "AfterLoading"-event to set this LoadingComplete-Indicator to true


This procedure felt overelaborate to me...and also did not work.


At this point, I cannot believe that there is no possibility to determine if the initial BO instance loading on the UI is completed or not. Or do I miss out something here?


Kind Regards

Pablo





ludger_bunger
Participant
0 Kudos

Hi Pablo,

I like the idea of using the $System.IsPersistent variable.

Did you try it?


Sorry I do not have a solution to your issues here.

Since UI-Designer is not my main area of expertise I'd have to set up a sample case and try myself whether I can figure something out which could be working for you.

former_member201819
Participant
0 Kudos

Just to add some more info on that:

The problem doesn't seem to be "just a user interface issue".

Additionally, these "backend problems" exist:

1) Access from code level from subnode level 1 downwards not possible

>> foreach(var child in subnode1.subnode2){no results}

2) When I define custom queries on these subnodes level 2+, they never return any results

>> although "normal" QueryByElements actually do return results

3) Custom query on subnode level1 returns results BUT "Navigate by Association" in Studio Query Execution Tool doesn't show available subnode level 2 as navigation target

>> although this target is available when executing QueryByElements on subnode level 1..

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

An expression like "foreach(var child in subnode1.subnode2" corresponds to a loop inside a loop.

Do you get a result if you break it up:

foreach(var child in subnode1 ) {

   foreach(var grandchild in child ) { ....

Bye,

   Horst

former_member201819
Participant
0 Kudos

Hello Horst,

you are right, I should have written "foreach(var child in specificInstanceOfSubnode1.subnode2)". I did actually use two loops in my code as you suggested, just got it wrong in my previous post, so that was not the problem, but thanks for your hint!

Kind Regards
Pablo

P. S. If you want to engage, I have an open Incident 3100951089 running with Cloud Support

former_member201819
Participant
0 Kudos

Going forward, I ran into another problem which might be related:

To check if a time recording item ("CalendarItem") had been changed since a certain date, I wanted to introduce a status where one possible value would be "Changed" and subsequently there would be an association "ReplacedBy" to another "CalendarItem".

Unfortunately, Dev Desktop throws error that the respective node was "not found":

(Same error for level 2, that is EmployeePayrollTime.TimesPerEmployee.TimeTypeBalance)

On the other hand, if I go back to subnode level 1, the association can be activated successfully:

Could there be a connection between this problem and the fact that the subnode items from level 2 and below are not displayed when opening an existing BO instance??

Kind Regards

Pablo

ludger_bunger
Participant
0 Kudos

Hi Pablo.

Imho these two issues are not (to be more precise: should not be) related to each other.

For the second I would assume a typo of some sort on TimeTypeBalance or a missing activation but I am reasonably sure you checked these already.

Did setting the Default Lead Selection property on TimesPerEmployee solve your first issue?

Best regards,

Ludger

former_member201819
Participant
0 Kudos

Hi Ludger,

hm allright, just seemed kind of an unlikely coincidence to me that both components fail from 2nd subnode level downwards.

No, there is definitely no typo in the association path, double checked on that. Furthermore, I defined each subsequent subnode via STRG+SPACE auto-complete so the SDK seems to (or should) "know" that they actually exist.

And as per my response to Senz' post, "Default Lead Selection" did obviously not solve the issue..

Kind Regards

Pablo

former_member186648
Active Contributor
0 Kudos

Hi Pablo,

If <Ctrl>+<Space> gave the node, then activation should also work.

You could raise a ticket.

Thanks, Pradeep.

former_member201819
Participant
0 Kudos

By the way, this little side problem could be solved by just defining the association like

association ReplacedByItem [0,1] to CalendarPost;

...or in general terms:

<association> <associationName> <multiplicity> to <nodeName>

>> that means, when you specify an association to a node of the same BO you are defining, the path is expected to be "just the subnode name" (which doesn't really make sense to me) instead of the whole static namespace path (which would be "association ReplacedByItem [0,1] to EmployeePayrollTime.TimesPerEmployee.TimeTypeBalance.CalendarPost" in my case or in general terms <association> <associationName> <multiplicity> to <staticNameSpacePath>.

Unfortunately, this had very likely nothing to do with my major parent-child-relation-lost problem...

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

The association defines which node has to be reached.

Either the Alternative Key or the valuation defines the instance(s).

For what reason do you need the path?

Bye,

   Horst

former_member201819
Participant
0 Kudos

Hello Horst,

I'm not sure if I understood what you mean.


The association defines which node has to be reached.

If I define an association from MyCustomBO to a subnode of another BO, say to SalesOrder.Item, I would declare it e.g. like "association ToSalesOrderItem [0,1] to SalesOrder.Item". So when I declare an association to a subnode of MyCustomBO, say to MyCustomBO.Item in MyCustomBO itself (intended to maintain relations with nodes in other instances of MyCustomBO), I would expect it to be "association ToMyCustomBOItem [0,1] to MyCustomBO.Item" and not just "association ToMyCustomBOItem [0,1] to Item" (this is how it actually works), see what I mean? Anyway, that is just something that didn't seem consistent to me and I only posted it in case somebody might have the same problem one day...

Cheers,

Pablo

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

This is just for convenience and backwatd compatibility.

But of course you can write also

association ToMyCustomBOItem [0,1] to MyCustomBO.Item;

Bye,

   Horst

former_member201819
Participant
0 Kudos

Hello Horst,

No, I can not write association ToMyCustomBOItem [0,1] to MyCustomBO.Item;

When I do this, I cannot activate the BO-Definition.


That was exactly what I critisized in this context

Kind Regards
Pablo

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

as you can see here

I was able to activate.

May you share your BODL code and the error message?

Bye,

  Horst

former_member201819
Participant
0 Kudos

OK, so maybe it is not a general problem.

You can see code and error message in my above post from May 27, 2016 11:26 AM.

Which studio/tenant version are you working with?

My one is:

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

In the posting from May 22nd you mention 2 associations

  • 2nd and 3rd level throw errors
    -> Just omit the levels in-between (which you found already in your posting from June 24th)
  • 1st level works fine

Did I miss the point?

Bye,

   Horst

former_member201819
Participant
0 Kudos

Hello Horst,

to be honest, you are confusing me a little bit.

1) My initial post was from May 25th, I was referring to my post from May 27, 2016 11:26 AM, which one do you mean by "May 22nd"?

2) We'll have to distinguish between implicit parent-child-associations and the 3rd-level-to-3rd-level (cross-BO) associations which I am talking about here

3) The image you posted is not visible

Kind Regards
Pablo

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

Sorry, this was a typo: "22nd" ->  "27th": Too much up and down scrolling

It is as you wrote in the posting of June 24th.

Let me repeat:

     <association> <associationName> <multiplicity> to <nodeName>

The value of <nodeName> defines as

  • You need to define the BO name and the node name as the target of the association
    <BO Name>.<Node Name>
  • You can omit the BO name if the node is part of the current BO
  • This is totally agnostic of any parent-child, grandparent-child, grandgrandparent-child, ... relationship
  • It simply defines the BO and the node inside this Bo which is the target of the association

HTH,

   Horst

former_member201819
Participant
0 Kudos

OK, feel like we are going round in circles.

Yes, I agree with all of your bullet points except one small difference marked big:

The value of <nodeName> defines as

  • You need to define the BO name and the node name as the target of the association
    <BO Name>.<Node Name>
  • You can have to omit the BO name if the node is part of the current BO
  • This is totally agnostic of any parent-child, grandparent-child, grandgrandparent-child, ... relationship
  • It simply defines the BO and the node inside this Bo which is the target of the association

At least that holds true in my case..

Cheers

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

Okay.

Would you mind showing me the definition and the activation error message for your association to the own node?

Thanks,

    Horst

former_member201819
Participant
0 Kudos

Hello Horst,

as I said, you can see the definition and the error message in my post from May 27, 2016 11:26 AM when you look at the two screenshots.


You can see the general node structure in my initial post.


Kind Regards

Pablo

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Pablo,

Also as said :

The definition from the posting of May 27, 2016 11:26 AM s wrong as it contains the in-between nodes.


What do you get if you omit the "TimesPerEmployee.TimeTypeBalance" sub-path?


Bye,

   Horst

former_member201819
Participant
0 Kudos
What do you get if you omit the "TimesPerEmployee.TimeTypeBalance" sub-path?

Allright, this works although I find this to be very confusing...

ludger_bunger
Participant
0 Kudos

Senz and Pradeep are right:

you need to select a table row in the "results per employee" table in order to get it's content shown in the time items table.

To do so by default on opening the screen you have to go to the UI-Designer in the Data model and set the "Default Lead Selection" property of the table (as Senz wrote).

Best regards,

Ludger

former_member186648
Active Contributor
0 Kudos

Hi Pablo,

Compare your two screenshots:
where it is working (lead selection shown on "Results per Employee" list)

where it is not working (No lead selection shown on "Results per Employee" list)

which means lead selection on save is not happening.

Thanks, Pradeep.

former_member201819
Participant
0 Kudos

Hi Pradeep,

thank you for your reply.

I don't really see what you mean as in the screenshot where it is not working, there is no data the table "Results per Employee" so how could there be a lead selection visible??

And what do you mean by "lead selection on save"? Why "on save"?

Kind Regards

Pablo

former_member187312
Participant
0 Kudos

Hi Pablo,

Did you set the Default Lead Selection option to true for the nodes below the level1 ?

Regards,

Senz

former_member201819
Participant
0 Kudos

Thank you for the hint Senz.

From a logical point of view, the Default Lead Selection should not have a significant influence on my problem as the same behaviour could be triggered by manually selecting a line item.

Anyhow, this is interesting, because when switching Default Lead Selection to "true" on all subnode-related data lists, the following happens:

When I open an existing BO instance, items in the subnode "Results Per Employee" show up for a fraction of a second and then they disappear.

>> It seems that the "sub-items-retrieval/query" somehow doesn't work correctly in this case.

Kind Regards

Pablo

former_member187312
Participant
0 Kudos

Hi Pablo,

Tried ?

loading type to lazy for the sub nodes ?,

Regards,

Senz

former_member201819
Participant
0 Kudos

Hi Senz,

yep, already had tried that, doesn't work either. Only effect is that the text "No records found" is only displayed when Loading Type is set to "lazy"...

By the way, this property "Loading Type" only exists for subnodes from level 2 downwards. The level 1 subnode "Times Per Employee" does not have that property. This might be related to the reason why the level 1 subnode items are found but not those from lower levels..


Kind Regards

Pablo

former_member187312
Participant
0 Kudos

Hi Pablo,

Only those options (Lead Selection and loading type) are enough to achieve your scenario, failing in the case, it may be due to events related to before-Save. Try Dump Analysis to capture Silverlight exception, If nothing works, raise ticket.

Sorry,

Senz

former_member201819
Participant
0 Kudos

Hey Senz,

you are right, seems like I should raise a ticket.

There are no BeforeSave-Events defined for subnodes in my solution, I also don't see a potential show-stopper with those events, even if they existed.

Unfortunately, I cannot perform "Dump Analysis" on UI/Silverlight exceptions. I think this is not supported for Partner Developers (which is a serious pain point for me). But anyway, this is not an issue in this particular case.

Thank you and Kind Regards

Pablo