Bulletin Board
Worklist app created with the 'Testing' tutorial. - the UI5 demo app "Bulletin Board", rebuilt as one self-contained abap2UI5 class.
Z2UI5_CL_SMPC_DEMO_005
Controls
sap.m
UI5 1.71
The facts
- Repository
- abap2UI5/samples-controls
- Class
Z2UI5_CL_SMPC_DEMO_005- Source file
z2ui5_cl_smpc_demo_005.clas.abap↗- Library
- sap.m
- 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: bulletin, board, app, table, toolbar, label, toolbarspacer, searchfield, column, text, columnlistitem, objectidentifier
Controls it builds
- sap.m.App
- sap.m.Column
- sap.m.ColumnListItem
- sap.m.IconTabBar
- sap.m.IconTabFilter
- sap.m.Label
- sap.m.ObjectHeader
- sap.m.ObjectIdentifier
- sap.m.ObjectNumber
- sap.m.SearchField
- sap.m.Shell
- sap.m.Table
- sap.m.Text
- sap.m.ToggleButton
- sap.m.Toolbar
- sap.m.ToolbarSpacer
- sap.m.semantic.FullscreenPage
- sap.m.semantic.SendEmailAction
- sap.ui.core.mvc.View
- sap.ui.layout.form.SimpleForm
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_demo_005.clas.abap — 613 lines
Click a number to link to a line — shift-click for a range.
Read it on GitHub ↗
" @keywords bulletin board app table toolbar label toolbarspacer searchfield column text columnlistitem objectidentifier
" @summary Worklist app created with the 'Testing' tutorial. - the UI5 demo app "Bulletin Board", rebuilt as one self-contained abap2UI5 class.
" @origin demo app Bulletin Board (sap.m/tutorial/testing) - https://sdk.openui5.org/demoapps (status: generated - machine-written, not yet reviewed)
"! <p class="shorttext">demo app - Bulletin Board</p>
"!
"! The UI5 demo app Bulletin Board - the app the demo kit's "Testing"
"! tutorial builds - rebuilt as ONE abap2UI5 class, page for page and
"! control for control: the Shell and its App, the worklist of posts with
"! its counted table header, its search, its price states, the flag toggle
"! and the e-mail share action, and the post page with its header and the
"! two tabs the tutorial ends on. The original's router is kept: both
"! routes of its manifest.json are calls of route_to( ) here, which puts the
"! same page into the App, forward to the post and back to the worklist.
"!
"! Where it differs from the original, and why - only what an app without a
"! browser-side model layer or a URL cannot do the same way:
"!
"! - the OData V2 service and its mock server become ABAP data - the 23
"! posts of the mock, verbatim. The search keeps the mock server's
"! semantics (a case-sensitive substringof on the Title), the table the
"! sorter's order (Title ascending, compared the way the mock server's
"! `<` does), and the flag is an ordinary two-way bound row field where
"! the original converts the mock's 0/1 with its FlaggedType - a
"! toggle stays in the rows like the pending change of the TwoWay OData
"! model does, and is never written anywhere either.
"! - the formatter module is business logic and moves to the backend: the
"! two-decimal price (numberUnit) and the ValueState its four bands
"! produce (priceState). The post's Timestamp - an Edm.DateTime the
"! OData model hands the untyped Text as a JS Date, which the string
"! property turns into its toString( ) - goes through the curated
"! Formatter.DateCreateObject, so the Text receives the same JS Date and
"! reads exactly as there, in the browser's time zone.
"! - there is no URL, so a route is a method call rather than a hash. The
"! post page's Back button walks the history of the routes taken
"! (myNavBack's history.go(-1)) instead of the browser's, and a deep link
"! to Post/{postId} has nothing that could carry it.
"! - the share action runs sap.m.URLHelper.triggerEmail in the browser, as
"! there, with the same subject and body, and the page URL at startup
"! where onInit reads window.location.href. The line break (\r\n) the
"! body puts before that URL is a blank: abap2UI5's URLHELPER action
"! refuses CR/LF in every parameter, a mail-header injection guard.
"! - the busy handling has nothing to wait for: the App's busy state until
"! the OData metadata has loaded, the post page's busy state while its
"! entity is requested and the worklist table's busyIndicatorDelay that
"! onInit lowers until the first updateFinished. The App's delay of 0
"! (appView>/delay) and the post page's static one are kept.
"! - both views have a page with the id `page`; one view needs unique ids,
"! so they are `worklistPage` and `postPage`.
"! - the i18n resource bundle becomes literals.
"! - the tutorial's OPA5 and QUnit tests have no equivalent: an abap2UI5
"! app is tested with ABAP Unit against the view it builds (see the
"! abap2UI5 insight "ABAP Unit for a screen"), and the demo kit's journeys
"! do not port.
"!
"! Original: src/sap.m/test/sap/m/demokit/tutorial/testing/14 in OpenUI5,
"! archived under ui5/demoapps/sap.m/tutorial/testing.
"! Demo apps: https://sdk.openui5.org/demoapps
CLASS z2ui5_cl_smpc_demo_005 DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES z2ui5_if_app.
" Edm.Decimal, Scale 4
TYPES ty_price TYPE p LENGTH 12 DECIMALS 4.
" one post as a worklist row shows it
TYPES:
BEGIN OF ty_s_row,
postid TYPE string,
title TYPE string,
category TYPE string,
price_text TYPE string,
price_state TYPE string,
currency TYPE string,
flagged TYPE abap_bool,
END OF ty_s_row.
" the post the post page is bound to (Post._onPostMatched's bindElement)
TYPES:
BEGIN OF ty_s_post_view,
title TYPE string,
price_text TYPE string,
currency TYPE string,
timestamp TYPE string,
description TYPE string,
END OF ty_s_post_view.
DATA t_rows TYPE STANDARD TABLE OF ty_s_row WITH EMPTY KEY.
DATA s_post TYPE ty_s_post_view.
" the worklistView model of Worklist.onInit
DATA table_title TYPE string.
DATA share_subject TYPE string.
DATA share_message TYPE string.
PROTECTED SECTION.
TYPES:
BEGIN OF ty_s_post,
postid TYPE string,
title TYPE string,
category TYPE string,
price TYPE ty_price,
currency TYPE string,
flagged TYPE abap_bool,
" Edm.DateTime, the mock's /Date(ms)/ as an ISO date-time in UTC
timestamp TYPE string,
description TYPE string,
END OF ty_s_post.
TYPES:
BEGIN OF ty_s_route,
name TYPE string,
postid TYPE string,
END OF ty_s_route.
DATA client TYPE REF TO z2ui5_if_client.
DATA t_all TYPE STANDARD TABLE OF ty_s_post WITH EMPTY KEY.
" the query of the last search (onFilterPosts)
DATA search_query TYPE string.
" the route on show and the ones before it - what the browser history
" holds there, walked by the Back button
DATA s_route TYPE ty_s_route.
DATA t_history TYPE STANDARD TABLE OF ty_s_route WITH EMPTY KEY.
" the page the App shows, re-issued after a rebuilt view
DATA page_current TYPE string VALUE `worklistPage`.
METHODS view_display.
METHODS page_worklist
IMPORTING
parent TYPE REF TO z2ui5_cl_ui5_view_builder.
METHODS page_post
IMPORTING
parent TYPE REF TO z2ui5_cl_ui5_view_builder.
METHODS on_event.
METHODS route_to
IMPORTING
name TYPE string
postid TYPE string OPTIONAL
replace TYPE abap_bool DEFAULT abap_false.
METHODS nav_back.
METHODS nav_to
IMPORTING
page TYPE string.
METHODS post_bind
IMPORTING
postid TYPE string.
METHODS list_refresh.
METHODS number_unit
IMPORTING
price TYPE ty_price
RETURNING
VALUE(result) TYPE string.
METHODS price_state
IMPORTING
price TYPE ty_price
RETURNING
VALUE(result) TYPE string.
METHODS model_init.
PRIVATE SECTION.
ENDCLASS.
CLASS z2ui5_cl_smpc_demo_005 IMPLEMENTATION.
METHOD z2ui5_if_app~main.
me->client = client.
IF client->check_on_init( ).
model_init( ).
list_refresh( ).
route_to( `worklist` ).
view_display( ).
ELSEIF client->check_on_navigated( ).
view_display( ).
ELSEIF client->check_on_event( ).
on_event( ).
ENDIF.
ENDMETHOD.
METHOD view_display.
" App.view.xml, with the two routing targets - Worklist.view.xml and
" Post.view.xml - as the App's pages. The core:require is the curated
" formatter module the post's Timestamp goes through
DATA(view) = z2ui5_cl_ui5_view_builder=>factory(
)->ele( n = `View` ns = `mvc`
)->a( n = `displayBlock` v = `true`
)->a( n = `height` v = `100%`
)->a( n = `xmlns` v = `sap.m`
)->a( n = `xmlns:mvc` v = `sap.ui.core.mvc`
)->a( n = `xmlns:core` v = `sap.ui.core`
)->a( n = `xmlns:semantic` v = `sap.m.semantic`
)->a( n = `xmlns:form` v = `sap.ui.layout.form`
)->a( n = `core:require` v = `{Formatter: 'z2ui5/model/formatter'}` ).
DATA(app) = view->ele( `Shell`
)->ele( `App`
)->a( n = `id` v = `app`
)->a( n = `busyIndicatorDelay` v = `0` ).
page_worklist( app ).
page_post( app ).
client->view_display( view->stringify( ) ).
" a rebuilt App starts on its first page while the route on show
" survives as class state - re-issue it
IF page_current <> `worklistPage`.
client->follow_up_action( val = client->cs_event-control_by_id
t_arg = VALUE #( ( `app` ) ( `to` ) ( page_current ) ) ).
ENDIF.
ENDMETHOD.
METHOD page_worklist.
" Worklist.view.xml
DATA(page) = parent->ele( n = `FullscreenPage` ns = `semantic`
)->a( n = `id` v = `worklistPage`
)->a( n = `title` v = `Bulletin Board` ).
" the growing table over /Posts, sorted by Title; the header counts the
" rows (onUpdateFinished, done in list_refresh)
DATA(table) = page->ele( n = `content` ns = `semantic`
)->ele( `Table`
)->a( n = `id` v = `table`
)->a( n = `width` v = `auto`
)->a( n = `class` v = `sapUiResponsiveMargin`
)->a( n = `growing` b = abap_true
)->a( n = `items` v = client->_bind( t_rows ) ).
" onFilterPosts: the query travels as the event's argument, the field
" is not bound - as in the original, where nothing binds its value
table->ele( `headerToolbar`
)->ele( `Toolbar`
)->tag( `Label`
)->a( n = `id` v = `tableHeader`
)->a( n = `text` v = client->_bind( table_title )
)->tag( `ToolbarSpacer`
)->tag( `SearchField`
)->a( n = `id` v = `searchField`
)->a( n = `width` v = `auto`
)->a( n = `search` v = client->_event( val = `SEARCH` arg = `${$parameters>/query}` ) ).
table->ele( `columns`
)->ele( `Column`
)->a( n = `id` v = `nameColumn`
)->a( n = `width` v = `33%`
)->a( n = `vAlign` v = `Middle`
)->tag( `Text`
)->a( n = `id` v = `nameColumnTitle`
)->a( n = `text` v = `Name`
)->end(
)->ele( `Column`
)->a( n = `id` v = `categoryColumn`
)->a( n = `width` v = `33%`
)->a( n = `vAlign` v = `Middle`
)->tag( `Text`
)->a( n = `id` v = `categoryColumnTitle`
)->a( n = `text` v = `Category`
)->end(
)->ele( `Column`
)->a( n = `id` v = `unitNumberColumn`
)->a( n = `width` v = `33%`
)->a( n = `hAlign` v = `End`
)->a( n = `vAlign` v = `Middle`
)->tag( `Text`
)->a( n = `id` v = `unitNumberColumnTitle`
)->a( n = `text` v = `Price`
)->end(
)->tag( `Column`
)->a( n = `id` v = `flaggedColumn`
)->a( n = `width` v = `80px`
)->a( n = `demandPopin` b = abap_true
)->a( n = `vAlign` v = `Middle` ).
" onPress: navTo("post") with the pressed row's PostID
table->ele( `items`
)->ele( `ColumnListItem`
)->a( n = `vAlign` v = `Middle`
)->a( n = `type` v = `Navigation`
)->a( n = `press` v = client->_event( val = `POST` arg = `${POSTID}` )
)->ele( `cells`
)->tag( `ObjectIdentifier`
)->a( n = `title` v = `{TITLE}`
)->tag( `Text`
)->a( n = `text` v = `{CATEGORY}`
)->tag( `ObjectNumber`
)->a( n = `number` v = `{PRICE_TEXT}`
)->a( n = `state` v = `{PRICE_STATE}`
)->a( n = `unit` v = `{CURRENCY}`
)->tag( `ToggleButton`
)->a( n = `id` v = `flaggedButton`
)->a( n = `tooltip` v = `Mark this post as flagged`
)->a( n = `icon` v = `sap-icon://flag`
)->a( n = `pressed` v = `{FLAGGED}`
)->a( n = `class` v = `sapUiMediumMarginBeginEnd` ).
" onShareEmailPress: URLHelper.triggerEmail(null, subject, message) with
" the two texts of the worklistView model - in the browser, no round-trip
DATA(share) = |\{ SUBJECT: $\{{ client->_bind_path( share_subject ) }\}, | &&
|BODY: $\{{ client->_bind_path( share_message ) }\} \}|.
page->ele( n = `sendEmailAction` ns = `semantic`
)->tag( n = `SendEmailAction` ns = `semantic`
)->a( n = `id` v = `shareEmail`
)->a( n = `press` v = client->follow_up_action( val = client->cs_event-urlhelper
t_arg = VALUE #( ( `TRIGGER_EMAIL` ) ( share ) ) ) ).
ENDMETHOD.
METHOD page_post.
" Post.view.xml
DATA(content) = parent->ele( n = `FullscreenPage` ns = `semantic`
)->a( n = `id` v = `postPage`
)->a( n = `busyIndicatorDelay` v = `0`
)->a( n = `navButtonPress` v = client->_event( `BACK` )
)->a( n = `showNavButton` b = abap_true
)->a( n = `title` v = `Post`
)->ele( n = `content` ns = `semantic` ).
content->tag( `ObjectHeader`
)->a( n = `id` v = `objectHeader`
)->a( n = `title` v = client->_bind( s_post-title )
)->a( n = `number` v = client->_bind( s_post-price_text )
)->a( n = `numberUnit` v = client->_bind( s_post-currency )
)->a( n = `backgroundDesign` v = `Translucent` ).
DATA(tabs) = content->ele( `IconTabBar`
)->a( n = `id` v = `iconTabBar`
)->a( n = `expanded` v = `{= !${device>/system/phone} }`
)->a( n = `class` v = `sapUiNoContentPadding`
)->ele( `items` ).
" the untyped {Timestamp} of the original shows the JS Date the OData
" model holds; DateCreateObject hands the Text the same Date
tabs->ele( `IconTabFilter`
)->a( n = `icon` v = `sap-icon://hint`
)->a( n = `key` v = `info`
)->ele( n = `SimpleForm` ns = `form`
)->a( n = `layout` v = `ResponsiveGridLayout`
)->ele( n = `content` ns = `form`
)->tag( `Label`
)->a( n = `text` v = `Posted At`
)->tag( `Text`
)->a( n = `text` v = |\{ path: '{ client->_bind_path( s_post-timestamp ) }', formatter: 'Formatter.DateCreateObject' \}|
)->tag( `Label`
)->a( n = `text` v = `Description`
)->tag( `Text`
)->a( n = `text` v = client->_bind( s_post-description ) ).
tabs->ele( `IconTabFilter`
)->a( n = `icon` v = `sap-icon://inspection`
)->a( n = `key` v = `statistics`
)->tag( `Text`
)->a( n = `text` v = `Viewed 55555 times`
)->a( n = `id` v = `viewCounter`
)->a( n = `class` v = `sapUiSmallMargin` ).
ENDMETHOD.
METHOD on_event.
CASE client->get_event( ).
WHEN `SEARCH`.
" onFilterPosts - an empty query removes the filter
search_query = client->get_event_arg( ).
list_refresh( ).
WHEN `POST`.
route_to( name = `post` postid = client->get_event_arg( ) ).
WHEN `BACK`.
" Post.onNavBack
nav_back( ).
ENDCASE.
ENDMETHOD.
METHOD route_to.
" router.navTo( ): what was on show goes onto the history the Back
" button walks - unless the entry is replaced - then the route's target
" is displayed and its pattern-matched handler runs
IF s_route-name IS NOT INITIAL AND replace = abap_false.
INSERT s_route INTO TABLE t_history.
ENDIF.
s_route = VALUE #( name = name postid = postid ).
CASE name.
WHEN `post`.
" Post._onPostMatched
post_bind( postid ).
nav_to( `postPage` ).
WHEN OTHERS.
nav_to( `worklistPage` ).
ENDCASE.
ENDMETHOD.
METHOD nav_back.
" BaseController.myNavBack("worklist"): back in the history if there is
" a previous entry, otherwise to the worklist, replacing the entry
IF t_history IS INITIAL.
route_to( name = `worklist` replace = abap_true ).
RETURN.
ENDIF.
DATA(previous) = t_history[ lines( t_history ) ].
DELETE t_history INDEX lines( t_history ).
s_route = VALUE #( ).
route_to( name = previous-name postid = previous-postid replace = abap_true ).
ENDMETHOD.
METHOD nav_to.
" the targets' levels decide the direction, as sap.m.routing does: the
" post (level 2) slides in with to( ), the worklist (level 1) comes
" back with backToPage( )
IF page = page_current.
RETURN.
ENDIF.
page_current = page.
client->follow_up_action( val = client->cs_event-control_by_id
t_arg = VALUE #( ( `app` )
( COND #( WHEN page = `postPage` THEN `to` ELSE `backToPage` ) )
( page ) ) ).
ENDMETHOD.
METHOD post_bind.
" bindElement("/Posts('<postId>')") - an unknown id leaves the page empty
DATA(post) = VALUE ty_s_post( t_all[ postid = postid ] OPTIONAL ).
s_post = VALUE #( title = post-title
price_text = COND #( WHEN post-postid IS NOT INITIAL THEN number_unit( post-price ) )
currency = post-currency
timestamp = post-timestamp
description = post-description ).
ENDMETHOD.
METHOD list_refresh.
" the flag is bound two-way, so a toggle is already back in the rows -
" carry it into the posts first, so a row the new filter hides keeps it
LOOP AT t_all ASSIGNING FIELD-SYMBOL(<post>).
IF line_exists( t_rows[ postid = <post>-postid ] ).
<post>-flagged = t_rows[ postid = <post>-postid ]-flagged.
ENDIF.
ENDLOOP.
t_rows = VALUE #( ).
LOOP AT t_all INTO DATA(post).
" the Contains filter on Title - the mock server's substringof, which
" is case-sensitive
IF search_query IS NOT INITIAL AND find( val = post-title sub = search_query ) < 0.
CONTINUE.
ENDIF.
INSERT VALUE #( postid = post-postid
title = post-title
category = post-category
price_text = number_unit( post-price )
price_state = price_state( post-price )
currency = post-currency
flagged = post-flagged ) INTO TABLE t_rows.
ENDLOOP.
" the sorter on Title, ascending - binary, like the mock server's `<`
SORT t_rows BY title.
" onUpdateFinished takes the counted title only when the table HAS rows and
" falls back to the plain worklistTableTitle when it is empty
table_title = COND #( WHEN t_rows IS INITIAL THEN `Posts` ELSE |Posts ({ lines( t_rows ) })| ).
ENDMETHOD.
METHOD number_unit.
" formatter.numberUnit: parseFloat(sValue).toFixed(2)
result = |{ price DECIMALS = 2 NUMBER = RAW }|.
ENDMETHOD.
METHOD price_state.
" formatter.priceState: the four price bands
result = COND #( WHEN price < 50 THEN `Success`
WHEN price < 250 THEN `None`
WHEN price < 2000 THEN `Warning`
ELSE `Error` ).
ENDMETHOD.
METHOD model_init.
" Worklist.onInit: the worklistView model's share texts - the message
" carries the app's URL (window.location.href)
DATA(config) = client->get( )-s_config.
share_subject = `<Email subject PLEASE REPLACE ACCORDING TO YOUR USE CASE>`.
share_message = |<Email body PLEASE REPLACE ACCORDING TO YOUR USE CASE> | &&
|{ config-origin }{ config-pathname }{ config-search }{ config-hash }|.
" localService/mockdata/Posts.json - the full row set, the OData
" /Date(ms)/ timestamps converted to the instant they carry
t_all = VALUE #(
( postid = `PostID_1` title = `29'er Mountain Bike (red)` category = `Bicycles`
price = 81 currency = `USD` flagged = abap_false timestamp = `2015-04-05T08:49:40Z`
description = `A great mountainbike, barely used and good as new. Pedals and saddle included` )
( postid = `PostID_2` title = `Football (rare with signatures)` category = `Sports`
price = 420 currency = `EUR` flagged = abap_false timestamp = `2015-04-08T14:46:22Z`
description = `A trophy for collectors, 2014 football with original signatures from the german national soccer team and the spirit of the world cup.` )
( postid = `PostID_3` title = `Video Games` category = `Multimedia`
price = 27 currency = `USD` flagged = abap_false timestamp = `2015-06-03T18:49:53Z`
description = `A collection of 22 classic video games from 1986 to 1992, old but still a lot of fun` )
( postid = `PostID_4` title = `Fluffy Teddy Bear` category = `Toys`
price = 13 currency = `USD` flagged = abap_true timestamp = `2015-04-24T16:27:57Z`
description = `This little companion is looking for a new friend, it is brown and has black eyes. One ear is missing.` )
( postid = `PostID_5` title = `Car Tires, 22 Inch` category = `Car parts`
price = 121 currency = `USD` flagged = abap_false timestamp = `2015-02-10T14:46:02Z`
description = `Spare winter tires for a compact-size car, 4 tires with good profile.` )
( postid = `PostID_6` title = `Garage Door with Blue Stripes, 4m x 2,2m` category = `Car parts`
price = 481 currency = `USD` flagged = abap_true timestamp = `2015-05-14T11:46:11Z`
description = `Good as new, a garage door for a standard double garage, keeps cars dry and carjackers away.` )
( postid = `PostID_7` title = `Kids Toys, a Whole Box of Stuff` category = `Toys`
price = 63 currency = `USD` flagged = abap_false timestamp = `2015-06-29T18:43:35Z`
description = `Best suited for kids aged from 4-10, a whole box of toys including model cars, marble balls, toy figures, and much more.` )
( postid = `PostID_8` title = `Screwdrivers` category = `Miscellaneous`
price = 28 currency = `USD` flagged = abap_false timestamp = `2015-08-11T06:08:54Z`
description = `20-Piece Multibit Ratcheting Screwdriver Set` )
( postid = `PostID_9` title = `Comfortable Bike Saddle` category = `Bicycles`
price = 25 currency = `USD` flagged = abap_false timestamp = `2015-03-17T15:35:23Z`
description = `A brand-new, unused bike saddle with black covering` )
( postid = `PostID_10` title = `Bike Rack` category = `Bicycles`
price = 106 currency = `USD` flagged = abap_true timestamp = `2015-04-24T10:23:41Z`
description = `Suitable for camper or RV, used` )
( postid = `PostID_11` title = `DVD: Trains of Europe` category = `Multimedia`
price = 61 currency = `USD` flagged = abap_false timestamp = `2015-03-04T05:14:18Z`
description = `An amazing collection of train models all around Europe, total runtime 412 minutes.` )
( postid = `PostID_12` title = `Matress` category = `Miscellaneous`
price = 306 currency = `USD` flagged = abap_false timestamp = `2015-06-29T21:18:30Z`
description = `Bed Mattress 30 x 70 inch, filled with natural fibers, barely used` )
( postid = `PostID_13` title = `High-End Gamer PC` category = `Furniture`
price = 256 currency = `USD` flagged = abap_false timestamp = `2015-07-09T09:47:42Z`
description = `3Ghz dual core, 16gb RAM, high tower. Great for playing the latest games.` )
( postid = `PostID_14` title = `Cooking Pot Set` category = `Miscellaneous`
price = 234 currency = `USD` flagged = abap_false timestamp = `2015-04-02T01:32:28Z`
description = `Stainless steel cooking pots (10 pcs) with a matching lid each.` )
( postid = `PostID_15` title = `Jeans` category = `Clothing`
price = 34 currency = `EUR` flagged = abap_false timestamp = `2015-07-19T04:27:48Z`
description = `Used-look Jeans european size 32x34, only worn once.` )
( postid = `PostID_16` title = `Moving Boxes` category = `Miscellaneous`
price = 60 currency = `USD` flagged = abap_false timestamp = `2015-02-23T01:06:33Z`
description = `100 Cardboard boxes perfect for relocating, only used once and in a pretty good shape.` )
( postid = `PostID_17` title = `Car VW Golf (white)` category = `Car Parts`
price = 3006 currency = `USD` flagged = abap_false timestamp = `2015-07-15T02:23:39Z`
description = `Only 160.000 km and in really good shape, grip shift, contact me for appointment and more details.` )
( postid = `PostID_18` title = `Swimming Pool` category = `Miscellaneous`
price = 4587 currency = `USD` flagged = abap_false timestamp = `2015-07-09T00:44:01Z`
description = `Perfect for your very own pool parties in the garden, measures: 5x10m, fill with ~500.000l water and enjoy.` )
( postid = `PostID_19` title = `Travel Suitcases` category = `Miscellaneous`
price = 560 currency = `USD` flagged = abap_false timestamp = `2015-03-20T07:52:18Z`
description = `New and in original packaging, a set of 5 high-quality suitcases from small to large sizes.` )
( postid = `PostID_20` title = `Rainbow Stickers` category = `Miscellaneous`
price = 45 currency = `USD` flagged = abap_true timestamp = `2015-05-07T01:22:13Z`
description = `A vast collection of rainbow stickers for collectors, about 2.000 individual pieces in all shapes and sizes` )
( postid = `PostID_21` title = `Notebook` category = `Multimedia`
price = 23 currency = `USD` flagged = abap_false timestamp = `2015-07-30T20:05:26Z`
description = `Used notebook with broken display, needs repair. A bargain for the DIY tech guy.` )
( postid = `PostID_22` title = `Plasma TV 60"!` category = `Multimedia`
price = 360 currency = `USD` flagged = abap_false timestamp = `2015-03-04T20:37:48Z`
description = `I got a larger one, so selling this one cheap for all the movie lovers out there` )
( postid = `PostID_23` title = `Cheap Boat` category = `Miscellaneous`
price = 26263 currency = `USD` flagged = abap_false timestamp = `2015-08-14T14:08:33Z`
description = `Living close to a lake or the ocean? This dream of a yacht (30ft long!) comes with lots of extras. Get it and fulfill yourself a dream.` )
).
ENDMETHOD.
ENDCLASS.
More in sap.m
- Combo box with value state — The combo box can show different value states.
- Icon Tab Bar - Background Design — In this example the backgroundDesign and headerBackgroundDesign properties are demonstrat…
- Icon Tab Bar - Process — In this example, the Icon Tab Bar is used to apply filters on the same content along a bu…
- Icon Tab Bar - Responsive Padding — This example demonstrates the Icon Tab Bar's support for paddings that depend on the widt…
- Icon Tab Bar - Tab Density Mode — In this example, the Icon Tab Bar is used in different tab density modes.
- Input - Assisted Tabular Suggestions — In this example assisted input is provided with table-like suggestions where several colu…
- Input - Checked — Input checks are handled via the validation of the data binding. In this example there ar…
- Input - States — This example demonstrates the different input field states, e.g. disabled, editable, with…
- Manage Products — Created with the 'Worklist App' tutorial. - the UI5 demo app "Manage Products", rebuilt a…
- Browse Orders — Master-detail app for browsing orders. - the UI5 demo app "Browse Orders", rebuilt as one…
- Team Calendar — Calendar demo app for team and team members. - the UI5 demo app "Team Calendar", rebuilt…
- Shopping Cart — The classic business process of finding and ordering products. - the UI5 demo app "Shoppi…
On this page