abap2UI5

Comparison Pattern

The pattern allows users to select multiple items from an sap.m.Table and display information about them in a structured way - all items are displayed next to each other for easy comparison, based on their specifics.

Z2UI5_CL_SMPC_APP_012

Controls sap.m UI5 1.71

The facts

Repository
abap2UI5/samples-controls
Class
Z2UI5_CL_SMPC_APP_012
Source file
z2ui5_cl_smpc_app_012.clas.abap ↗
Library
sap.m
UI5 entity
sap.m.ComparisonPattern
Demo kit sample
sap.m.sample.ComparisonPattern
SAP's own sample
running at sdk.openui5.org ↗
Minimum UI5
1.71 — the floor abap2UI5 holds its samples to
In the playground
runs in the browser, with no system and nothing installed

Keywords: comparisonpattern, comparison, pattern, sap.m, compare, items, side, app, table, toolbar, title, toolbarspacer

Controls it builds

Read out of the builder chain by the abap2UI5 linter, not from the category this sample is filed under — which is what makes “which samples build one of these” a question the catalogue can answer at all.

Libraries

Run it here

The sample running, in this page — the app on its own, with no editor over it. Switch to Playground with this code

Nothing is installed and nothing is sent anywhere: the ABAP is compiled to JavaScript in this browser and runs against abap2UI5 itself.

The ABAP

z2ui5_cl_smpc_app_012.clas.abap — 1152 lines Read it on GitHub ↗
" @keywords comparisonpattern comparison pattern sap.m compare items side app table toolbar title toolbarspacer
" @summary The pattern allows users to select multiple items from an sap.m.Table and display information about them in a structured way - all items are displayed next to each other for easy comparison, based on their specifics.
" @origin sap.m.sample.ComparisonPattern - https://sdk.openui5.org/entity/sap.m.ComparisonPattern/sample/sap.m.sample.ComparisonPattern (status: checked - verified in a running system)
CLASS z2ui5_cl_smpc_app_012 DEFINITION PUBLIC.

  PUBLIC SECTION.
    INTERFACES z2ui5_if_app.

    TYPES:
      BEGIN OF ty_s_product,
        productid     TYPE string,
        category      TYPE string,
        maincategory  TYPE string,
        taxtarifcode  TYPE string,
        suppliername  TYPE string,
        weightmeasure TYPE string,
        weightunit    TYPE string,
        description   TYPE string,
        name          TYPE string,
        dateofsale    TYPE string,
        productpicurl TYPE string,
        status        TYPE string,
        quantity      TYPE string,
        uom           TYPE string,
        currencycode  TYPE string,
        price         TYPE p LENGTH 8 DECIMALS 2,
        width         TYPE string,
        depth         TYPE string,
        height        TYPE string,
        dimunit       TYPE string,
        selected      TYPE abap_bool,
      END OF ty_s_product.
    TYPES ty_t_product TYPE STANDARD TABLE OF ty_s_product WITH EMPTY KEY.
    TYPES:
      BEGIN OF ty_s_comp_value,
        text        TYPE string,
        description TYPE string,
        visible     TYPE abap_bool,
      END OF ty_s_comp_value.
    TYPES ty_t_comp_value TYPE STANDARD TABLE OF ty_s_comp_value WITH EMPTY KEY.
    TYPES:
      BEGIN OF ty_s_comp_prop,
        key    TYPE string,
        values TYPE ty_t_comp_value,
      END OF ty_s_comp_prop.
    TYPES ty_t_comp_prop TYPE STANDARD TABLE OF ty_s_comp_prop WITH EMPTY KEY.

    DATA t_products      TYPE ty_t_product.
    DATA t_comp_products TYPE ty_t_product.
    DATA t_comp_props    TYPE ty_t_comp_prop.
    DATA pagescount      TYPE i.
    DATA isdesktop       TYPE abap_bool.
    DATA compare_text    TYPE string.
    DATA compare_visible TYPE abap_bool.

  PROTECTED SECTION.
    TYPES:
      BEGIN OF ty_s_key,
        key   TYPE string,
        field TYPE string,
      END OF ty_s_key.
    TYPES ty_t_key TYPE STANDARD TABLE OF ty_s_key WITH EMPTY KEY.

    DATA client      TYPE REF TO z2ui5_if_client.
    DATA first_item  TYPE i.
    DATA check_page2 TYPE abap_bool.

    METHODS view_display.
    METHODS on_event.
    METHODS comparison_build.
    METHODS comparison_props_build.
    METHODS model_init.

  PRIVATE SECTION.
ENDCLASS.


CLASS z2ui5_cl_smpc_app_012 IMPLEMENTATION.

  METHOD z2ui5_if_app~main.

    me->client = client.
    IF client->check_on_init( ).
      model_init( ).
      view_display( ).
    ELSEIF client->check_on_navigated( ).
      view_display( ).
    ELSEIF client->check_on_event( ).
      on_event( ).
    ENDIF.

  ENDMETHOD.


  METHOD view_display.

    " the original's router matches #/Page2 directly (a deep link, a reload):
    " the live hash rides in s_config-hash on every request, so a render whose
    " hash carries it enters the comparison - with nothing selected it stays
    " empty, exactly the original's cold #/Page2
    IF check_page2 = abap_false AND contains( val = client->get( )-s_config-hash sub = `/Page2` ).
      comparison_build( ).
      check_page2 = abap_true.
    ENDIF.

    DATA(view) = z2ui5_cl_ui5_view_builder=>factory( ).

    " the sample's App/Main/Comparison views merged into one view: the App hosts both pages, the router's navTo becomes a NavContainer `to` frontend action
    view->ele( n = `View` ns = `mvc`
        )->a( n = `height`     v = `100%`
        )->a( n = `xmlns`      v = `sap.m`
        )->a( n = `xmlns:mvc`  v = `sap.ui.core.mvc`
        )->a( n = `xmlns:f`    v = `sap.f`
        )->a( n = `xmlns:card` v = `sap.f.cards`
        )->a( n = `xmlns:l`    v = `sap.ui.layout`

        )->ele( `App`
            )->a( n = `id` v = `rootControl`

            )->ele( `Page`
                )->a( n = `title` v = `First Page`

                )->ele( `content`
                    )->ele( `Table`
                        )->a( n = `id`              v = `idProductsTable`
                        )->a( n = `selectionChange` v = client->_event( `SELECTION` )
                        )->a( n = `mode`            v = `MultiSelect`
                        )->a( n = `inset`           v = `false`
                        )->a( n = `items`           v = |\{ path: '{ client->_bind_path( t_products ) }', sorter: \{ path: 'NAME' \} \}|

                        )->ele( `headerToolbar`
                            )->ele( `Toolbar`
                                )->tag( `Title`
                                    )->a( n = `text`  v = `Laptops`
                                    )->a( n = `level` v = `H2`
                                )->tag( `ToolbarSpacer`
                                " the controller's setText/setVisible on selection replaced by bound model properties
                                )->tag( `Button`
                                    )->a( n = `id`      v = `compareBtn`
                                    )->a( n = `text`    v = client->_bind( compare_text )
                                    )->a( n = `visible` v = client->_bind( compare_visible )
                                    )->a( n = `press`   v = client->_event( `COMPARE` )

                            )->end(
                        )->end(
                        )->ele( `columns`
                            )->ele( `Column`
                                )->tag( `Text`
                                    )->a( n = `text` v = `Product`

                            )->end(
                            )->ele( `Column`
                                )->a( n = `hAlign`         v = `Center`
                                )->a( n = `width`          v = `12em`
                                )->a( n = `minScreenWidth` v = `Tablet`
                                )->a( n = `demandPopin`    v = `true`

                                )->tag( `Text`
                                    )->a( n = `text` v = `Quantity`

                            )->end(
                            )->ele( `Column`
                                )->a( n = `minScreenWidth` v = `Tablet`
                                )->a( n = `demandPopin`    v = `true`
                                )->a( n = `hAlign`         v = `Center`

                                )->tag( `Text`
                                    )->a( n = `text` v = `Weight`

                            )->end(
                            )->ele( `Column`
                                )->a( n = `hAlign` v = `End`

                                )->tag( `Text`
                                    )->a( n = `text` v = `Unit Price`

                            )->end(
                        )->end(
                        )->ele( `items`
                            " selected two-way binding added to read the multi-selection in the SELECTION handler (getSelectedContextPaths equivalent)
                            )->ele( `ColumnListItem`
                                )->a( n = `vAlign`   v = `Middle`
                                )->a( n = `type`     v = `Inactive`
                                )->a( n = `selected` v = `{SELECTED}`

                                )->ele( `cells`
                                    )->tag( `ObjectIdentifier`
                                        )->a( n = `title` v = `{NAME}`
                                        )->a( n = `text`  v = `{PRODUCTID}`
                                    )->tag( `Input`
                                        )->a( n = `value`       v = `{QUANTITY}`
                                        " the ORIGINAL writes type="{Text}" (Main.view.xml): it meant the
                                        " literal enum value and wrote a binding, so the property falls back
                                        " to its default. Ported verbatim rather than repaired
                                        " abap2ui5lint-disable-next-line unknown-binding-path -- the sample's own quirk
                                        )->a( n = `type`        v = `{Text}`
                                        )->a( n = `description` v = `{UOM}`
                                        )->a( n = `fieldWidth`  v = `{60%}`
                                    )->tag( `ObjectNumber`
                                        )->a( n = `number` v = `{WEIGHTMEASURE}`
                                        )->a( n = `unit`   v = `{WEIGHTUNIT}`
                                    )->tag( `ObjectNumber`
                                        )->a( n = `number` v = |\{ parts:[\{path:'PRICE'\},\{path:'CURRENCYCODE'\}], type: 'sap.ui.model.type.Currency', formatOptions: \{showMeasure: false\} \}|
                                        )->a( n = `unit`   v = `{CURRENCYCODE}`

                                )->end(
                            )->end(
                        )->end(
                    )->end(
                )->end(
            )->end(
            )->ele( n = `DynamicPage` ns = `f`
                )->a( n = `id`    v = `page-comparison`
                )->a( n = `class` v = `sapUiComparisonContainer`

                )->ele( n = `title` ns = `f`
                    " the original's stateChange handler (add/removeSnappedContent Carousel animation workaround) is dropped - imperative aggregation surgery
                    )->ele( n = `DynamicPageTitle` ns = `f`
                        )->a( n = `id`               v = `dynamic-page`
                        )->a( n = `backgroundDesign` v = `Transparent`

                        )->ele( n = `heading` ns = `f`
                            )->tag( `Title`
                                )->a( n = `text` v = `Second Page`

                        )->end(
                        )->ele( n = `snappedContent` ns = `f`
                            )->ele( `Carousel`
                                )->a( n = `height`                 v = `auto`
                                )->a( n = `class`                  v = `sapUiSmallMarginBottom`
                                )->a( n = `id`                     v = `carousel-snapped`
                                )->a( n = `pageChanged`            v = client->_event( val = `PAGE_CHANGED` arg = `${$parameters>/activePages/0}` )
                                )->a( n = `pageIndicatorPlacement` v = `Top`
                                )->a( n = `showPageIndicator`      v = |\{= !${ client->_bind( isdesktop ) } \}|
                                )->a( n = `pages`                  v = client->_bind( t_comp_products )

                                )->ele( `customLayout`
                                    )->tag( `CarouselLayout`
                                        )->a( n = `visiblePagesCount` v = client->_bind( pagescount )

                                )->end(
                                )->ele( n = `Card` ns = `f`
                                    )->a( n = `class` v = `sapUiTinyMarginTop`

                                    )->ele( n = `header` ns = `f`
                                        " iconSrc formatter .formatter.url flattened to absolute image URLs in the model
                                        )->tag( n = `Header` ns = `card`
                                            )->a( n = `title`            v = `{NAME}`
                                            )->a( n = `subtitle`         v = `{STATUS}`
                                            )->a( n = `iconSrc`          v = `{PRODUCTPICURL}`
                                            )->a( n = `iconDisplayShape` v = `Square`

                                    )->end(
                                )->end(
                            )->end(
                        )->end(
                    )->end(
                )->end(
                )->ele( n = `header` ns = `f`
                    )->ele( n = `DynamicPageHeader` ns = `f`
                        )->a( n = `backgroundDesign` v = `Transparent`

                        )->ele( `Carousel`
                            )->a( n = `height`                 v = `auto`
                            )->a( n = `class`                  v = `sapUiSmallMarginBottom`
                            )->a( n = `id`                     v = `carousel-expanded`
                            )->a( n = `pageChanged`            v = client->_event( val = `PAGE_CHANGED` arg = `${$parameters>/activePages/0}` )
                            )->a( n = `pageIndicatorPlacement` v = `Top`
                            )->a( n = `showPageIndicator`      v = |\{= !${ client->_bind( isdesktop ) } \}|
                            )->a( n = `pages`                  v = client->_bind( t_comp_products )

                            )->ele( `customLayout`
                                )->tag( `CarouselLayout`
                                    )->a( n = `visiblePagesCount` v = client->_bind( pagescount )

                            )->end(
                            )->ele( n = `Card` ns = `f`
                                )->a( n = `class` v = `sapUiTinyMarginTop`

                                )->ele( n = `header` ns = `f`
                                    )->tag( n = `Header` ns = `card`
                                        )->a( n = `title`            v = `{NAME}`
                                        )->a( n = `subtitle`         v = `{STATUS}`
                                        )->a( n = `iconSrc`          v = `{PRODUCTPICURL}`
                                        )->a( n = `iconDisplayShape` v = `Square`

                                )->end(
                                )->ele( n = `content` ns = `f`
                                    )->ele( n = `VerticalLayout` ns = `l`
                                        )->a( n = `width` v = `100%`

                                        )->ele( n = `BlockLayout` ns = `l`
                                            )->ele( n = `BlockLayoutRow` ns = `l`
                                                )->ele( n = `BlockLayoutCell` ns = `l`
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Supplier:`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{SUPPLIERNAME}`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Main Category:`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{MAINCATEGORY}`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Category:`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{CATEGORY}`

                                                    )->end(
                                                )->end(
                                                )->ele( n = `BlockLayoutCell` ns = `l`
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Width (cm)`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{WIDTH}`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Height (cm)`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{HEIGHT}`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->tag( `Label`
                                                            )->a( n = `text` v = `Weight (kg)`

                                                    )->end(
                                                    )->ele( `HBox`
                                                        )->a( n = `class` v = `sapUiSmallMarginBottom`

                                                        )->tag( `Text`
                                                            )->a( n = `text` v = `{WEIGHTMEASURE}`

                                                    )->end(
                                                )->end(
                                            )->end(
                                        )->end(
                                    )->end(
                                )->end(
                            )->end(
                        )->end(
                    )->end(
                )->end(
                )->ele( n = `content` ns = `f`
                    )->ele( `List`
                        )->a( n = `id`               v = `listItems`
                        )->a( n = `backgroundDesign` v = `Transparent`
                        )->a( n = `class`            v = `sapUiSmallMarginBottom`
                        )->a( n = `items`            v = client->_bind( t_comp_props )

                        )->ele( `items`
                            )->ele( `CustomListItem`
                                )->a( n = `class` v = `sapUiComparisonContent`

                                )->tag( `Panel`
                                    )->a( n = `expandable` v = `true`
                                    )->a( n = `expanded`   v = `false`
                                    )->a( n = `headerText` v = `{KEY}`
                                    )->a( n = `height`     v = `2.75rem`
                                    )->a( n = `expand`     v = client->_event( val   = `PANEL_EXPANDED`
                                                                               t_arg = VALUE #( ( `${KEY}` ) ( `${$parameters>/expand}` ) ) )

                                )->ele( `HBox`
                                    )->a( n = `class`            v = `sapUiTinyMarginTop`
                                    )->a( n = `alignItems`       v = `Start`
                                    )->a( n = `backgroundDesign` v = `Solid`
                                    )->a( n = `items`            v = |\{ path: 'VALUES', templateShareable : true \}|

                                    )->ele( `items`
                                        )->ele( `VBox`
                                            )->a( n = `class` v = `sapUiTinyMarginTopBottom sapUiComparisonItem`

                                            )->ele( `layoutData`
                                                )->tag( `FlexItemData`
                                                    )->a( n = `growFactor` v = `1`
                                                    )->a( n = `baseSize`   v = `0`

                                            )->end(
                                            )->ele( `HBox`
                                                )->tag( `FormattedText`
                                                    )->a( n = `htmlText` v = `{TEXT}`

                                            )->end(
                                            " the controller's onPanelExpanded setVisible replaced by the bound VISIBLE flag per value row
                                            )->ele( `HBox`
                                                )->a( n = `class`   v = `sapUiSmallMarginTop`
                                                )->a( n = `visible` v = `{VISIBLE}`

                                                )->tag( `Text`
                                                    )->a( n = `text` v = `{DESCRIPTION}`

                                            )->end(
                                        )->end(
                                    )->end(
                                )->end(
                            )->end(
                        )->end(
                    )->end(
                )->end(
            )->end(
        )->end( ).

    " the original controller's onAfterRendering binding filter: only Laptops are compared
    client->follow_up_action( val   = client->cs_event-binding_call
                              t_arg = VALUE #( ( `idProductsTable` ) ( `items` ) ( `filter` ) ( `CATEGORY` ) ( `EQ` ) ( `Laptops` ) ) ).

    " the original's manifest router, app-owned: the hash stays the app's own
    " (#/Page2, no route prefix), and a hash change the app did not write -
    " browser Back/Forward, a manual edit - round-trips as HASH_CHANGED.
    " Re-asserted per render, since the registration dies with an app switch
    client->follow_up_action( val   = client->cs_event-hash_attach_changed
                              t_arg = VALUE #( ( `HASH_CHANGED` ) ) ).

    client->view_display( view->stringify( ) ).

    " A Carousel's active page is live control state a rebuilt view resets to
    " page 0, while first_item survives as class state AND drives the bound
    " comparison rows - so after a rebuild the two Carousels show item 0 next to
    " props for items first_item.. Re-issued positionally, the same form the
    " event branch uses (the pages are aggregation-template clones with no id
    " the backend can spell). Guarded, because page 0 is where a fresh view
    " already is. Found by the linter's control-state-lost-on-rebuild rule
    IF first_item > 0.
      client->follow_up_action( val   = client->cs_event-control_by_id
                                t_arg = VALUE #( ( `carousel-snapped` )
                                                 ( `setActivePage` )
                                                 ( |carousel-snapped/pages/{ first_item }| ) ) ).
      client->follow_up_action( val   = client->cs_event-control_by_id
                                t_arg = VALUE #( ( `carousel-expanded` )
                                                 ( `setActivePage` )
                                                 ( |carousel-expanded/pages/{ first_item }| ) ) ).
    ENDIF.

    " the NavContainer's active page is the same class of live control state:
    " a rebuilt view (a restored draft, a return from a called app) is back on
    " the first page while check_page2 survives as class state
    IF check_page2 = abap_true.
      client->follow_up_action( val   = client->cs_event-control_by_id
                                t_arg = VALUE #( ( `rootControl` ) ( `to` ) ( `page-comparison` ) ) ).
    ENDIF.

  ENDMETHOD.


  METHOD on_event.

    CASE client->get_event( ).

      WHEN `SELECTION`.
        DATA(selected_count) = 0.
        LOOP AT t_products TRANSPORTING NO FIELDS WHERE selected = abap_true.
          selected_count = selected_count + 1.
        ENDLOOP.
        IF selected_count > 1.
          compare_text    = |Compare ({ selected_count })|.
          compare_visible = abap_true.
        ELSE.
          compare_visible = abap_false.
        ENDIF.

      WHEN `COMPARE`.
        comparison_build( ).
        check_page2 = abap_true.
        " the router's navTo("page2") mapped to the NavContainer `to` frontend action
        client->follow_up_action( val   = client->cs_event-control_by_id
                                  t_arg = VALUE #( ( `rootControl` ) ( `to` ) ( `page-comparison` ) ) ).
        " navTo also writes the router's hash: with the hash listener
        " registered this pushes the app-owned `#/Page2` - the original's URL
        " 1:1 - as a real history entry, so browser Back has somewhere to go
        client->hash_set( `/Page2` ).

      WHEN `HASH_CHANGED`.
        " browser Back/Forward (or a manual edit) moved the app-owned hash -
        " the router's routeMatched: show the page the hash now names. The
        " hash rides in s_config-hash with this very request; the app
        " instance is untouched, so the selection survives like with the
        " original's client-side router
        IF contains( val = client->get( )-s_config-hash sub = `/Page2` ).
          IF check_page2 = abap_false.
            comparison_build( ).
            check_page2 = abap_true.
            client->follow_up_action( val   = client->cs_event-control_by_id
                                      t_arg = VALUE #( ( `rootControl` ) ( `to` ) ( `page-comparison` ) ) ).
          ENDIF.
        ELSEIF check_page2 = abap_true.
          check_page2 = abap_false.
          " NavContainer `back` pops the page the `to` above pushed
          client->follow_up_action( val   = client->cs_event-control_by_id
                                    t_arg = VALUE #( ( `rootControl` ) ( `back` ) ) ).
        ENDIF.

      WHEN `PAGE_CHANGED`.
        DATA(page_arg) = client->get_event_arg( ).
        IF page_arg CO `0123456789`.
          first_item = page_arg.
        ELSE.
          first_item = 0.
        ENDIF.
        comparison_props_build( ).
        " _updateCarouselsActivePage: the original keeps the two Carousels in
        " step by handing each its own page AT THE SAME INDEX
        " (carousel.setActivePage( carousel.getPages()[ iFirstItem ] )). Those
        " pages are aggregation-template CLONES with no id the backend can
        " spell, so they are addressed positionally since 2026-08-06
        client->follow_up_action( val   = client->cs_event-control_by_id
                                  t_arg = VALUE #( ( `carousel-snapped` )
                                                   ( `setActivePage` )
                                                   ( |carousel-snapped/pages/{ first_item }| ) ) ).
        client->follow_up_action( val   = client->cs_event-control_by_id
                                  t_arg = VALUE #( ( `carousel-expanded` )
                                                   ( `setActivePage` )
                                                   ( |carousel-expanded/pages/{ first_item }| ) ) ).

      WHEN `PANEL_EXPANDED`.
        DATA(prop_key) = client->get_event_arg( ).
        DATA(expanded) = client->get_event_arg( 2 ).
        READ TABLE t_comp_props ASSIGNING FIELD-SYMBOL(<s_prop>) WITH KEY key = prop_key.
        IF sy-subrc = 0.
          LOOP AT <s_prop>-values ASSIGNING FIELD-SYMBOL(<s_value>).
            <s_value>-visible = expanded.
          ENDLOOP.
        ENDIF.

    ENDCASE.

  ENDMETHOD.


  METHOD comparison_build.

    t_comp_products = VALUE #( ).
    LOOP AT t_products INTO DATA(s_product) WHERE selected = abap_true.
      APPEND s_product TO t_comp_products.
    ENDLOOP.

    " the original's ResizeHandler-driven _getPagesCount (600/1024 thresholds), computed once from the reported device width
    DATA(width) = client->get( )-s_device-resize-width.
    IF width > 0 AND width <= 600.
      pagescount = 1.
    ELSEIF width > 0 AND width <= 1024.
      pagescount = 2.
    ELSE.
      pagescount = 4.
    ENDIF.
    IF pagescount > lines( t_comp_products ).
      pagescount = lines( t_comp_products ).
    ENDIF.
    " a cold #/Page2 (deep link, reload) has no selection: the original's
    " settings model is then empty and visiblePagesCount falls back to its
    " UI5 default 1 - a computed 0 would be an invalid CarouselLayout count
    IF pagescount < 1.
      pagescount = 1.
    ENDIF.
    isdesktop = xsdbool( pagescount = 4 ).

    first_item = 0.
    comparison_props_build( ).

  ENDMETHOD.


  METHOD comparison_props_build.

    " the original iterates the first selected product's JSON keys (except ProductPicUrl); here the same keys as a fixed list
    DATA(t_keys) = VALUE ty_t_key(
      ( key = `ProductId`     field = `PRODUCTID` )
      ( key = `Category`      field = `CATEGORY` )
      ( key = `MainCategory`  field = `MAINCATEGORY` )
      ( key = `TaxTarifCode`  field = `TAXTARIFCODE` )
      ( key = `SupplierName`  field = `SUPPLIERNAME` )
      ( key = `WeightMeasure` field = `WEIGHTMEASURE` )
      ( key = `WeightUnit`    field = `WEIGHTUNIT` )
      ( key = `Description`   field = `DESCRIPTION` )
      ( key = `Name`          field = `NAME` )
      ( key = `DateOfSale`    field = `DATEOFSALE` )
      ( key = `Status`        field = `STATUS` )
      ( key = `Quantity`      field = `QUANTITY` )
      ( key = `UoM`           field = `UOM` )
      ( key = `CurrencyCode`  field = `CURRENCYCODE` )
      ( key = `Price`         field = `PRICE` )
      ( key = `Width`         field = `WIDTH` )
      ( key = `Depth`         field = `DEPTH` )
      ( key = `Height`        field = `HEIGHT` )
      ( key = `DimUnit`       field = `DIMUNIT` ) ).

    DATA(from_item) = first_item + 1.
    DATA(last_item) = first_item + pagescount.
    IF last_item > lines( t_comp_products ).
      last_item = lines( t_comp_products ).
    ENDIF.

    t_comp_props = VALUE #( ).
    " the original's cold #/Page2 renders BOTH lists empty ('no data') - its
    " Props are built per selected product, so no product means no rows, not
    " nineteen property panels with empty value lists
    IF t_comp_products IS INITIAL.
      RETURN.
    ENDIF.
    LOOP AT t_keys INTO DATA(s_key).
      DATA(s_prop) = VALUE ty_s_comp_prop( key = s_key-key ).
      LOOP AT t_comp_products FROM from_item TO last_item INTO DATA(s_product).
        ASSIGN COMPONENT s_key-field OF STRUCTURE s_product TO FIELD-SYMBOL(<value>).
        IF sy-subrc = 0.
          APPEND VALUE #( text        = |<strong>{ <value> }</strong>|
                          description = `Some description of the property here`
                          visible     = abap_false ) TO s_prop-values.
        ENDIF.
      ENDLOOP.
      APPEND s_prop TO t_comp_props.
    ENDLOOP.

  ENDMETHOD.


  METHOD model_init.

    " the full mock /ProductCollection (sap/ui/demo/mock/products.json); the table binding filters to Category = Laptops (onAfterRendering), as the original loads all rows and filters client-side
    " ProductPicUrl resolved to absolute OpenUI5 URLs (the sample's .formatter.url)
    t_products = VALUE #(
      ( productid = `HT-1000` category = `Laptops` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `4.2` weightunit = `KG`
        description = `Notebook Basic 15 with 2,80 GHz quad core, 15" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro` name = `Notebook Basic 15`
        dateofsale = `2017-03-26` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1000.jpg` status = `Available` quantity = `10` uom = `PC` currencycode = `EUR` price = `956.00` width = `30`
        depth = `18` height = `3` dimunit = `cm` )
      ( productid = `HT-1001` category = `Laptops` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `4.5` weightunit = `KG`
        description = `Notebook Basic 17 with 2,80 GHz quad core, 17" LCD, 4 GB DDR3 RAM, 500 GB Hard Disc, Windows 8 Pro` name = `Notebook Basic 17`
        dateofsale = `2017-04-17` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1001.jpg` status = `Available` quantity = `20` uom = `PC` currencycode = `EUR` price = `1249.00` width = `29`
        depth = `17` height = `3.1` dimunit = `cm` )
      ( productid = `HT-1002` category = `Laptops` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `4.2` weightunit = `KG`
        description = `Notebook Basic 18 with 2,80 GHz quad core, 18" LCD, 8 GB DDR3 RAM, 1000 GB Hard Disc, Windows 8 Pro` name = `Notebook Basic 18`
        dateofsale = `2017-01-07` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1002.jpg` status = `Available` quantity = `10` uom = `PC` currencycode = `EUR` price = `1570.00` width = `28`
        depth = `19` height = `2.5` dimunit = `cm` )
      ( productid = `HT-1003` category = `Laptops` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Smartcards` weightmeasure = `4.2` weightunit = `KG`
        description = `Notebook Basic 19 with 2,80 GHz quad core, 19" LCD, 8 GB DDR3 RAM, 1000 GB Hard Disc, Windows 8 Pro` name = `Notebook Basic 19`
        dateofsale = `2017-04-09` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1003.jpg` status = `Out of Stock` quantity = `15` uom = `PC` currencycode = `EUR` price = `1650.00` width = `32`
        depth = `21` height = `4` dimunit = `cm` )
      ( productid = `HT-1007` category = `Accessories` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Technocom` weightmeasure = `0.2` weightunit = `KG`
        description = `Digital Organizer with State-of-the-Art Storage Encryption` name = `ITelO Vault`
        dateofsale = `2017-05-17` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1007.jpg` status = `Out of Stock` quantity = `15` uom = `PC` currencycode = `EUR` price = `299.00` width = `32`
        depth = `22` height = `3` dimunit = `cm` )
      ( productid = `HT-1010` category = `Accessories` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `4.3` weightunit = `KG`
        description = `Notebook Professional 15 with 2,80 GHz quad core, 15" Multitouch LCD, 8 GB DDR3 RAM, 500 GB SSD - DVD-Writer (DVD-R/+R/-RW/-RAM),Windows 8 Pro` name = `Notebook Professional 15`
        dateofsale = `2017-02-22` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1010.jpg` status = `Out of Stock` quantity = `16` uom = `PC` currencycode = `EUR` price = `1999.00` width = `33`
        depth = `20` height = `3` dimunit = `cm` )
      ( productid = `HT-1011` category = `Laptops` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `4.1` weightunit = `KG`
        description = `Notebook Professional 17 with 2,80 GHz quad core, 17" Multitouch LCD, 8 GB DDR3 RAM, 500 GB SSD - DVD-Writer (DVD-R/+R/-RW/-RAM),Windows 8 Pro` name = `Notebook Professional 17`
        dateofsale = `2017-01-02` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1011.jpg` status = `Out of Stock` quantity = `17` uom = `PC` currencycode = `EUR` price = `2299.00` width = `33`
        depth = `23` height = `2` dimunit = `cm` )
      ( productid = `HT-1020` category = `Accessories` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Technocom` weightmeasure = `0.16` weightunit = `KG`
        description = `Digital Organizer with State-of-the-Art Encryption for Storage and Network Communications` name = `ITelO Vault Net`
        dateofsale = `2017-05-08` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1020.jpg` status = `Discontinued` quantity = `14` uom = `PC` currencycode = `EUR` price = `459.00` width = `10`
        depth = `1.8` height = `17` dimunit = `cm` )
      ( productid = `HT-1021` category = `Accessories` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Technocom` weightmeasure = `0.18` weightunit = `KG`
        description = `Digital Organizer with State-of-the-Art Encryption for Storage and Secure Stellite Link` name = `ITelO Vault SAT`
        dateofsale = `2017-06-30` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1021.jpg` status = `Available` quantity = `50` uom = `PC` currencycode = `EUR` price = `149.00` width = `11`
        depth = `1.7` height = `18` dimunit = `cm` )
      ( productid = `HT-1022` category = `Accessories` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Technocom` weightmeasure = `0.2` weightunit = `KG`
        description = `32 GB Digital Assistant with high-resolution color screen` name = `Comfort Easy`
        dateofsale = `2017-03-02` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1022.jpg` status = `Out of Stock` quantity = `30` uom = `PC` currencycode = `EUR` price = `1679.00` width = `84`
        depth = `1.5` height = `14` dimunit = `cm` )
      ( productid = `HT-1023` category = `Accessories` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Technocom` weightmeasure = `0.8` weightunit = `KG`
        description = `64 GB Digital Assistant with high-resolution color screen and synthesized voice output` name = `Comfort Senior`
        dateofsale = `2017-02-25` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1023.jpg` status = `Available` quantity = `24` uom = `PC` currencycode = `EUR` price = `512.00` width = `80`
        depth = `1.6` height = `13` dimunit = `cm` )
      ( productid = `HT-1030` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `21` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 1920 x 1080 @ 85Hz, Dot Pitch: 0.27mm` name = `Ergo Screen E-I`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1030.jpg` status = `Available` quantity = `14` uom = `PC` currencycode = `EUR` price = `230.00` width = `37`
        depth = `12` height = `36` dimunit = `cm` )
      ( productid = `HT-1031` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `21` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 1920 x 1200 @ 85Hz, Dot Pitch: 0.26mm` name = `Ergo Screen E-II`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1031.jpg` status = `Available` quantity = `24` uom = `PC` currencycode = `EUR` price = `285.00` width = `40.8`
        depth = `19` height = `43` dimunit = `cm` )
      ( productid = `HT-1032` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `21` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 2560 x 1440 @ 85Hz, Dot Pitch: 0.25mm` name = `Ergo Screen E-III`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1032.jpg` status = `Out of Stock` quantity = `50` uom = `PC` currencycode = `EUR` price = `345.00` width = `40.8`
        depth = `19` height = `43` dimunit = `cm` )
      ( productid = `HT-1035` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `14` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 1600 x 1200 @ 85Hz, Dot Pitch: 0.24mm` name = `Flat Basic`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1035.jpg` status = `Available` quantity = `23` uom = `PC` currencycode = `EUR` price = `399.00` width = `39`
        depth = `20` height = `41` dimunit = `cm` )
      ( productid = `HT-1036` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `15` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 2048 x 1080 @ 85Hz, Dot Pitch: 0.26mm` name = `Flat Future`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1036.jpg` status = `Available` quantity = `22` uom = `PC` currencycode = `EUR` price = `430.00` width = `45`
        depth = `26` height = `46` dimunit = `cm` )
      ( productid = `HT-1037` category = `Flat Screen Monitors` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Very Best Screens` weightmeasure = `17` weightunit = `KG`
        description = `Optimum Hi-Resolution max. 2016 x 1512 @ 85Hz, Dot Pitch: 0.24mm` name = `Flat XL`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1037.jpg` status = `Available` quantity = `23` uom = `PC` currencycode = `EUR` price = `1230.00` width = `54.5`
        depth = `22.1` height = `39.1` dimunit = `cm` )
      ( productid = `HT-1040` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Alpha Printers` weightmeasure = `32` weightunit = `KG`
        description = `Print 2400 dpi image quality color documents at speeds of up to 32 ppm (color) or 36 ppm (monochrome), letter/A4. Powerful 500 MHz processor, 512MB of memory` name = `Laser Professional Eco`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1040.jpg` status = `Available` quantity = `21` uom = `PC` currencycode = `EUR` price = `830.00` width = `51`
        depth = `46` height = `30` dimunit = `cm` )
      ( productid = `HT-1041` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Alpha Printers` weightmeasure = `23` weightunit = `KG`
        description = `Up to 22 ppm color or 24 ppm monochrome A4/letter, powerful 500 MHz processor and 128MB of memory` name = `Laser Basic`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1041.jpg` status = `Available` quantity = `8` uom = `PC` currencycode = `EUR` price = `490.00` width = `48`
        depth = `42` height = `26` dimunit = `cm` )
      ( productid = `HT-1042` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Alpha Printers` weightmeasure = `17` weightunit = `KG`
        description = `Print up to 25 ppm letter and 24 ppm A4 color or monochrome, with Available first-page-out-time of less than 13 seconds for monochrome and less than 15 seconds for color` name = `Laser Allround`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1042.jpg` status = `Available` quantity = `9` uom = `PC` currencycode = `EUR` price = `349.00` width = `53`
        depth = `50` height = `65` dimunit = `cm` )
      ( productid = `HT-1050` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Alpha Printers` weightmeasure = `3` weightunit = `KG`
        description = `4800 dpi x 1200 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB, Ethernet` name = `Ultra Jet Super Color`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1050.jpg` status = `Discontinued` quantity = `17` uom = `PC` currencycode = `EUR` price = `139.00` width = `41`
        depth = `41` height = `28` dimunit = `cm` )
      ( productid = `HT-1051` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `1.9` weightunit = `KG`
        description = `1000 dpi x 1000 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB - excellent dimensions for the small office` name = `Ultra Jet Mobile`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1051.jpg` status = `Discontinued` quantity = `18` uom = `PC` currencycode = `EUR` price = `99.00` width = `46`
        depth = `32` height = `25` dimunit = `cm` )
      ( productid = `HT-1052` category = `Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `18` weightunit = `KG`
        description = `4800 dpi x 1200 dpi - up to 35 ppm (mono) / up to 34 ppm (color) - capacity: 250 sheets - Hi-Speed USB2.0, Ethernet` name = `Ultra Jet Super Highspeed`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1052.jpg` status = `Available` quantity = `25` uom = `PC` currencycode = `EUR` price = `170.00` width = `41`
        depth = `41` height = `28` dimunit = `cm` )
      ( productid = `HT-1055` category = `Multifunction Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `6.3` weightunit = `KG`
        description = `1000 dpi x 1000 dpi - up to 16 ppm (mono) / up to 15 ppm (color)- capacity 80 sheets - scanner (216 x 297 mm, 1200dpi x 2400dpi)` name = `Multi Print`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1055.jpg` status = `Available` quantity = `16` uom = `PC` currencycode = `EUR` price = `99.00` width = `55`
        depth = `45` height = `29` dimunit = `cm` )
      ( productid = `HT-1056` category = `Multifunction Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `4.3` weightunit = `KG`
        description = `1200 dpi x 1200 dpi - up to 25 ppm (mono) / up to 24 ppm (color)- capacity 80 sheets - scanner (216 x 297 mm, 2400dpi x 4800dpi, high resolution)` name = `Multi Color`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1056.jpg` status = `Available` quantity = `5` uom = `PC` currencycode = `EUR` price = `119.00` width = `51`
        depth = `41.3` height = `22` dimunit = `cm` )
      ( productid = `HT-1060` category = `Mice` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `0.09` weightunit = `KG`
        description = `Cordless Optical USB Mice, Laptop, Color: Black, Plug&Play` name = `Cordless Mouse`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1060.jpg` status = `Available` quantity = `25` uom = `PC` currencycode = `EUR` price = `9.00` width = `6`
        depth = `14.5` height = `3.5` dimunit = `cm` )
      ( productid = `HT-1061` category = `Mice` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `0.09` weightunit = `KG`
        description = `Optical USB, PS/2 Mouse, Color: Blue, 3-button-functionality (incl. Scroll wheel)` name = `Speed Mouse`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1061.jpg` status = `Available` quantity = `12` uom = `PC` currencycode = `EUR` price = `7.00` width = `7`
        depth = `15` height = `3.1` dimunit = `cm` )
      ( productid = `HT-1062` category = `Mice` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `0.03` weightunit = `KG`
        description = `Optical USB Mouse, Color: Red, 5-button-functionality(incl. Scroll wheel), Plug&Play` name = `Track Mouse`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1062.jpg` status = `Discontinued` quantity = `12` uom = `PC` currencycode = `EUR` price = `11.00` width = `3`
        depth = `7` height = `4` dimunit = `cm` )
      ( productid = `HT-1063` category = `Keyboards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `2.1` weightunit = `KG`
        description = `Ergonomic USB Keyboard for Desktop, Plug&Play` name = `Ergonomic Keyboard`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1063.jpg` status = `Available` quantity = `50` uom = `PC` currencycode = `EUR` price = `14.00` width = `50`
        depth = `21` height = `3.5` dimunit = `cm` )
      ( productid = `HT-1064` category = `Keyboards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `1.8` weightunit = `KG`
        description = `Corded Keyboard with special keys for Internet Usability, USB` name = `Internet Keyboard`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1064.jpg` status = `Out of Stock` quantity = `35` uom = `PC` currencycode = `EUR` price = `16.00` width = `52`
        depth = `25` height = `3` dimunit = `cm` )
      ( productid = `HT-1065` category = `Keyboards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `2.3` weightunit = `KG`
        description = `Corded Ergonomic Keyboard with special keys for Media Usability, USB` name = `Media Keyboard`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1065.jpg` status = `Available` quantity = `26` uom = `PC` currencycode = `EUR` price = `26.00` width = `51.4`
        depth = `23` height = `4` dimunit = `cm` )
      ( productid = `HT-1066` category = `Mousepads` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `80` weightunit = `G`
        description = `Nice mouse pad with ITelO Logo` name = `Mousepad`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1066.jpg` status = `Available` quantity = `12` uom = `PC` currencycode = `EUR` price = `6.99` width = `15`
        depth = `6` height = `0.2` dimunit = `cm` )
      ( productid = `HT-1067` category = `Mousepads` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Oxynum` weightmeasure = `80` weightunit = `G`
        description = `Ergonomic mouse pad with ITelO Logo` name = `Ergo Mousepad`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1067.jpg` status = `Out of Stock` quantity = `16` uom = `PC` currencycode = `EUR` price = `8.99` width = `15`
        depth = `6` height = `0.2` dimunit = `cm` )
      ( productid = `HT-1068` category = `Mousepads` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Fasttech` weightmeasure = `90` weightunit = `G`
        description = `ITelO Mousepad Special Edition` name = `Designer Mousepad`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1068.jpg` status = `Available` quantity = `26` uom = `PC` currencycode = `EUR` price = `12.99` width = `24`
        depth = `24` height = `0.6` dimunit = `cm` )
      ( productid = `HT-1069` category = `Computer System Accessories` maincategory = `Computer Systems` taxtarifcode = `1` suppliername = `Fasttech` weightmeasure = `45` weightunit = `G`
        description = `Universal card reader` name = `Universal card reader`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1069.jpg` status = `Available` quantity = `22` uom = `PC` currencycode = `EUR` price = `14.00` width = `6`
        depth = `6` height = `3` dimunit = `cm` )
      ( productid = `HT-1070` category = `Graphic Cards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Ultrasonic United` weightmeasure = `0.255` weightunit = `KG`
        description = `Proctra X: PCI-E GDDR5 3072MB` name = `Proctra X`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1070.jpg` status = `Out of Stock` quantity = `15` uom = `PC` currencycode = `EUR` price = `70.90` width = `22`
        depth = `35` height = `17` dimunit = `cm` )
      ( productid = `HT-1071` category = `Graphic Cards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Ultrasonic United` weightmeasure = `0.3` weightunit = `KG`
        description = `Gladiator XLN: PCI-E GDDR5 3072MB DVI Out, TV Out low-noise` name = `Gladiator MX`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1071.jpg` status = `Discontinued` quantity = `16` uom = `PC` currencycode = `EUR` price = `81.70` width = `22`
        depth = `35` height = `17` dimunit = `cm` )
      ( productid = `HT-1072` category = `Graphic Cards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Ultrasonic United` weightmeasure = `0.4` weightunit = `KG`
        description = `Hurricane GX: PCI-E 691 GFLOPS game-optimized` name = `Hurricane GX`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1072.jpg` status = `Available` quantity = `13` uom = `PC` currencycode = `EUR` price = `101.20` width = `22`
        depth = `35` height = `17` dimunit = `cm` )
      ( productid = `HT-1073` category = `Graphic Cards` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Smartcards` weightmeasure = `0.4` weightunit = `KG`
        description = `Hurricane GX/LN: PCI-E 691 GFLOPS game-optimized, low-noise.` name = `Hurricane GX/LN`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1073.jpg` status = `Out of Stock` quantity = `5` uom = `PC` currencycode = `EUR` price = `139.99` width = `22`
        depth = `35` height = `17` dimunit = `cm` )
      ( productid = `HT-1080` category = `Scanners` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `2.3` weightunit = `KG`
        description = `Flatbed scanner - 9.600 × 9.600 dpi - 216 x 297 mm - Hi-Speed USB - Bluetooth` name = `Photo Scan`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1080.jpg` status = `Out of Stock` quantity = `8` uom = `PC` currencycode = `EUR` price = `129.00` width = `34`
        depth = `48` height = `5` dimunit = `cm` )
      ( productid = `HT-1081` category = `Scanners` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `2.4` weightunit = `KG`
        description = `Flatbed scanner - 9.600 × 9.600 dpi - 216 x 297 mm - SCSI for backward compatibility` name = `Power Scan`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1081.jpg` status = `Out of Stock` quantity = `11` uom = `PC` currencycode = `EUR` price = `89.00` width = `31`
        depth = `43` height = `7` dimunit = `cm` )
      ( productid = `HT-1082` category = `Scanners` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `3.2` weightunit = `KG`
        description = `Flatbed scanner - Letter - 2400 dpi x 2400 dpi - 216 x 297 mm - add-on module` name = `Jet Scan Professional`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1082.jpg` status = `Out of Stock` quantity = `13` uom = `PC` currencycode = `EUR` price = `169.00` width = `33`
        depth = `41` height = `12` dimunit = `cm` )
      ( productid = `HT-1083` category = `Scanners` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Printer for All` weightmeasure = `3.2` weightunit = `KG`
        description = `Flatbed scanner - A4 - 2400 dpi x 2400 dpi - 216 x 297 mm - add-on module` name = `Jet Scan Professional`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1083.jpg` status = `Available` quantity = `10` uom = `PC` currencycode = `EUR` price = `189.00` width = `35`
        depth = `40` height = `10` dimunit = `cm` )
      ( productid = `HT-1085` category = `Multifunction Printers` maincategory = `Printers & Scanners` taxtarifcode = `1` suppliername = `Alpha Printers` weightmeasure = `23.2` weightunit = `KG`
        description = `Copymaster` name = `Copymaster`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1085.jpg` status = `Available` quantity = `10` uom = `PC` currencycode = `EUR` price = `1499.00` width = `45`
        depth = `42` height = `22` dimunit = `cm` )
      ( productid = `HT-1090` category = `Speakers` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Speaker Experts` weightmeasure = `3` weightunit = `KG`
        description = `PC multimedia speakers - 5 Watt (Total)` name = `Surround Sound`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1090.jpg` status = `Available` quantity = `20` uom = `PC` currencycode = `EUR` price = `39.00` width = `12`
        depth = `10` height = `16` dimunit = `cm` )
      ( productid = `HT-1091` category = `Speakers` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Speaker Experts` weightmeasure = `1.4` weightunit = `KG`
        description = `PC multimedia speakers - 10 Watt (Total) - 2-way` name = `Blaster Extreme`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1091.jpg` status = `Available` quantity = `15` uom = `PC` currencycode = `EUR` price = `26.00` width = `13`
        depth = `11` height = `17.5` dimunit = `cm` )
      ( productid = `HT-1092` category = `Speakers` maincategory = `Computer Components` taxtarifcode = `1` suppliername = `Speaker Experts` weightmeasure = `2.1` weightunit = `KG`
        description = `PC multimedia speakers - optimized for Blutooth/A2DP` name = `Sound Booster`
        dateofsale = `` productpicurl = `https://sdk.openui5.org/test-resources/sap/ui/documentation/sdk/images/HT-1092.jpg` status = `Discontinued` quantity = `50` uom = `PC` currencycode = `EUR` price = `45.00` width = `12.4`
        depth = `10.4` height = `18.1` dimunit = `cm` )

The first 841 lines of 1152 — the whole class is on GitHub.

More in sap.m

Search every abap2UI5 sample · the full list on one page

On this page