Skip to Content
Technical Articles
Author's profile photo Hans Verreydt

Using Fiori as frontend for SAP EWM RF ITS screens – Part 2

Hi All,

In this part, I’ll describe how we used the Fundamental Library as basic for a Fiori frontend for our SAP RF ITS screens.

In my previous blog post, I’ll described how I used SAPUI5 as frontend for our RF ITS screens. Part 1

———————————————————————————————————————

 

In my previous blog post, I explained how I changed the ITS templates & generators from SAP to use SAPUI5 as frontend technology for our ITS screens.

I got a lot of good response from the community but also, some people were concerned about the performance and the response time, which I explained at the end of my previous blog post.

Nico Deleener from our SAP Partner (Flexso), gave me the idea to work with the Fiori Fundamental Library.

So, what is the Fiori Fundamental Library:

An open source and community driven project to provide a consistent user interface across web applications.

we used the “Fundamental Library Styles” because we only want to change our frontend.
When we used SAPUI5 as frontend, we needed to load every time, for each template the entire sap.m.* library, which takes some time.
When focussing only on the frontend, and created Fiori apps with only CSS files, we don’t have to load all those libraries.

So, we had to give it a try, to see if the Fundamental Library Styles was the solution!

All the steps are almost the same as described in part 1. So, I’ll not go in every detail again in this part.

Step 1: Create a new style

For our Fundamental style, I created again a new class, based on the standard generation class.

 

  • Create a new record in table “W3GENSTYLES”.
    • Style: ZMOBFIORI
    • ABAP Class: ZCL_ITS_GEN_FIORI_MOBILE
    • Info: For Mobile Responsive Design Style (Fiori)

 

Step 2: Create a new ITS service

  • Create Service: ZITSGENFIORI
    • For this case, I did a copy of my SAPUI5 version, but you can easily start from the default one. (ITSGENMOBILE4)

 

Step 3: Adapt the templates with Fiori Fundamental tags.

 

  • HTML Templates
    • HEADER/BEGIN
    <head>

        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">


    `if ( ~itsmobileDeviceInclude != "" )
        include(~service=~current_service, ~language="", ~theme=~theme, ~name=~itsmobileDeviceInclude & ".html");
     end;`

 

    • HEADER/CSS
` if ( ~itsmobileCssInclude != "" ) <!-- customer include from gui settings -->`
        <link rel="stylesheet" href="`mimeURL(~service=~current_service, ~theme=~theme, ~language="", ~name=~itsmobileCssInclude & ".css")`" type="text/css" `sh()`>
` else <!-- default include from itsmobile --> `
        <link rel="stylesheet" href="`mimeURL(~service="itsmobile", ~theme=99, ~language="", ~name="styles/all/mobile.css")`" type="text/css" `sh()`>
` end;`

<link href="//unpkg.com/fundamental-styles@latest/dist/fundamental-styles.css" rel="stylesheet">
    • HEADER/SCRIPT
      • Remains the same as the default one. If you added already the Script for the SAPUI5 libraries, please remove those here.
    • MAIN_SCREEN/BEGIN
<!-- main screen begin -->
<div width="100%">`
    if ( ~itsmobileCuaInclude != "" ) <!-- customers cua area -->
       include(~service=~current_service, ~language="", ~theme=~theme, ~name=~itsmobileCuaInclude & ".html");
    elseif ( ~itsmobileNoCuaInclude != "1" && ~itsmobileNoCuaInclude != "X" ) <!-- default cua area -->

    end;`

</div>

<main class="fd-page fd-page--home fd-page--list">
  <header>
    <div class="fd-bar fd-bar--home-page-xl fd-bar--header">
      <div class="fd-bar__middle">
        <div class="fd-bar__element">
            <b>Biobest SAP</b>
        </div>
      </div>
    </div>
  </header>
  <div class="fd-page__content--xl" role="region">
    <div>
        <br>

 

    • MAIN_SCREEN/END
    </div>
  </div>
  <footer>
    <div class="fd-bar fd-bar--home-page-xl fd-bar--footer">
      <div class="fd-bar__right">
        <div class="fd-bar__element">
          <button class="fd-button fd-button--positive" onclick="setOkCode ('/00')">Enter</button>
        </div>
      </div>
    </div>
  </footer>
</main>
<!-- main screen end -->

 

    • ELEMENTS/BUTTON
`if ( ( 'GEN_NAME'[GEN_LOOP_LINE].exists == "X" ) && ( 'GEN_NAME'[GEN_LOOP_LINE].visible == "X" ) )
    `<button class="fd-button" style="width: 100%" onclick="setOkCode ('`'GEN_NAME'[GEN_LOOP_LINE].okcode`')">`strmask('GEN_NAME'[GEN_LOOP_LINE].label) `</button>`
    `<br><br>`
end;`

 

    • ELEMENTS/INPUT_OUTPUT/NORMAL
`if ( 'GEN_NAME'[GEN_LOOP_LINE].exists == "X" )
    if ( 'GEN_NAME'[GEN_LOOP_LINE].mode == "multiline" )
        `<textarea `
         `class="MobileEditMultiline`class_ext('GEN_NAME', GEN_LOOP_LINE); class("GEN_NAME", GEN_LOOP_LINE)`" `
         if ( 'GEN_NAME'[GEN_LOOP_LINE].disabled == "X" ) `disabled="disabled" `end;
         if ( 'GEN_NAME'[GEN_LOOP_LINE].readonly == "X" ) `readonly="readonly" `end;
         if ( 'GEN_NAME'[GEN_LOOP_LINE].okcode != "" )
             `onchange="setOkCode('`'GEN_NAME'[GEN_LOOP_LINE].okcode`');return false;" `
         end;
         `style="`width("GEN_COLS", "GEN_WIDTH"); style("GEN_NAME", GEN_LOOP_LINE)`" `
         `rows="`'GEN_NAME'[GEN_LOOP_LINE].rows`" cols="GEN_COLS" `
         `onfocus="setFocusField('`'GEN_NAME'[GEN_LOOP_LINE].name`');" `
         `onblur="leaveFocusField('`'GEN_NAME'[GEN_LOOP_LINE].name`');" `
         `name="`'GEN_NAME'[GEN_LOOP_LINE].name`">`'GEN_NAME'[GEN_LOOP_LINE]`</textarea>`
    else
        if ( 'GEN_NAME'[GEN_LOOP_LINE].disabled == "X" )
            if ( 'GEN_NAME'[GEN_LOOP_LINE].visible != "X" )
                 `<input class="fd-input" type="hidden" `
            elseif ( 'GEN_NAME'[GEN_LOOP_LINE].type == "Password" )
                `<input class="fd-input" type="password" readonly="readonly" tabindex="-1" `
                `style="`width("GEN_COLS", "GEN_WIDTH"); style("GEN_NAME", GEN_LOOP_LINE)`" `
                if ( 'GEN_NAME'[GEN_LOOP_LINE].highlighted == "X" )
                    `class="MobilePasswordHighlightedDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                else;
                    `class="MobilePasswordDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                end;
            elseif ( 'GEN_NAME'[GEN_LOOP_LINE].inputrequired == "X" )
                `<input class="fd-input" type="text" readonly="readonly" tabindex="-1" `
                `style="`width("GEN_COLS", "GEN_WIDTH"); align("GEN_NAME", GEN_LOOP_LINE); style("GEN_NAME", GEN_LOOP_LINE)`" `
                if ( 'GEN_NAME'[GEN_LOOP_LINE].highlighted == "X" )
                    `class="MobileEditRequiredHighlightedDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                else;
                    `class="MobileEditRequiredDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                end;
            else
                `<input class="fd-input" type="text" readonly="readonly" tabindex="-1" `
                `style="`width("GEN_COLS", "GEN_WIDTH"); align("GEN_NAME", GEN_LOOP_LINE); style("GEN_NAME", GEN_LOOP_LINE)`" `
                if ( 'GEN_NAME'[GEN_LOOP_LINE].highlighted == "X" )
                    `class="MobileEditHighlightedDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                else;
                    `class="MobileEditDisabled `class("GEN_NAME", GEN_LOOP_LINE)`" `
                end;
            end;
            `onfocus="focusField('`'GEN_NAME'[GEN_LOOP_LINE].name`');" `
            `name="`'GEN_NAME'[GEN_LOOP_LINE].name`" `
            if ( ( 'GEN_NAME'[GEN_LOOP_LINE].inputrequired == "X" ) && ( 'GEN_NAME'[GEN_LOOP_LINE] == "?" ) )
                 `value="" `
            else
                 `value="`strmaskext('GEN_NAME'[GEN_LOOP_LINE], 1)`" `
            end;
            `size="`'GEN_NAME'[GEN_LOOP_LINE].width`" maxlength="`'GEN_NAME'[GEN_LOOP_LINE].maxinputsize`"
            `sh()`>`
        else                                     <!-- not disabled -->
            icon( "GEN_NAME", GEN_LOOP_LINE );
            if ( 'GEN_NAME'[GEN_LOOP_LINE].visible != "X" )
                `<input class="fd-input" type="hidden" `
            elseif ( 'GEN_NAME'[GEN_LOOP_LINE].type == "Password" )
                `<input class="fd-input" type="password" width="100%" `
            elseif ( 'GEN_NAME'[GEN_LOOP_LINE].inputrequired == "X" )
                `<input class="fd-input" type="text" width="100%" `
                if ( 'GEN_NAME'[GEN_LOOP_LINE].highlighted == "X" )
                    `class="MobileEditRequiredHighlighted `class("GEN_NAME", GEN_LOOP_LINE)`" `
                else
                    `class="MobileEditRequired `class("GEN_NAME", GEN_LOOP_LINE)`" `
                end;
            else
                `<input class="fd-input" type="text" width="100%" `
                if ( 'GEN_NAME'[GEN_LOOP_LINE].highlighted == "X" )
                    `class="MobileEditHighlighted `class("GEN_NAME", GEN_LOOP_LINE)`" `
                else
                    `class="MobileEdit `class("GEN_NAME", GEN_LOOP_LINE)`" `
                end;
            end;
            if ( 'GEN_NAME'[GEN_LOOP_LINE].okcode != "" )
                `onchange="setOkCode('`'GEN_NAME'[GEN_LOOP_LINE].okcode`');return false;" `
            end;
            `onfocus="setFocusField('`'GEN_NAME'[GEN_LOOP_LINE].name`');" `
            `onblur="leaveFocusField('`'GEN_NAME'[GEN_LOOP_LINE].name`');" `
            `name="`'GEN_NAME'[GEN_LOOP_LINE].name`" `
            if ( ~currdynpro.speechenabled != "" ) `id="`'GEN_NAME'[GEN_LOOP_LINE].name`" `end;
            if ( ( 'GEN_NAME'[GEN_LOOP_LINE].inputrequired == "X" ) && ( 'GEN_NAME'[GEN_LOOP_LINE] == "?" ) )
                `value="" `
            else
                `value="`strmaskext('GEN_NAME'[GEN_LOOP_LINE], 1)`" `
            end;
            `maxlength="`'GEN_NAME'[GEN_LOOP_LINE].maxinputsize`"`
            sh()`><br>`
        end;
    end;
else

end;`

 

    • ELEMENTS/INPUT_OUTPUT/OUTPUT_ONLY
`if ( ( 'GEN_NAME'[GEN_LOOP_LINE].exists == "X" ) && ( 'GEN_NAME'[GEN_LOOP_LINE].visible == "X" ) )
    `<input class="fd-input" type="text" readonly="readonly" value="`strmask('GEN_NAME'[GEN_LOOP_LINE])`" >
    <br>`
end;`

 

Save and publish your ITS service!

 

Step 4: Generate your screens!

Make sure that you have your own Z-ITS service (in this case ZEWM_ITS_FIORI) and make sure that this also exists in SICF.

 

Result:

 

 

 

I did a small test with SAP Cloud ALM, where we have a clear overview which resources are called. This way, you clearly can see how much extra time there’s needed when using SAPUI5.

Comparing the SAP Standard ITS service with the new version with the Fundamental library for performance gave me the same result, which made me very happy! 🙂

 

 

So at the end, I made different kind of versions for our ITS services.

Let me give a small recap of this:

I started working with the standard SAP ITS service because our EWM RF screens use this. As we’re working with multiple different kind of mobile devices, I was looking for a solution were all the screens are the same on all devices. So, we needed responsive screens!

Note: As we’re working with mobile devices without any extra hardware buttons, we also activated the extra buttons in the HTML templates!

SAP Standard ITS:

 

SAP ITS with JQuery Mobile:

I came across a presentation from ASUG 2013 which explained using JQuery Mobile for ITS. So this was a good starting point for me!

 

SAP ITS with SAPUI5:

In my previous blog post, I’ll described how I used SAPUI5. See my previous blog post.

 

SAP ITS with Fundamental Library:

Conclusion

I my opinion, the Fundamental Libraries are currently the best option when you want to change the ITS frontend to Fiori.

We have our Fiori look & feel, we have our responsive design, and we have the same performance as standard SAP ITS screens! What else do you want more!

We’re still testing this case, but from our first testing results, this is a keeper! 🙂

 

I hope you really enjoyed this reading, and you will find this blog post helpful in your projects.

Please feel free to reach out if you have problems when trying this!

 

Hans Verreydt
SAP Application Specialist – Biobest Group NV

Assigned Tags

      26 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Marco Beier
      Marco Beier

      As with the first one, I really liked this post! Sharing these "PoCs" gives a nice Idea to what is or can be possible/viable solutions. Well written and I appreciate that, like in the first part, you even include the coding/template parts. 🎷🐛👏

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Thanks Marco!

      Author's profile photo Martin Prokop
      Martin Prokop

      A BIG "like" to you, Hans, for your courage and enthusiasm!

      The SAP approach in matter of RF UI is rather disappointing. In 2021 was introduced new “EWM_MOBGUI” service in the transaction SICF, bringing the old dynpros directly to RF screen... It enables you to modify screens with Screen Personas, but you would have to redesign it screen by screen. Not mentioning the probable data traffic overhead, which is added in this case and slows the operation further down.

      Best Regards

      Martin

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Thx!

      Author's profile photo Marnix Van Achter
      Marnix Van Achter

      Hi Hans,

      I have implemented both your solutions (UI5 & Fiori) and we do see a difference in the length of the input fields.

      In the UI5 version they are 'normal' length but in the Fiori version the input fields are very long. Even verification fields which are normally 1 position fields are filling the full line.

      Any idea what might be wrong here ?

      Best regards,

      Marnix Van Achter

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Thanks Marnix!

      In the Fiori version, I changed also the input fields with css for the Fiori version.

      But in this case, I added the width=100% when the fields needed to be scanned. Ofcoure you van tweak this the way you want ;-).

      Cheers!

      Hans

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Just check the "ELEMENTS/INPUT_OUTPUT/NORMAL" section. Here you can change this...

      Author's profile photo Vishal Kumar
      Vishal Kumar

      Hello Hans

      Thanks for such a informative blog !

      Can you help me , how to identify the HTML tags where we need to place / change the above code ?

       

      Regards

       

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hi Vishal,

      What do you mean?

      Which HTML tags do you want to change?

      You need to create a new ITS service (for example: ZITSGENFIORI) with Topic 99 and HTML templates. In these templates (based on the original one), you need to change your code

      Regards,
      Hans

      Author's profile photo Vishal Kumar
      Vishal Kumar

      Hi Hans

      Thank you for answering.

      But I am not able to Generated the screens as I am getting error :

      Template%20Generation%20Filed

      Template Generation Filed

      Can you please help me with this. I can see Content / Element / Begin has no code.

       

      Thanks  & Regards

      Vishal Kumar

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Did you create the ITS service "ZITSGENFIORI" as a copy from ITSGENMOBILE4?

      if so, the templates (with code) should be available in this ITS service, where you can change it, like you want.

      if not, please check if you created the correct ITS service.

      Regards,
      Hans

      Author's profile photo Vishal Kumar
      Vishal Kumar

      Hello Hans

       

      Now, I did everything as per the blog. But somehow the buttons are still not visible on the RF screen.

      Can you share what parameters needs to be maintained in the service in the SICF node ?

       

      Thanks again .

       

      Regards

      Vishal Kumar

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      The Buttons (Back, List, ...) are not specific in the code. These are EWM settings (instead of the function codes (F7, ...).

      if you change these settings, you'll see the buttons also in the standard RF test transaction.

       

      Regards,
      Hans

      Author's profile photo Vishal Kumar
      Vishal Kumar

      Ok . Now I understood with the HTML template I could change the screen design but for button I need to do it via EWM configuration .

      But somehow for me even the Screen Design has not changed.

      Do I need to add this HTML template in the parameters of the Service configuration in SICF ?

       

      Regards

      Vishal Kumar

       

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hi Vishal,

       

      The SICF configuration is standard, like other RF applications. For this, you can check the EWM cookbook for example.

      Which screen design doesn't change?

      Regards,
      Hans

      Author's profile photo Marnix Van Achter
      Marnix Van Achter

      Hans,

       

      Is it possible to add for instance a BACK button next to the ENTER button at the bottom instead of adding the F7 button to all the RF screens ?

      If possible that probably needs to be done in MAIN_SCREEN/END but I have no idea if this would screw up the solution, and also I am not an expert so I have no idea how to do that either 🙂

      Extra comment a few hours later...

      I think that this is a stupid question anyway because behind the F7 in the RF config there are different func.codes (BACK, BACKF, UPDBACK, FCMENU, ...)

       

      Best regards,

      Marnix

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hey Marnix,

       

      The ENTER button has a fixed action / OK Code, which I can use in the "onPress" method.

      The BACK button, and other buttons are dynamic, and also these actions are dynamic. If we can set a fixed action for that BACK button, than this is possible, oterwise... 🙂

       

      Regards,
      Hans

      Author's profile photo Tom Franckaert
      Tom Franckaert

      Great blog!

      Is it possible to debug the html creation at runtime?

      How are all the if's handled in the generated html templates?

      Regards,

      Tom.

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hi Tom,

      Good question...  Didn't do that yet, but maybe this can help?
      https://blogs.sap.com/2009/07/30/its-debugging-techniques/

      Regards,
      Hans

      Author's profile photo Bala Manchikalapati
      Bala Manchikalapati

      Can anyone help me in answering my issue ( Error Loading the Page ) from Test service or URL.

      web page is showing : "Please Wait" and when I select INSPECT

      I am getting this Error in console:

      Uncaught SyntaxError: Unexpected token '<'
      zitsgensapui5?sap-client=100:146

      Uncaught ReferenceError: its_setdomain is not defined
      at zitsgensapui5?sap-client=100:146:32
      its_utils.js:1

      Uncaught SyntaxError: Unexpected token '<'
      its_frameset.js:1

      Uncaught SyntaxError: Unexpected token '<'
      sap_secu.js:1

      Uncaught SyntaxError: Unexpected token '<'
      zitsgensapui5?sap-client=100:331

      Uncaught TypeError: self.its_frame_root.Initialize is not a function
      at initialize (zitsgensapui5?sap-client=100:331:25)
      at onload (zitsgensapui5?sap-client=100:330:2)

       

      <script type="text/javascript">its_setdomain();</script>

      Uncaught ReferenceError: its_setdomain is not defined

      Author's profile photo Martin Gajdos
      Martin Gajdos

      Hi Hans,

      Very valuable blog which brings me an overview into RF UI of SAP EWM.

      Is there however a usual way how to monitor a response time for RF UI, UI5, SAP UI/FIORI (Screen/Process type) ?

      Thanks,

      Martin

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Thx!

      For the response time, we're using SAP Cloud ALM for this. Not sure if there are any other solutions for that...

      Regards,
      Hans

      Author's profile photo Marnix Van Achter
      Marnix Van Achter

      Hi Hans,

      Another question for you... We do have some users that are 'complaining' about the font size.Is it possible to make the font bigger somehow ???

      I have no idea where to start looking for a solution for this.

      Best regards,

      Marnix

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hi Marnix,

      You can add some css in the header section, where you define your font size and add those to your elements were this is needed.

      Regards,
      Hans

      Author's profile photo Bala Manchikalapati
      Bala Manchikalapati

      Hi Hans,

      Thanks for your great blog and its really worth implementing this from Fiori thro ITS.

      I implemented the same and getting the below Error when running with URL ( Test service ) from SICF.

      http://xxxxx.xxxxx.xxxx.888987/sap/bc/gui/sap/its/zwm/zitsgensapui5

      web page is showing : "Please Wait" and when I select INSPECT

      I am getting this Error in console:

      Uncaught SyntaxError: Unexpected token '<'
      zitsgensapui5?sap-client=100:146

      Uncaught ReferenceError: its_setdomain is not defined
      at zitsgensapui5?sap-client=100:146:32
      its_utils.js:1

      Uncaught SyntaxError: Unexpected token '<'
      its_frameset.js:1

      Uncaught SyntaxError: Unexpected token '<'
      sap_secu.js:1

      Uncaught SyntaxError: Unexpected token '<'
      zitsgensapui5?sap-client=100:331

      Uncaught TypeError: self.its_frame_root.Initialize is not a function
      at initialize (zitsgensapui5?sap-client=100:331:25)
      at onload (zitsgensapui5?sap-client=100:330:2)

       

      <script type="text/javascript">its_setdomain();</script>

      Uncaught ReferenceError: its_setdomain is not defined

       

       

      Can you please help me where it went wrong for this error?

       

      Thank in advance.

      Bala M

      Author's profile photo Hans Verreydt
      Hans Verreydt
      Blog Post Author

      Hi Bala,

       

      Sorry for the late response.

      Did you check your code for the "<"? it seems that this is a bit wrong? Maybe a sign to much?

       

      Regards,
      Hans