Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Karol-K
Product and Topic Expert
Product and Topic Expert
9,383

Introduction

As there are some questions on this functionality in Design Studio (Bookmarks) I post here some insides on "how this function is working". I hope this helps better in understanding what the technical solution is - and based on this some actions and behavior after save / load bookmark will get clearer.

Why bookmarks?

The purpose of bookmarks is to save the visible state of the application for a specific user. In 1.3 release the list of bookmarks is user-specific, but anyone who knows the ID can execute a bookmark of a different user directly in URL (parameter BOOKMARK=<ID>).

Technical Background

I do not want to rewrite the blog "Working with Bookmarks in Design Studio 1.3" as this is already containing information on bookmarks. The goal here is to give some technical background to explain the behavior after loading a bookmark.

Part 1. Saved Content

Currently the bookmarks are saving ALL information about the current application - this is containing in particular:

  • Data Source(s) (including name, filters, variables, drilldown, expanded hierarchies)
  • all Components which are available in the application - all component properties will be saved as they look like at the time of save

In both cases, you can look at the content of BIBOK file contained in the local repository under "/_TECHNICAL_CONTENT/" subfolder. You will see a flat list of components and data sources with something called "INIT_PARAMETERS" which represent the state of the application on runtime. Those init parameters are corresponding to the properties visible in designer and you will find there your all values.

Part 2. Saved Parameters / Properties

The saved parameters are containing all available properties - this includes also scripts and content of the components (e.g. list of items in a drop down). This should explain why when you save a bookmark and then add it to some drop down in the application - after load of the same bookmark the dropdown is again empty. It was empty at the time of save and this was saved in the bookmark.

Part 3. Load of Bookmarks


Why obsolete bookmarks are not listed?

Technically, it is possible to load also obsolete bookmarks - but, taking into count the facts described in "Part 2", load of such bookmark would reset all changed done in the application to the point of time as the bookmark was saved. Based on this fact, listing of old bookmarks for the end user is not supported.


Loading of an Obsolete Bookmark

The opening of a bookmark via URL (using the shared URL) is loading the bookmark. There are some defined rules how such bookmarks are applied on the application:

  • (1) new components (only positioned on the root container level) in the application are not touched - those will be not affected by loaded bookmark
    • eg. you introduce a component "BUTTON_NEW" on the root container level - it will be available even a bookmark is loaded on the application
    • components which are introduced as children of some panels will be not visible as the parent container does not know about them
  • (2) changed properties of existing component will be overwritten by the loaded content from bookmark
    • eg. you change a property TEXT for component "BUTTON_OLD" to "New Text" from "Old Text" - the changed text property will become "Old Text" as this was the value in the bookmark.
  • (3) deletion of component in the application affected by bookmark - loaded bookmark will create the components again even those were deleted in the application.

Part 4. What to do after load of bookmark to propagate correctly the bookmark-dropdown?

After loading a bookmark you have to re-create the dropdown by calling explicitly the scripts to get again the actual list of bookmarks and passing the content to the dropdown. Here you will probably face also the issue with selection of first item - this is currently known issue in drop down which has an event "onSelect", but technically this is an "onChange" event - therefore currently selected index cannot be selected again as it does not change.

Part 5. Global Script Variables & Local Script Variables


Why local script variables are lost in script after loading the bookmark?

Load of the bookmark needs to reset the application. For this reason the script will be interrupted and re-run with next statement after the bookmark is loaded. All local variables are not defined anymore and cannot be used in the sequence of calls after bookmark load.

What happen to global script variables ?

The global script variables are behaving same as the content of any other component - saved in a bookmark and restored by bookmark load to the value which was saved in the bookmark. This means, you cannot use them to pass some values when loading a bookmark.

Part 6. Startup script and bookmarks.

The script "onStartup()" will be NOT executed when loading a standard bookmark. Only the fragment bookmark does execute the scripts when loaded.


Part 7. Ideas on how to handle th bookmarks workflows.

Solution for dropdown issue. Always add first an entry "- select a bookmark - " to assure that the user can select the "first" entry which is located technically on index 2. (discussed in thread Bookmarks and Selection in Dropdown).

Passing Values between bookmark loads.

If you ask yourself how to pass values which you know before loading a bookmark - and you want to use after you loaded a bookmark. As of today you need to save them as a bookmark as well, but not using the bookmark itself, but playing with the title of the bookmark. E.g. save a bookmark giving it a title starting with "|" character - then you can pass some name=values separating by ";" character. after loading the real bookmark, you can again loop on all available bookmarks and re-parse the title of the one starting with "|" character. of course you have immediately to delete it. I will try to make an example of this soon - it is not the best implementation, but the current possibility.


Example: Passing Values on Bookmark Load by Additional Bookmark.

In the attached application (works on 1.3 release, you have to create a folder in local repository "INSIDE_BOOKMARK" and copy the file "content.biapp.txt" into the fodler, renaming to content.biapp) you can find some code which helps you to pass values on bookmark load. It is not a perfect implementation, as this is saving a temporary bookmark (which costs also performance) and reuses the bookmark title to build up a name=value pairs which need to be parsed after load. This implementation is only (as far I know) one possible way to pass values through bookmark load.



Functions.

  • Load All Bookmarks - simple script to reload actual bookmarks and pass into the dropdown box (with additional entry to overcome the selection problem in dropdown box )
  • Personalize Application / Delete Personalization - you can check here what happen when you personalize application and load a bookmark
  • Save Bookmark - taking the text as bookmark description
  • List Of Bookmarks - dropdown with all available bookmarks, only for choice - no event "onSelect"
  • Load Bookmark - Simple case, just load a bookmark
  • Load Bookmark - Use the additional workflow to load a bookmark, but keep some actual values as they are now
  • the input field is just to see what bookmark has loaded - you can put here any text which will help you to recognize the bookmark content, there is no "magic" on this field, it is loaded as it was in bookmark
  • the input field for global script variable (MY_VARIABLE) which can be applied (Apply) and reloaded into the text field (Reload - use this after bookmark is loaded to check actual value). The sctipt variable is then visible in the text with current content "- empty -"
  • the input filed for any content which should be kept on bookmark load - when using the "transfer" variant of load.
  • REUSABLE_SCRIPTS (an hidden panel with 2 checkboxes)

         

    • the first one is a function which is executed before a bookmark is loaded - it is responsible for collecting the values and save of the temporary bookmark
    • the first one is loading the temporary bookmark and reading its title to parse the values and distribute to corresponding areas (global variables or properties of components)

Part 7. Future Direction

Development unit is trying to improve the bookmarking functionality by introduction of an "embedded" bookmarks - which will allow to save only an embedded part of an application. By this handling of the bookmarks will be easier - as the load would not reset completely the application, but would reload only a part of it (e.g. some container). Using that, the saved content can be separated from the scripts and would allow more flexibility in bookmarking.

Questions?

In case of any questions, please post - I will update the content.

41 Comments
martin_chambers
Participant
0 Kudos

Hi Karol,

Thanks a lot for this inside account of how bookmarks work. It explains a lot about the unfortunate way in which the dropdown component and bookmarks mix.

I'm very interested in your suggestion about passing values from before to after a bookmark load. You mention that local variables get deleted due to the application reset.

I haven't really thought this through but would using a global variable help here? Could one assign a value to a global variable before the bookmark load and access it afterwards?

Cheers,

Martin

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Martin,

the global script variables are part of the bookmark, you cannot use them to pass the values. for passing the "current" values when loading the bookmark, please check updated "Part 6" and the attachment - I hope this is understandable.

Regards, Karol

martin_chambers
Participant
0 Kudos

Hi Karol,

Thanks for your quick reply. I think I will try implementing your suggestion soon.

Regards,

Martin

Former Member
0 Kudos

Hi Karol,

Is there a way to show exactly which bookmark was being loaded and display as a status mesage.

I have tried STATUS_INFO.setText(name + " Bookmark loaded");

where name can be a hidden input field copied from the selected bookmark prior to loading. But it always show the first bookmark on the bookmark list is loaded no matter which one was actually chosen in the list. Do you know how to achieve that?

Thank you.

Best regards,

Zabrina

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Zabrina,

this is the point

Example: Passing Values on Bookmark Load by Additional Bookmark.

before you trigger load of the bookmark (and at this time you know what is the ID, what is the description), the only way is to save additional bookmark temporary with this information and then after the original bookmark is loaded, reload the temporary bookmark where all the information is in the title.

in 1.4 there should be a better way to handle bookmarks.

Regards, Karol

Former Member
0 Kudos

Great Karol, I will test out your example.

I also have an issue regarding the first item of the dropdown box (bookmark in this case) never get selected since BOOKMARK_DROPDOWN.getSelectedValue() always return null when the first item is chosen. I saw that you have a work around using dummy first item. Will this issue be resolved in 1.4?

Also, there is an issue with those obsolete bookmarks still being stored in the BOOKMARK directory and not able to clean up by itself. Every time when we run the application, information about those obsolete bookmarks are coming up but without knowing what id is what, it is not possible to tell which one should be deleted manually. Will this issue be resolved in 1.4?

Thank you again.

Best regards,

Zabrina

Former Member
0 Kudos

Hi Karol,

I have tested the Bookmarking Functionality on the BI platform, and these are the scenarios I've tested it for.

I saved a couple of Bookmarks and I did the following changes,

Deleted a component,

Renamed a component,

Resized a component,

Changed a Text in Textbox,

Renamed a Datasource,

Remapped a different Query to a DataSource.

In all these conditions, the bookmarks were Reset everytime.

Is this the way it is suppose to work?

Our clients are very much interested in Bookmarks, but they have asked for the stability of the Bookmarks across the above conditions.

Regards,

Fazith Ali Z

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Fazith,

you should wait on 1.4 release (GA planned for November) - there will be improvement on this - new type of bookmarks, which will not get obsolete after changes in the application.

Karol

Former Member
0 Kudos

Hello,

Let me refresh this thread.

I have 1.4 installed locally and I am still not able display as a status message chosen bookmark.

The same as in earlier thread, it always shows the first bookmark on the bookmark list.

Do you know some workaround for that.

Thank you.

Best regards,

Marcin

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Marcin,

do I understand you correctly?

you want to figure out which bookmark was loaded and push this into status message?

Karol

Former Member
0 Kudos

Hi Karol,

Yes that is my intention.

When I use this

TEXT_1.setText(DROPDOWN_1.getSelectedText() + " Bookmark loaded");

I always receive the first bookmark form bookmark list..

Thanks,

Marcin

Former Member
0 Kudos

Hi Karol,

Have you got any idea why it works like this ?

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

when you load the bookmark, the dropdown_1 is containing the list as it was on the saving time point. you would need to use the workaround I have posted in How to restore custom filters after bookmark load.

in your case, before you load the bookmark selected by the user, you would need to save another "temporary" bookmark with the information which one was selected by the user, eg. place the ID in the title. after the real bookmark is loaded, you need again to loop on existing bookmarks, find the id and select the item in the drop down via script.

not sure if this short explanation will bring you to the point, if not - can you attach some easy version of your app (w/o any data sources) - I will put the scripts there.

Karol

Former Member
0 Kudos

Hello Karol,

here is my bookmark report.

I have tried to create temp bookmark but results are still the same.

Thanks

MustafaBensan
SAP Champion
SAP Champion
0 Kudos

Hi Karol,

In your feedback for the Realtime Chat Component blog post you made a comment that got my attention: "Alternative to it would be using the bookmark functionality (as those can be shared between users and updated from both sides)".  Does this mean that if one user creates, saves and shares a bookmark with another user and that other user modifies the application (like a filter setting or other property) and then saves the bookmark, the bookmark settings of the original author are overwritten too?

Thanks,

Mustafa.

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Mustafa,

there is no real locking mechanism in bookmarking, those are pushed into data base on save, not checking if something has been updated in the meantime - so the answer is - it will overwrite. But, I am quite sure, with some code in the app (like saving some additional "lock" bookmark) we could make also chat via bookmarking - independent of the current question if this makes really sense ;-).

in full solution, you would need to have some timer component which would need to check existence of special temporary bookmark which simulates a lock situation, and if your app can lock the real bookmark, then you can reload + update the bookmark. the content would be probably some text content.

as of now, it is theoretical - especially with the question is bookmarking is the right function for chats. but i like from time to time to evaluate "waht would be possible"...

Karol

former_member201696
Participant
0 Kudos

Hi Karol,

thanks a lot for the detail of Bookmark.

If i have create a URL Standard Bookmark and then I execute this URL Bookmark. Did the Bookmark execute always all scripts for "On Startup"?

BR

Gabriel

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Gabriel,

The script "onStartup()" will be NOT executed when loading a standard bookmark. Only the fragment bookmark does execute the scripts when loaded.

updated in Part 6. Startup script and bookmarks.

Karol

former_member201696
Participant
0 Kudos

Hi Karol,

Thanks for the answer.

I have for all Design Studio Report created a footer, with technical Information (Execution date, User). Did you have a idea where can I paste this script?

BR

Gabriel

arpansgupta
Explorer
0 Kudos

Hi Karol,

Do the bookmarks I saved are session specific? I tried to add the book marks to a listbox it is going fine. BUT if I refresh the application and try to read the bookmarks(which I saved in last session) by using "getAllBookmarks()" then the listbox shows nothing.

Can u pl suggest.

Regards,

Arpan

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi,

Bookmarks are not session specific. The content is stored in the system.

Which deployment are you using?

Which bookmark type are you using?

Karol

arpansgupta
Explorer
0 Kudos

I was too expecting the same that bookmarks must not be session specific. Because I was able to view then in CMC.

I am on SAP BOBI 5.1 Service pack 7.

Using standard bookmarks. Saving the bookmarks by name and reading and assigning them to a dropdown / Listbox. Once I refresh the application and try to populate the Listbox with "getAllBookmarks()" , it retrieves nothing..

Arpan

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

be aware that the standard bookmarks are declared as obsolete as soon you change the application. the bookmarks stay stil in database, but will be not listed in the method getAllBookmarks(). you can nevertheless call them by URL.

so, try to save a bookmark and use the load w/o any changes in the application (I mean changes in the designer).

Karol

arpansgupta
Explorer
0 Kudos

I have a simple requirement. In my application, I have saved, say 4 bookmarks.A SAVE button saves the bookmarks and add it to a dropdown. ( Saving, Loading, Reading everything is working fine with getAllBookmarks()).

Now if I open the application again, I have a button to fill the dropdown with all those 4 bookmarks. BUT it is adding nothing.Logically, If I open the application again it should point to those 4 saved bookmarks.

By URL, I need to pass "id", If I can not read them in an array by getAllBookmarks() or getAllBookmarksbyFolder() How I will able to refer the id of all 4 bookmarks in a for-loop.

Arpan

michael_simon4
Participant
0 Kudos

Hi Arpan,

could you post your coding? We were doing the same like you before using the fragment bookmarks. It worked without problems (as long as the bookmarks were not invalidated):

var bookmarks = Bookmark.getAllBookmarks();

LBO_BOOKMARK.removeAllItems();

bookmarks.forEach(function(element, index) {

  LBO_BOOKMARK.addItem(element.id, element.text);

});

Best regards,

Michael

arpansgupta
Explorer
0 Kudos

Hi Michael,

I am using the most basic example as published on SAP official product tutorial page.

I have following components

Input field , Dropdown, Save Button, Load Button, Load-All Button

                                             Coding for Save Button

var name = INPUTFIELD_1.getValue();

Bookmark.saveBookmark(name);

var bookmarks = Bookmark.getAllBookmarks();

bookmarks.forEach(function(element, index) {

 

  DROPDOWN_1.addItem(element.name, element.text);

});

INPUTFIELD_1.setValue("");

                                             Coding for Load Button.

Bookmark.loadBookmark(DROPDOWN_1.getSelectedValue());

var bookmarks = Bookmark.getAllBookmarks();

DROPDOWN_1.removeAllItems();

bookmarks.forEach(function(element, index) {

  DROPDOWN_1.addItem(element.name, element.text);

});

INPUTFIELD_1.setValue("");

                                             Coding for Load-All Button.

var bookmarks = Bookmark.getAllBookmarks();

DROPDOWN_1.removeAllItems();

bookmarks.forEach(function(element, index) {

  DROPDOWN_1.addItem(element.name, element.text);

});

If I am on the same session then all code works fine. BUT if I re-opens the application, The Load-All buttons does not add anything to dropdown. I am not able to view / read the saved bookmarks.

This is something very strange because I am able to see the bookmarks in CMC.

Arpan

michael_simon4
Participant
0 Kudos

Hi Arpan,

I rebuild your example - it works fine for me. I saved some bookmarks, reopened the application and as soon as I press the Load-All Button, the Dropdown box gets populated with my prior saved bookmarks.

When you look at the column "Application" in the CMC bookmark administration - is it empty or filled? When the column is empty the Bookmark is somehow invalidated.

If I were you I would create an example Application with fragment bookmarks (which work better than the Standard Bookmarks) and test again and/or create a OSS message.

Best regards,

Michael

arpansgupta
Explorer
0 Kudos

Hi Michael,

I started to recreate everything afresh, now it seems working. BUT If I am editing the application and re-saving it, the OLD bookmarks are not getting loaded.

Is there any approach to correct this.?

Also Is there any backup strategy / method for bookmarks, Say in case I upgrade any patch or something. I have a doubt that bookmarks will be un-readable.

-Arpan

michael_simon4
Participant
0 Kudos

Hi Arpan,

the described bahavior for standard bookmarks is by design - as soon as you save the  application anew, the standard booknarks become invalid and won't be listed by the Bookmark.getAllBookmarks() function any more (if you know the Bookmark URL, they could still be executed). This is the reason, why you should use the fragmental bookmarks- they won't get invalidated by changes in the application (but the bookmarks still contain the old version of the application when loaded.

With both bookmark types we are not really happy at all - but as far as I know SAP plans to implement a more flexible bookmarking option end of this year.

Best regards,

Michael

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

adding to Michael...

you need to be careful with bookmarks. when you use Fragment Bookmarks, you can control what you save - a Container. Then all properties of this area (and all components in this container) will be stored. You can technically change the content, but when you make it - the load of bookmark will revert your changes for this container. If you are not careful, this can lead to inconsistences.

I probably have written it in the blogs,so here very short.

* avoid changes in this area

* use global scripts and link them from events in the components - then you can still adjust the scripts as saved will be only link between the component and globals script

* do not make big changes in this area (removing, inserting new and moving components) - this is critical for compatibility.

I would recommend using fragment bookmarks and make a plan what you need to save - and save only the minimum which you need.

Karol

MustafaBensan
SAP Champion
SAP Champion
0 Kudos

Hi Karol,

I have a question for clarification:  if the fragment container includes an SDK component and an upgraded version of the component is installed, how are existing fragment bookmarks affected by this?

Thanks,

Mustafa.

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

there is no difference in the bookmarks between standard and sdk components.

* all have a bunch of properties

* bookmark saves the properties as they are in the system

-> problems will come if in upgrade case the SDK component will be heavy refactored (properties would change names).

example of the content for gauge component would be:

<bi:component name="GAUGE_1" type="org_scn_community_basics_Gauge">

  <bi:property name="LEFT_MARGIN" value="37"/>

  <bi:property name="TOP_MARGIN" value="76"/>

  <bi:property name="WIDTH" value="auto"/>

  <bi:property name="RIGHT_MARGIN" value="237"/>

  <bi:property name="HEIGHT" value="auto"/>

  <bi:property name="BOTTOM_MARGIN" value="70"/>

  <bi:property name="title" value=""/>

  <bi:property name="endValue" value="60"/>

  <bi:property name="startValue" value="40"/>

  <bi:property name="indicatorValue" value="30"/>

  <bi:property name="showedValue" value="50%"/>

  <bi:property name="startSecondColor" value="45"/>

  <bi:property name="startThirdColor" value="55"/>

  </bi:component>

as you see, there is no link to a version, so everyone who codes SDK - do not change parameters in your components as this will break bookmarks. you can place new parameters, those will be filled in by default values when not in bookmark.

Karol

MustafaBensan
SAP Champion
SAP Champion
0 Kudos

Hi Karol,

I have recently been doing some testing as a follow-up to this discussion related to bookmark updates and the concept of locking.  Something I have noticed is that when a user loads a Portable Fragment Bookmark created by another user, modifies the bookmark content and then re-saves the same bookmark in order to update it, instead of updating the bookmark, Design Studio creates a new bookmark.  It appears that it is not possible to update a Portable Fragment Bookmark created by another user, even if you have full rights to the folder containing the bookmark.  I thought the intent of Portable Fragment Bookmarks was to allow sharing across multiple users for both read and update operations of those bookmarks.

I was wondering if this behaviour where a new Portable Fragment Bookmark is created when attempting to update a bookmark originally created by  by another user is by design?

Thanks,

Mustafa.

Karol-K
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Mustafa,

this behavior is not known by me, I would expect that overwrite is overwriting 😉 I need to ask the experts on this topic - I will point them to your question.

Karol

MustafaBensan
SAP Champion
SAP Champion
0 Kudos

Hi Karol,

Thanks very much for looking into this.  I have tested multiple times and the overwrite only seems to work for the creator of the original portable fragment bookmark, so if you can find out anything about this it would be a big help.

Regards,

Mustafa.

Former Member
0 Kudos

Hi Karol,

is there a way to see bookmarks from portal or CMC.

I have lost the link for the bookmark.

 

Thanks,

Sujith.

Karol-K
Product and Topic Expert
Product and Topic Expert

Hi,

 

on BIP there is an admin UI for bookmarks, see documentation

https://websmp203.sap-ag.de/~sapidb/012002523100012464482016E/ds_16SP03_admin_bip_en.pdf

 

-> 6.1.

 

In NW there is an ABAP table which is listing all bookmarks, you can view it with SE37. If you need it, I have to check the technical name.

 

Karol

michael_simon4
Participant
0 Kudos

Hi Karol,

 

is it possible in the admin UI on the BIP to start/load the bookmark or determine the bookmark URL? I didn't found a way to get the bookmark URL from the BIP admin UI.

 

Best regards,

Michael

former_member484788
Discoverer
0 Kudos
Hallo ich möchte eine View mithilfe des Navigationsstatuses vom Bookmark erstellen um diese dann weiter an den Brodcaster (se80-->RSRD_SETTING) zu übermitteln. Sowie ich das verstanden habe kann man über se37 die Bookmarks ausslesen. Kannst du mir den technischen Namen nenne?

Vielen Dank

Mansur
0 Kudos
Hi Karol, Hi Mustafa,

 

I am new to Design Studio (DS 1.6SP04 ) and have many doubts to clear.

 

But now only this one, i am saving the bookmark using FRAGMENTBOOKMARK.

var id = Bookmark.FragmentBookmark.saveBookmark(LAYOUT_CONTAINER, bookmark_title,"","",GENERIC_BOOKMARK_IDENTIFIER);

however once the bookmark is executed, none of the event are triggered and executed. one of the blog mentioned that OnStartup() will execute but it seems its not.

Do we have any event for bookmark which gets executed before the bookmark is loaded so there we can customize the stuff ???

Thanks in Advance.

 
Former Member
0 Kudos
Hi Karol,

 

Apparently in the newer versions of DS the bookmark do not save the global variables any more. we use scripts to repopulate the values from the DS states in the Open bookmark function, and it works. But now we have users sharing bookmarks (via URL) and in this case the system do not pass trough our Open bookmark function... so the question is: how to detect the app is opened from a shared URL bookmark ?

Any idea will be welcome 🙂