Skip to Content

Dear all,

Have you been wondering when you would finally be able to put comments on your Design Studio dashboards in a decent and tremendously customizable way for free? Well, that day is today!

In the following sections I will showcase my new component ConVista EasyComment which is published open-source on GitHub, talk about the backend integration, comment saving & loading and the overall commentary architecture involved.

What do you get?

Obviously to put some comments you need a place where you can do that. I decided to use a WYSIWYG (What You See Is What You Get) HTML editor. There are a couple of libraries out there providing editors like that. My choice was CKEditor because of a well documented API, a suitable developer license and the ability to Paste from MS Word. You could also look into tinymce and Froala just to mention a few more.

You can extend gracefully by implementing your own editor plugins by the way.

/wp-content/uploads/2016/03/comment1_905837.png

     Fig.1 Demo dashboard

My SDK component ConVista EasyComment comes with lots of built in functionality like spell-checking, multi-language support, the ability to add images, an option to adjust the reading direction and many more. These features are provided by the CKEditor library out of the box.

The save button (icon on the bottom right of the toolbars) exposes its functionality to the DesignStudio SDK component event On Save Button Clicked. You can also extract/modify HTML content on the editor using the scripting methods getHTMLString and setHTMLString.

You can customize the toolbars to be shown through the component property Toolbar Settings. I used the new SDK 1.6 feature that allows to put complex objects on the contribution file for that. That way DesignStudio creates a table like input window:

/wp-content/uploads/2016/03/comment7_905838.png

     Fig 2 Properties


You can activate/deactivate the toolbars one by one. For the Document section which contains the save button you can decide even on item level (but you can’t hide the save button ;-). Let’s put false on every item except for Editing and see what we get.

/wp-content/uploads/2016/03/comment8_905839.png

     Fig 3 Reduced editor toolbar view


If you need more fine grained customization you will need to get back to me or adjust the coding on the SDK component yourself. Now let’s jump to the fun part.

On Saving and Loading

At first I am going to tell you about the frontend part which is covered by the EasyComment component and how to model a data structure to store our DesignStudio comments before actually moving over to the backend part to show you possible starting points to implement your individual solution.

To be able to actually persist and successfully load a comment for a specific DesignStudio object you need to identify the object itself and maybe its filter state. For static content this very easy and straightforward. We could just take the technical name of the targeted object as key and save our HTML-string along with it on a table on our backend. For dynamic content like charts with arbitrary complex filter possibilities this can be a very complicated task.

Some of the commercial DesignStudio commentary components approach this topic on the SAP backend by evaluating for example BEx query state and learn the object state from there. That way they can identify the right comment to load or with what key to store it. To get this done for all of the possible DesignStudio data sources like BEx queries, BW cubes, Universes, Custom SDK data sources, CSV files and HANA views is quite a lengthy task for an ABAP developer.

Don’t make this harder as it needs to be!

My approach is not going to cover all kinds of complex scenarios but it will be as easy as it gets and get the job done for many cases. At first I make the assumption that it is sufficient to store only a limited number of characteristics values to successfully identify the breakdown of a value on a component like a DesignStudio chart, crosstab, KPI-View or Scorecard. Let’s differentiate two cases:

  • Static only content like DesignStudio texts or objects themselves and
  • dynamic content like data breakdowns and key figures on Crosstabs or Charts.

All of the static content can be covered by its technical object name and the dashboard they are on for example:

Key Fields

HTML Content

DashboardID

Object Technical Name

MYDASH_1

Demo_dashboard

<h1>This a comment for a dashboard itself</h1>

MYDASH_1

SOME_QUERY

<i>This is a general comment on a query</i>

MYDASH_2

TEXT_TITLE

<h2><b>This is a comment for a standard text</b></h2>

     Table 1 Static objects comment saving


Now on the dynamic stuff. From my experience many cases that need comments for key figure release processes for example, there is only a limited number of filter values involved. Often you can get away with an accounting basis, an accounting entity and a key date (single date, date ranges and etc.).

Key Fields

HTML Content

DashboardID

Obj tech. Name

Acc. Basis


Acc. Entity

Key date

MYDASH_1

QUERY1

GAAP

COMP1

10.03.2016

<p>some html content</p>

MYDASH_1

HANA_CALC_VIEW

GAAP

COMP1

01.01.2016

<p>year end forecasts are looking good</p>

MYDASH_1

CHART_1

COMP2

10.03.2016

<p> Please check the spike! </p>

     Table 2 Dynamic objects comment saving


How do you provide this data to the WebService?

DesignStudio offers lots of scripting methods that already provide what we need:

  • DashboardID: Accessible through APPLICATION.getInfo().name


  • Object technical Name: All SAP data sources (except SDK data sources) provide the method getInfo() which gives you access to the underlying meta data. The technical name is part of it.
  • Accounting Basis, Accounting Entity and Key date: Data sources offer methods to retrieve key-value pairs for given dimensions and DesignStudio components like the Dimension Filter give the user the ability to filter certain values on demand. When working with filter variables you can for example use the following script to learn their current setting influenced by the user input during runtime:

    

     var vars = DS_1.getVariables();

     vars.forEach(function(element, index) {

       if(element.inputEnabled){

         DS_1.getVariableValueExt(element.name);

    }

});


You could save the values for later usage with the ConVista EasyComment using the SCN community SDK component ARRAY.

Now that we learned how to retrieve keys to identify our data sets, we are ready to send some HTML-strings to the backend. Exciting, isn’t it!? Let me give you a simplified example.

As I already told you before, there is an event provided by the EasyComment component which gets triggered when you click the save button on the editor. Here is a script from a demo application:

             //cache busting

var ccid = APPLICATION.getTickCount();

//retrieve an accounting entity

var bukrs = DROPDOWN_1.getSelectedValue();

//set http request method

      me.setHttpMethod(“POST”);

      me.setServerUrl(

     “http://<sap backend>:<port>/sap/bc/<WebService Endpoint>?bukrs=”+bukrs+“&ccid=”+ccid

);

//Actually Trigger the save

      me.saveHTMLOnServer();


This DesignStudio script sets up the HTTP parameters and sends a POST request to the server. The method saveHTMLOnServer internally retrieves the current HTML-string from the editor on execution. If everything on the backend went good, you just saved your first comment!

To retrieve it again you need some more scripting and an approach how to expose that functionality. Usually people go for selection events in some sort of way. Let’s check out an example with a Dropdown.

/wp-content/uploads/2016/03/comment2_905879.png

     Fig 4 Editor full cycle interaction


Once the user selects an entity from the dropdown, the components On Select method fires. In there I put the following scripting:

            //Get the currently selected entity

var bukrs = me.getSelectedValue();

//Cache busting

var ccid = APPLICATION.getTickCount();

COMMENT_1.setServerUrl(

     “http://<sap backend>:<port>/sap/bc/<WebService Endpoint>?bukrs=”+bukrs+“&ccid=”+ccid

);

//Set HTTP request method

COMMENT_1.setHttpMethod(“GET”);

//Actually trigger the load

COMMENT_1.loadHTMLFromServer();

The above script loads the saved comment into the editor according to the selection on the dropdown. If you need to more than just an accounting entity to select your comment, like in my example, you will have to enrich this scripting slightly (e.g. put some more URL parameters etc.).

In light of above you can easily imagine how to extend this approach to serve your specific needs without aiming for a general solution for every possible scenario and putting hundreds of hours. Now let’s have a look at a possible SAP backend WebService class implementation to take care of the saving and loading of our precious HTML-strings.

Integration of the SDK component with a server

In order to be able to save the HTML content you add to the editor, I implemented the DesignStudio SDK component to be ready to integrate with a RESTful Web Service. I am using the standard JavaScript object XMLHttpRequest to manage the communication from the browser to the backend. Of course Cross-Origin Resource Sharing (CORS) problems might apply at this point if you are hosting your dashboard on a different server than the backend. To overcome that browser security problem you have to setup your backend code to supply two HTTP headers on the HTTP response:

Access-Control-Allow-Origin: true

Access-Control-AllowCredentials: true

I will show an easy ABAP example below. At first you have to provide an ABAP class which will serve as the handler for the WebService communication.

  • ABAP class setup

Create a standard class and put it on your local objects or a development package.

     /wp-content/uploads/2016/03/comment3_905880.png

Put the following two interfaces to provide your custom implementation for the SAP standard HTTP interfaces.

     /wp-content/uploads/2016/03/comment4_905881.png

Once you save, the class structure will immediately be generated and look something like this:

     /wp-content/uploads/2016/03/comment5png_905882.png

In order to put your custom WebService behavior you will have to implement the method HANDLE_REQUEST. Before that there is one more step. We need to register this class with an ICF node. To do so, call transaction SICF and create a new node under default_host > sap > bc.

     /wp-content/uploads/2016/03/comment6png_905891.png

Put your class under the handler list and save. Go back and activate the ICF node. Hit test to learn your WebService endpoint URL and check if the registration worked. You will need that URL for the DesignStudio scripting and also for easy testing purposes with your browser.

Note that every user induced URL call on a browser is basically an HTTP GET request.

  • HTTP CORS setup and HANDLE_REQUEST implementation

Now I am going to show you the essential ABAP code to get started. You need to be able to retrieve URL parameters from the HTTP requests, put CORS headers on your response and send the response to the client. This is done using SAP standard interface methods:

constants:
lc_header_mimetype_name      
type string value ‘Content-Type’,
lc_header_mimetype_value_html
type string value ‘text/HTML; charset=utf-8’,
lc_header_aca_origin         
type string value ‘Access-Control-Allow-Origin’,
lc_header_aca_credentials    
type string value ‘Access-Control-Allow-Credentials’,

lc_true                       type string value ‘true’.

data: _request_method    type string,
lt_inputparams       
type tihttpnvp,
ls_inputparams       
like line of lt_inputparams,
ld_bukrs             
type i,
ld_html_string       
type string,
ld_cors_callee       
type string,
ld_request_payload   
type string.

  “Get passed parameters
call method server->request->get_form_fields
changing
fields = lt_inputparams.
“Get passed payload, HTML data
call method server->request->get_cdata
receiving
data = ld_request_payload.
“ CORS setup
ld_cors_callee
= http://<server hosting DesignStudio>:<port>’.

  “Translate Input Parameters to Uppercase
loop at lt_inputparams assigning <ls_inputparams>.

translate: <ls_inputparams>name  to upper case.
case <ls_inputparams>name.
when ‘BUKRS’.
ld_bukrs
= <ls_inputparams>value.
endcase.
endloop.

_request_method = server->request->get_header_field( name = ‘~request_method’ ).
“Determine if method is get or post.
if _request_method = ‘GET’.
“set the response mimetype to HTML
server
->response->set_header_field
( name  = lc_header_mimetype_name
value = lc_header_mimetype_value_html ).
“Set CORS access control to avoid browser policy restrictions
server
->response->set_header_field
( name = lc_header_aca_origin
value = ld_cors_callee ).
server
->response->set_header_field
( name = lc_header_aca_credentials
value = lc_true ).


“Do your table loading implementation here and assign to ld_html_string


“set the cdata response to the text
server
->response->set_cdata( data = ld_html_string ).

elseif _request_method = ‘POST’ .

“set the response mimetype to HTML
server
->response->set_header_field
( name  = lc_header_mimetype_name
value = lc_header_mimetype_value_html ).

“Set CORS access control to avoid browser policy restrictions
server
->response->set_header_field( name = lc_header_aca_origin
value = ld_cors_callee).
server
->response->set_header_field
( name = lc_header_aca_credentials
value = lc_true ).
“Do your table saving implementation here and send given html back to have a graceful answer since the SDK component is “assigning back the data coming from the server to the editor “right away
“set the cdata response to the text
server
->response->set_cdata( data = ld_request_payload ).

endif.

Make sure you send the send HTML-string back on POST requests because the EasyComment component relies on setting the HTML response to the editor as assurance that the saving worked. You could write a message here if something is wrong too. Further error handling is not implemented yet.

  • Tables

To get you started have a look at the table examples in the previous section. Put the table coding at the sections highlighted in red above on the ABAP code.

Once all of that is done, put an example value on your table and make a browser GET request using the URL we remembered before. If that works, your WebService is ready to serve and you can start integrating with EasyComment. Now start saving some comments even with images attached! ūüôā

/wp-content/uploads/2016/03/comment9_905892.png

     Fig 5 EasyComponent editor with image on comment


Commentary Lifecycle (Commentary Solution Architecture)

To sum up the technical part I would like to provide a high level view on what I showed you in detail before.

EasyComment-Architecture.jpg

     Fig 6 Commentary Lifecycle Deployment View


In DesignStudio you need to put some logic to trigger the RESTful WebService and think about how to make that accessible to the user during runtime. On the backend you need to provide the communication endpoint for the RESTful WebService to deal with the HTTP requests. In my case that was SAP BW but the implementation is by no means limited to that. You could call any other system.

EasyComment-Sequence.jpg

     Fig 7 Commentary Lifecycle Implementation View

This sequence diagram visualizes the function calls on the involved software instances. DesignStudio scripting and events trigger internal methods on the EasyComment SDK component. As a result the component communicates with the backend to actually save and load HTML content. The callbacks deliver the content to the frontend.

What’s next?

As a next step I want to implement, what I call “Live-Commentary”. This means you no longer need to save your html content actively by hitting the save button but just start typing and save immediately. This will be achieved using WebSockets which enable full-duplex communication. User-Authorization at a side, this will allow users to edit comments even in parallel, seeing what their colleague does right away. Some of you might be familiar with that behavior from google docs or similar applications. I will keep you posted as development progresses.

Final Words

You are now able to enrich your DesignStudio dashboards with shiny comments up to a complexity that suits your needs. The frontend technology to get you started is already setup and implemented. The only open task is to decide how to store your HTML content. I have shown you a possible starting point to get this done quick and easy. Now find yourself an ABAP developer or roll up your own sleeves and have fun commenting.

You can get the component by installing the ConVista SDK components package which is available on GitHub:

ConVista-ds-sdk-visualizations by MartinPankraz

As always feel free to leave comments and ask lots of follow up questions.

Yours

Martin

To report this post you need to login first.

31 Comments

You must be Logged on to comment or reply to a post.

  1. Andreas Hufnagel

    Hi Martin,

    thank you for sharing! this is really helpfull.

    one very slight comment on ABAP code:

    insert line

    field-symbols: <ls_inputparams> type ihttpnvp.

    data definition of ls_inputparams is obsolete.

    otherwise it´s plug and play.

    design studio test app + sicf service on Netweaver was set up in ~30 min on sandbox systems (without persisting data).

    thank you,

    Andreas

    (0) 
    1. Martin Pankraz Post author

      Hi Amardip,

       

      So far you get only the current value on clicking the save button on the commentary component. Do you have a use case for retrieving it beforehand?

       

      Kind regards

      Martin

      (0) 
      1. Suraj Grewal

        Hi Martin ,

        I am also unable to fetch the content which is written by user . I have attached the screenshot of the code .Please let me know in case I need to do any modifications .

        (0) 
        1. Martin Pankraz Post author

          Hi Suraj,

           

          Like I said before, the html text is only updated on saving it. In the meantime you cannot retrieve it using that script function. What would be the use case of reading the value without saving it?

           

          Kind regards

          Martin

          (0) 
          1. Suraj Grewal

            Hi Martin,

            Thanks for the reply.The code is written itself on the click of Save button .So upon clicking the Save button it should fetch the comments from clipboard .If possible I will try to share the code snippet along with screenshot .

            Regards,

            Suraj Grewal

            (0) 
            1. Martin Pankraz Post author

              Hi Suraj,

               

              You are right. In the scenario you describe the internal html string is not update. The component only sends the correct string to the backend. I just fixed that. You can update the component from my GitHub repository as usual.

               

              Kind regards

              Martin

              (0) 
              1. Suraj Grewal

                 

                Hi Martin ,

                Thanks a lot for your quick replies and quick fix .I will update the component from Github and will let you know in case of any concerns.

                 

                Regards,

                Suraj Grewal

                (0) 
  2. Suraj Grewal

    Hi Martin ,

    Thanks a lot for the blog . There are few points in which I need your help .We have the requirement where we have to add comment for every cell of the report just like the Excel functionality.Our query is a cell based query .So for storing comment for every cell we need to define a key from which we can identify different cells .So for these we are reading the UID of selections for getting the exact location where user in trying to insert the comment in query as our query has more than 200 cells.Below is the code for fetching the UID.

    var a=CROSSTAB_1.getSelection();

    a.forEach(function(value, key) {

    APPLICATION.alert(key);

    value.forEach(function(element, index) {

    APPLICATION.alert(element);

    });

    });

    With the above code I will be getting 4 UIDs as my query is built on 2 structures so 1 alert will show the UID of structure and then UID of selection inside that structure .Same will continue for the second structure and second selection .

    Just like excel I have added 2 custom option in context menu i.e. Show comment and insert comment .The issue which I am facing is it will read UID only at the time of clicking on insert comment .I cannot fetch values at the time of clicking on save button which is embedded on the comment component.

    So either I need to create some global variable which I can access from JS of save button or I need to call webservice when I click on insert button then by ABAP code I need to update a Z table which will hold the current user logged in and the combination of UIDs . Once it will get updated I will get the comment component infront of me .Now I will write any content and will click on save button .

     

    Now my concern is once save button is clicked how I can identify which UID I need to pick from Z table and corresponding to that ID only I need to place the comment?

    Do I need to call the webservice 3 times for posting the comment ?

    1.While fetching the UIDs from cell and store it in a Z table , POST method has to be called.

    2.Once we will click on save button firstly we need to use GET method to read the UID from table

    How we will read the¬†UID from Z Table as we don’t¬†have UID stored anywhere in Design Studio when we¬†click on save button ?

    then call POST method to post the comment in Z table .

     

    It will be very helpful to me . ūüôā

    Kind Regards,

    Suraj Grewal

     

     

    (0) 
    1. Martin Pankraz Post author

      Hi Suraj,

       

      Since you need to wait for the user to write a comment for a particular cell, you definitely need to remember the ids somewhere. I would suggest to keep it on the client for performance and maintenance reasons. You could either use global script variables or use the communities JSON object to store those values during runtime. That way there is only server call for actually storing the comment.

       

      Kind regards

      Martin

      (0) 
      1. Suraj Grewal

         

        Hi Martin,

        Good day!!

        Thanks for the reply . The approach which I am trying to follow is

        1. I will create 1 Textbox and will capture the UIDs as I am getting the UIDs with the above code .This operation will be performed when I will click on insert comment in context menu. We will set the visibility of textbox to false .

        2.In the second step I will write the comment in comment box and will click on save button .Upon clicking on save button I will read the text of the textbox and will pass as a parameter in the URL in order to update the table .

        Please let me know in case it will be a better option or not ?

         

        Regards,

        Suraj Grewal

        (0) 
        1. Martin Pankraz Post author

          Hi Suraj,

           

          Your approach is as sound as the options I suggested. I’d say this is only a question of application design philosophy. If you favor the functionality of the text box over the other components, go for it.

           

          Kind regards

          Martin

          (1) 
  3. Amardip Selmokar

    Hi Martin,

    I am trying to set the text on text box using getHTMLString() method,but it is not working.

    Kindly have look over following script :

    On save button clicked : OVERVIEW.setText(COMMENT_1.getHTMLString());

    (0) 
    1. Martin Pankraz Post author

       

      Hi Amardip,

      Please see my comments above. There was a small bug regarding the method getHTMLString and you need to make sure to only call it after you hit save on the commentary box (for example on the on Save button event).

       

      You can update the component from my GitHub repository as usual.

       

      Kind regards

      Martin

      (0) 
  4. Amardip Selmokar

    Hi Martin,

    Yes,I have written the script OVERVIEW.setText(COMMENT_1.getHTMLString()); on save button event.

    When I type something in commentary box and hit on save,it pass null values and shows blank “Overview” text.

    Can you please provide your contact details,so that we can discus further.Thanks in advance.

     

     

     

    (0) 
    1. Martin Pankraz Post author

      Hi Amardip,

       

      You can click on my profile and follow me. That way you are able to write private messages.

       

      Did you make sure the SDK component is updated? I just tested again without any problems.

       

      Kind regards

      Martin

      (0) 
  5. Suraj Grewal

    Hi Amardip,

    I was also facing the same issue but after updating the SDK now I am getting Strings in HTML tags .

    HI Martin,

    I have started following you but I am unable to find you in chat room ūüôĀ

    Thanks & Regards,

    Suraj Grewal

    (0) 
  6. Suraj Grewal

    Hi Martin ,

    Could you please suggest some idea where I can differentiate between the NW portal links as in the GET and POST both methods we need to put the URL .The initial part of the URL will be hardcoded .

    ‚Äúhttp://<sap backend>:<port>/sap/bc/<WebService Endpoint>?bukrs=‚ÄĚ+bukrs+‚Äú&ccid=‚ÄĚ+ccid.

     

    Since normally we have 3 boxes , Dev, Quality and production so how to distinguish it in Design Studio level ?

    Thanks & Regards,

    Suraj Grewal

     

    (0) 
    1. Martin Pankraz Post author

      Hi Suraj,

       

      you can use the component’s method setServerUrl in combination with global script variables containing the server addresses. To determine on which system you are you can for example do the following:

       

      var cuid = DS_1.getInfo().system;

      if(cuid === g_sys_dev){

       

      }else if (cuid === g_sys_qual)…

       

      The CUID’s of your systems should be different. I have seen environments however where that was not the case.

       

      Let me know if that solves your problem.

       

      Kind regards

      Martin

      (0) 
  7. Ramakrishnan Venkatesan

    Hi Martin,

    I have followed your Blog, after updating latest version, now I can save comments successfully in backend system.

    But, I have a requirement to display existing comments initially.

    for that, I have created a button and written below code in “On click”

    var BUKRS = INPUTFIELD_1.getValue();
    var ccid = APPLICATION.getTickCount();
    COMMENT_1.setServerUrl(“<Webservice endpoint>?sap-client=100?sap-bukrs=”+BUKRS+”&ccid=”+ccid+”?”);
    COMMENT_1.setHttpMethod(“GET”);
    COMMENT_1.loadHTMLFromServer();

    My backend system has entries for the combination.

    Backend code:


    SPAN {
    font-family: “Courier New”;
    font-size: 10pt;
    color: #000000;
    background: #FFFFFF;
    }
    .L0S33 {
    color: #4DA619;
    }
    .L0S52 {
    color: #0000FF;
    }
    .L0S55 {
    color: #800080;
    }
    ¬†IF¬†_request_method¬†=¬†‘GET’ .

    ld_cors_callee = “*”.

     


    SPAN {
    font-family: “Courier New”;
    font-size: 10pt;
    color: #000000;
    background: #FFFFFF;
    }
    .L0S31 {
    font-style: italic;
    color: #808080;
    }
    .L0S33 {
    color: #4DA619;
    }
    .L0S52 {
    color: #0000FF;
    }
    .L0S55 {
    color: #800080;
    }
    .L0S70 {
    color: #808080;
    }
    ¬†¬†¬†¬†“set¬†the¬†response¬†mimetype¬†to¬†html
    server->response->set_header_field( name  = lc_header_mimetype_name
    value = lc_header_mimetype_value_html ).

    “set¬†cors¬†access¬†control¬†to¬†avoid¬†browser¬†policy¬†restrictions
    server->response->set_header_field( name = lc_header_aca_origin
    value = ld_cors_callee ).

    server->response->set_header_field( name = lc_header_aca_credentials
    value = lc_true ).
    ld_html_string¬†=¬†‘testing’.
    server->response->set_cdata( data = ld_html_string ).

    Endif.

    I don’t get comments displayed in commentary box.¬† Could ¬†you advise what¬†is missing in my code.

    Thanks.

    Regards,

    Venkatesan

    (0) 
    1. Martin Pankraz Post author

      Hi  Venkatesan,

       

      First of all, did you check on abap if you receive a call at all? You can use external breakpoints for example. Judging from the code snippet, the URL you are calling is wrong. Check the question marks. There should only be one at the end of the url. The query string itself should not contain any. Change your URL like so:

       

      COMMENT_1.setServerUrl(‚Äú<Webservice endpoint>?sap-client=100&sap-bukrs=‚ÄĚ+BUKRS+‚ÄĚ&ccid=‚ÄĚ+ccid);

       

      Let me know.

       

      Kind regards

      Martin

      (0) 
      1. Ramakrishnan Venkatesan

        Hi Martin,

        Thanks for your reply.  I have tried with external breakpoints. I can get into debugging. All statements working correctly.

        I have simplified code in class,¬†just to display “Testing” irrespective of any input passed.

        If I execute it in browser, I can¬†get¬†response¬†in browser and¬†it is correctly displaying¬†“testng”. I have also tried it with SOAPUI, it does get response as per code.

        It doesn’t work only with our component. I have tried by executing it locally and also by deploying it in BI Platform it is not working to display.

        To tell you more, BO and BW are in two different servers.  Cross domain policy is correctly set. And also We already having working Xcelcius dashboard with webservice connection.

        For this REST API, I am suspecting in CORS area and Proxy setting. I am not very familiar with CORS.  Is there any setting need to be done for Proxy related.

         

        Sample Code:

        _request_method = server->request->get_header_field( name = ‘~request_method’ ).

        “determine if method is get or post.
        IF _request_method = ‘GET’ OR _request_method = ‘get’.
        “set the response mimetype to html
        server->response->set_header_field( name  = lc_header_mimetype_name
        value = lc_header_mimetype_value_html ).

        “set cors access control to avoid browser policy restrictions
        server->response->set_header_field( name = lc_header_aca_origin
        value = ld_cors_callee ).

        server->response->set_header_field( name = lc_header_aca_credentials
        value = lc_true ).
        ld_html_string = ‘testing’.
        server->response->set_cdata( data = ld_html_string ).
        ENDIF

         

         

        (0) 
        1. Martin Pankraz Post author

          Hi Venkatesan,

           

          obviously communication is correct if you can save comments, catch backend breakpoints and display values afterwards. You should always check the browser’s developer console to troubleshoot (hit f12, navigate to console tab and refresh your page to see possible errors). Let me know what you find there.

           

          You are still trying to load the comment from a button click, right? Did you also check the URL for the initial load like I asked?

           

          Kind regards

          Martin

          (0) 
  8. Suraj Grewal

    Hi Martin ,

    Good Day!!!

    We have installed the component in the SAP Netweaver platform as well but we are unable to see the comment component . Could you please suggest what might be the issue ?

    Regards,

    Suraj Grewal

    (0) 
  9. Carsten Schild

    Hi Martin,

    i’ve implemented your solution(thanks for sharing) and everything works fine except of one thing:

    The cors implementation only works when i manualy make a request to the webservice(abap) through webbrowser(only then the cors headers are transferred).

    When i start it from the Design Studio App(portal) directly, without making the manual request – i get a cross site error. Shouldn’t the cors implemantation be somehow¬†on the Portal side, or did i miss something? I’m quite new to the cors topic so any¬†help would be appreciated.

    (0) 
    1. Martin Pankraz Post author

      Hi Carsten,

       

      Calling the web service URL From the webbrowser will always work because this cannot be a cross domain problem by design ūüėČ

      Please check with an external breakpoint on abap if the web service is reached. Secondly check if the http response contains the http headers. Lastly check the cross site domain error message. Maybe you can already derive from the message if you missed the protocol, out in a wrong domain or forgot the port.¬†Keep in mind that you allow the java side to call abap. One last hint: If you run local mode in DesignStudio and you didn’t fix your port you get a different port on every execution, which will get you into trouble with the cors implementation.

       

      The cors implementation is on my abap example.

       

      Kind regards

      Martin

      (0) 
      1. Carsten Schild

        Hi Martin,

         

        thanks for your answer.

        I’ve set a breakpoint – the service isn’t called. In the error console i see the url to the webservice. I can open it manually –¬†the service ist called and then the cors headers are transferred.

        How can the cors headers be set from the abap part, when the application runs on the portal and the browser prohibits callling the abap url from within java script?

        It seems i’m just missing a tiny piece to make it work…

        Carsten

        (0) 
        1. Martin Pankraz Post author

           

          Hi Carsten,

          that is the core of CORS. You tell the browser to accept responses from domains other than your own. So DesignStudio running on your portal may receive calls from abap. It should look like the following:

          Make sure to use an external breakpoint. From your description it seems there is a problem even calling your webservice class. Make sure you have the inital call correct.

           

          To circumvent CORS entirely you would need a web dispatcher that routes request to the corresponding machines (Java and ABAP) but exposing both under the same domain to the browser satisfying the CORS restriction.

           

          Kind regards

          Martin

           

          (0) 

Leave a Reply