From 84533639b6584ce4090c77a121f92305441b9bf9 Mon Sep 17 00:00:00 2001 From: oblomov <102328295+oblomov-dev@users.noreply.github.com> Date: Mon, 12 Jun 2023 19:30:24 +0200 Subject: [PATCH] update (#268) * update * update * update * update * update * update * commit * update * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * update * update * update * update * update --- README.md | 47 ++- src/z2ui5_cl_app_hello_world.clas.abap | 4 - src/z2ui5_cl_http_handler.clas.abap | 5 +- ...z2ui5_cl_http_handler.clas.locals_imp.abap | 277 +++++++++++++----- ...2ui5_cl_http_handler.clas.testclasses.abap | 10 +- 5 files changed, 224 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 8b1fd68a..ad1a63a4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # abap2UI5 -Developing UI5 Apps in pure ABAP - follow this project on [**twitter**](https://twitter.com/OblomovDev) to keep up to date and don't forget to explore the [**demo repository**.](https://github.com/oblomov-dev/abap2UI5-demos) +image

+Follow this project on [**twitter**](https://twitter.com/OblomovDev) to keep up to date and don't forget to explore the [**demo repository** :flashlight:](https://github.com/oblomov-dev/abap2UI5-demos) #### Features * easy to use – implement just one interface for a standalone UI5 application * pure ABAP – development using 100% ABAP (no JavaScript, DDL, EML or Customizing) @@ -35,31 +36,9 @@ Developing UI5 Apps in pure ABAP - follow this project on [**twitter**](https:// * Development of UI5 Selection Screens in pure ABAP (former version) [(SCN - 22.01.2023)](https://blogs.sap.com/2023/01/22/abap2ui5-project-development-of-ui5-selection-screens-in-pure-abap-no-app-deployment-or-javascript-needed/) * [work-in-progress] Launchpad integration with the following extension [(abap2UI5_ext-launchpad)](https://github.com/oblomov-dev/abap2UI5_ext-launchpad_app) -#### Demo - - #### Installation -Install with [abapGit](https://abapgit.org), create a new HTTP service and replace the handler method with the following code snippet. For more information, check out this [documentation.](https://blogs.sap.com/2023/04/14/abap2ui5-6-7-installation-configuration-debugging/) - -##### ABAP for Cloud: -```abap -METHOD if_http_service_extension~handle_request. - - z2ui5_cl_http_handler=>client = VALUE #( - t_header = request->get_header_fields( ) - t_param = request->get_form_fields( ) - body = request->get_text( ) ). - - DATA(lv_resp) = SWITCH #( request->get_method( ) - WHEN 'GET' THEN z2ui5_cl_http_handler=>http_get( ) - WHEN 'POST' THEN z2ui5_cl_http_handler=>http_post( ) ). - - response->set_status( 200 )->set_text( lv_resp ). - -ENDMETHOD. -``` - -##### Standard ABAP: +Install with [abapGit](https://abapgit.org) ![abapGit](https://docs.abapgit.org/img/favicon.png), create a new HTTP service and replace the handler method with the following code snippet: +##### Standard ABAP :computer: ```abap METHOD if_http_extension~handle_request. @@ -81,9 +60,27 @@ METHOD if_http_extension~handle_request. server->response->set_cdata( lv_resp ). server->response->set_status( code = 200 reason = 'success' ). +ENDMETHOD. +``` +##### ABAP for Cloud :cloud: +```abap +METHOD if_http_service_extension~handle_request. + + z2ui5_cl_http_handler=>client = VALUE #( + t_header = request->get_header_fields( ) + t_param = request->get_form_fields( ) + body = request->get_text( ) ). + + DATA(lv_resp) = SWITCH #( request->get_method( ) + WHEN 'GET' THEN z2ui5_cl_http_handler=>http_get( ) + WHEN 'POST' THEN z2ui5_cl_http_handler=>http_post( ) ). + + response->set_status( 200 )->set_text( lv_resp ). + ENDMETHOD. ``` #### FAQ +* check out this [documentation](https://blogs.sap.com/2023/04/14/abap2ui5-6-7-installation-configuration-debugging/) for detailed installation guidelines
* read these [instructions](https://blogs.sap.com/2023/02/22/abap2ui5-development-of-ui5-apps-in-pure-abap-1-3/) when you develop your first app
* want to configure the theme, bootstrapping, language and title? see [configuration & debugging](https://blogs.sap.com/2023/04/14/abap2ui5-6-7-installation-configuration-debugging/) * as always - your comments, questions, wishes and bugs are welcome, please create an [issue](https://github.com/oblomov-dev/ABAP2UI5/issues) diff --git a/src/z2ui5_cl_app_hello_world.clas.abap b/src/z2ui5_cl_app_hello_world.clas.abap index 18bdbf3f..7debe36b 100644 --- a/src/z2ui5_cl_app_hello_world.clas.abap +++ b/src/z2ui5_cl_app_hello_world.clas.abap @@ -8,15 +8,11 @@ CLASS z2ui5_cl_app_hello_world DEFINITION PUBLIC. DATA quantity TYPE string. DATA check_initialized TYPE abap_bool. - PROTECTED SECTION. - PRIVATE SECTION. ENDCLASS. - CLASS Z2UI5_CL_APP_HELLO_WORLD IMPLEMENTATION. - METHOD z2ui5_if_app~main. IF check_initialized = abap_false. diff --git a/src/z2ui5_cl_http_handler.clas.abap b/src/z2ui5_cl_http_handler.clas.abap index 568bd276..5f984103 100644 --- a/src/z2ui5_cl_http_handler.clas.abap +++ b/src/z2ui5_cl_http_handler.clas.abap @@ -95,9 +95,6 @@ CLASS Z2UI5_CL_HTTP_HANDLER IMPLEMENTATION. ` onAfterRendering: function () {` && |\n| && ` sap.z2ui5.onAfter();` && |\n| && ` },` && |\n| && - ` do: function (value) {` && |\n| && - ` return value;` && |\n| && - ` },` && |\n| && ` onEventFrontend: function (vAction) {` && |\n| && |\n| && ` if (vAction == 'POPUP_CLOSE') {` && |\n| && @@ -191,7 +188,7 @@ CLASS Z2UI5_CL_HTTP_HANDLER IMPLEMENTATION. ` return;` && |\n| && ` }` && |\n| && |\n| && - ` var oModel = new sap.ui.model.json.JSONModel(sap.z2ui5.oResponse.OVIEWMODEL.oViewModel);` && |\n| && + ` var oModel = new sap.ui.model.json.JSONModel(sap.z2ui5.oResponse.OVIEWMODEL);` && |\n| && ` var oView = new sap.ui.core.mvc.XMLView.create({` && |\n| && ` definition: sap.z2ui5.oResponse.PARAMS.XML_MAIN,` && |\n| && ` }).then(oView => {` && |\n| && diff --git a/src/z2ui5_cl_http_handler.clas.locals_imp.abap b/src/z2ui5_cl_http_handler.clas.locals_imp.abap index 4aa566af..ab9495d2 100644 --- a/src/z2ui5_cl_http_handler.clas.locals_imp.abap +++ b/src/z2ui5_cl_http_handler.clas.locals_imp.abap @@ -761,6 +761,8 @@ CLASS z2ui5_lcl_fw_handler DEFINITION. RETURNING VALUE(result) TYPE REF TO z2ui5_lcl_fw_handler. + + METHODS set_app_leave RETURNING VALUE(result) TYPE REF TO z2ui5_lcl_fw_handler. @@ -777,9 +779,18 @@ CLASS z2ui5_lcl_fw_handler DEFINITION. RETURNING VALUE(result) TYPE REF TO z2ui5_lcl_fw_handler. - METHODS request_end_model + CLASS-METHODS bind_front_2_back + IMPORTING + lo_model TYPE REF TO z2ui5_lcl_utility_tree_json + lo_app TYPE REF TO object + t_attri TYPE z2ui5_lcl_utility=>ty_t_attri ##NEEDED. + + CLASS-METHODS bind_back_2_front + IMPORTING + lo_app TYPE REF TO object + t_attri TYPE z2ui5_lcl_utility=>ty_t_attri RETURNING - VALUE(r_view_model) TYPE REF TO z2ui5_lcl_utility_tree_json. + VALUE(result) TYPE string ##NEEDED. PROTECTED SECTION. PRIVATE SECTION. @@ -1150,6 +1161,7 @@ CLASS z2ui5_lcl_fw_db IMPLEMENTATION. ENDLOOP. + DATA(ls_db) = VALUE z2ui5_t_draft( uuid = id uuid_prev = db-id_prev @@ -1245,31 +1257,23 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. lo_resp->add_attribute( n = `PARAMS` v = z2ui5_lcl_utility=>trans_any_2_json( ms_next-s_set ) apos_active = abap_false ). lo_resp->add_attribute( n = `S_MSG` v = z2ui5_lcl_utility=>trans_any_2_json( ms_next-s_msg ) apos_active = abap_false ). lo_resp->add_attribute( n = `ID` v = ms_db-id ). - lo_resp->add_attribute_object( `OVIEWMODEL` )->add_attribute_instance( request_end_model( ) ). + + lo_resp->add_attribute( n = `OVIEWMODEL` v = bind_back_2_front( lo_app = ms_db-o_app t_attri = ms_db-t_attri ) apos_active = abap_false ). result = lo_resp->get_root( )->stringify( ). + + DELETE ms_db-t_attri WHERE bind_type = cs_bind_type-one_time. z2ui5_lcl_fw_db=>create( id = ms_db-id db = ms_db ). ENDMETHOD. - METHOD set_app_client. + METHOD bind_front_2_back. CONSTANTS c_prefix TYPE string VALUE `LO_APP->`. - result = NEW #( ). - result->ms_db-id = z2ui5_lcl_utility=>get_uuid( ). - DATA(lv_id) = result->ms_db-id. - result->ms_db = z2ui5_lcl_fw_db=>load_app( id_prev ). - result->ms_db-id = lv_id. - result->ms_db-id_prev = id_prev. - - DATA(lo_app) = CAST object( result->ms_db-o_app ) ##NEEDED. - TRY. - DATA(lo_model) = mo_body->get_attribute( `OUPDATE` ). - - LOOP AT result->ms_db-t_attri REFERENCE INTO DATA(lr_attri) + LOOP AT t_attri REFERENCE INTO DATA(lr_attri) WHERE bind_type = cs_bind_type-two_way. FIELD-SYMBOLS TYPE any. @@ -1321,6 +1325,80 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. CATCH cx_root. ENDTRY. + ENDMETHOD. + + + METHOD bind_back_2_front. + + CONSTANTS c_prefix TYPE string VALUE `LO_APP->`. + + DATA(r_view_model) = z2ui5_lcl_utility_tree_json=>factory( ). + r_view_model->mv_name = `oViewModel`. + DATA(lo_update) = r_view_model->add_attribute_object( `oUpdate` ). + + LOOP AT t_attri REFERENCE INTO DATA(lr_attri) WHERE bind_type <> ``. + + IF lr_attri->bind_type = cs_bind_type-one_time. + r_view_model->add_attribute( n = lr_attri->name v = lr_attri->data_stringify apos_active = abap_false ). + CONTINUE. + ENDIF. + + DATA(lo_actual) = COND #( WHEN lr_attri->bind_type = cs_bind_type-one_way + THEN r_view_model + ELSE lo_update ). + + FIELD-SYMBOLS TYPE any. + DATA(lv_name) = c_prefix && to_upper( lr_attri->name ). + ASSIGN (lv_name) TO . + z2ui5_lcl_utility=>raise( when = xsdbool( sy-subrc <> 0 ) ). + + IF lr_attri->gen_kind IS NOT INITIAL. + lv_name = '->*'. + ASSIGN (lv_name) TO . + lr_attri->type_kind = lr_attri->gen_type_kind. + ENDIF. + + CASE lr_attri->type_kind. + + WHEN `h`. + lo_actual->add_attribute( n = lr_attri->name + v = z2ui5_lcl_utility=>trans_any_2_json( ) + apos_active = abap_false ). + + WHEN OTHERS. + + CASE lr_attri->type. + + WHEN `ABAP_BOOL` OR `ABAP_BOOLEAN` OR `XSDBOOLEAN`. + + lo_actual->add_attribute( + n = lr_attri->name + v = SWITCH #( WHEN abap_true THEN `true` ELSE `false` ) + apos_active = abap_false ). + + WHEN OTHERS. + + lo_actual->add_attribute( + n = lr_attri->name + v = /ui2/cl_json=>serialize( ) + apos_active = abap_false ). + ENDCASE. + ENDCASE. + ENDLOOP. + + result = r_view_model->stringify( ). + + ENDMETHOD. + + + METHOD set_app_client. + + result = NEW #( ). + result->ms_db-id = z2ui5_lcl_utility=>get_uuid( ). + DATA(lv_id) = result->ms_db-id. + result->ms_db = z2ui5_lcl_fw_db=>load_app( id_prev ). + result->ms_db-id = lv_id. + result->ms_db-id_prev = id_prev. DATA(lo_arg) = mo_body->get_attribute( `ARGUMENTS` ). TRY. @@ -1344,6 +1422,12 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. CATCH cx_root. ENDTRY. + bind_front_2_back( + lo_model = mo_body->get_attribute( `OUPDATE` ) + lo_app = result->ms_db-o_app + t_attri = result->ms_db-t_attri + ). + ENDMETHOD. @@ -1367,7 +1451,6 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. ENDIF. TRY. - TRY. CREATE OBJECT result->ms_db-o_app TYPE (lv_classname). CATCH cx_root. @@ -1539,70 +1622,6 @@ CLASS z2ui5_lcl_fw_handler IMPLEMENTATION. ENDMETHOD. - - METHOD request_end_model. - - CONSTANTS c_prefix TYPE string VALUE `LO_APP->`. - - DATA(lo_app) = CAST object( ms_db-o_app ) ##NEEDED. - r_view_model = z2ui5_lcl_utility_tree_json=>factory( ). - r_view_model->mv_name = `oViewModel`. - DATA(lo_update) = r_view_model->add_attribute_object( `oUpdate` ). - - LOOP AT ms_db-t_attri REFERENCE INTO DATA(lr_attri) WHERE bind_type <> ``. - - IF lr_attri->bind_type = cs_bind_type-one_time. - r_view_model->add_attribute( n = lr_attri->name v = lr_attri->data_stringify apos_active = abap_false ). - CONTINUE. - ENDIF. - - DATA(lo_actual) = COND #( WHEN lr_attri->bind_type = cs_bind_type-one_way - THEN r_view_model - ELSE lo_update ). - - FIELD-SYMBOLS TYPE any. - DATA(lv_name) = c_prefix && to_upper( lr_attri->name ). - ASSIGN (lv_name) TO . - z2ui5_lcl_utility=>raise( when = xsdbool( sy-subrc <> 0 ) ). - - IF lr_attri->gen_kind IS NOT INITIAL. - lv_name = '->*'. - ASSIGN (lv_name) TO . - lr_attri->type_kind = lr_attri->gen_type_kind. - ENDIF. - - CASE lr_attri->type_kind. - - WHEN `h`. - lo_actual->add_attribute( n = lr_attri->name - v = z2ui5_lcl_utility=>trans_any_2_json( ) - apos_active = abap_false ). - - WHEN OTHERS. - - CASE lr_attri->type. - - WHEN `ABAP_BOOL` OR `ABAP_BOOLEAN` OR `XSDBOOLEAN`. - - lo_actual->add_attribute( - n = lr_attri->name - v = SWITCH #( WHEN abap_true THEN `true` ELSE `false` ) - apos_active = abap_false ). - - WHEN OTHERS. - - lo_actual->add_attribute( - n = lr_attri->name - v = /ui2/cl_json=>serialize( ) - apos_active = abap_false ). - ENDCASE. - ENDCASE. - ENDLOOP. - - DELETE ms_db-t_attri WHERE bind_type = cs_bind_type-one_time. - - ENDMETHOD. - ENDCLASS. CLASS z2ui5_lcl_fw_client IMPLEMENTATION. @@ -1720,3 +1739,99 @@ CLASS z2ui5_lcl_fw_client IMPLEMENTATION. ENDMETHOD. ENDCLASS. + +CLASS z2ui5_lcl_fw_view DEFINITION. + + PUBLIC SECTION. + CLASS-METHODS read_view + RETURNING + VALUE(result) TYPE string. +ENDCLASS. + +CLASS z2ui5_lcl_fw_view IMPLEMENTATION. + + METHOD read_view. + + result = ` <Label ` && |\n| && + ` text="quantity" ` && |\n| && + ` /> <Input ` && |\n| && + ` value="onEvent( {/oUpdate/QUANTITY} )` && |\n| && + ` /> <Label ` && |\n| && + ` text="product" ` && |\n| && + ` /> <Input ` && |\n| && + ` enabled="false" ` && |\n| && + ` value="{VALUE}" ` && |\n| && + ` /> <Button ` && |\n| && + ` press="onEvent( { 'EVENT' : 'BUTTON_POST', 'METHOD' : 'UPDATE' , 'isHoldView' : false })" ` && |\n| && + ` text="post" ` && |\n| && + ` /></form:content></form:SimpleForm></Page></Shell></mvc:View>`. + ENDMETHOD. + +ENDCLASS. + +CLASS z2ui5_lcl_fw_view_app DEFINITION. + + PUBLIC SECTION. + INTERFACES z2ui5_if_app. + + DATA quantity TYPE string VALUE `10` ##NEEDED. +ENDCLASS. + +CLASS z2ui5_lcl_fw_view_app IMPLEMENTATION. + + METHOD z2ui5_if_app~main. + + DATA(lt_attri) = z2ui5_lcl_utility=>get_t_attri_by_ref( me ). + DATA(lv_view) = z2ui5_lcl_fw_view=>read_view( ). + + SPLIT lv_view AT `{` INTO TABLE DATA(lt_view). + DELETE lt_view INDEX 1. + + LOOP AT lt_view INTO DATA(lr_view). + SPLIT lr_view AT `}` INTO lr_view DATA(lv_dummy). + + LOOP AT lt_attri REFERENCE INTO DATA(lr_attri). + IF lr_view = `/oUpdate/` && lr_attri->name. + lr_attri->bind_type = z2ui5_lcl_fw_handler=>cs_bind_type-two_way. + CONTINUE. + ENDIF. + + IF lr_view = lr_attri->name. + lr_attri->bind_type = z2ui5_lcl_fw_handler=>cs_bind_type-one_way. + CONTINUE. + ENDIF. + ENDLOOP. + ENDLOOP. + + client->set_next( VALUE #( xml_main = lv_view ) ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/z2ui5_cl_http_handler.clas.testclasses.abap b/src/z2ui5_cl_http_handler.clas.testclasses.abap index b6d391fe..bb9671a9 100644 --- a/src/z2ui5_cl_http_handler.clas.testclasses.abap +++ b/src/z2ui5_cl_http_handler.clas.testclasses.abap @@ -522,7 +522,7 @@ CLASS ltcl_unit_02_app_start IMPLEMENTATION. FIELD-SYMBOLS <val> TYPE any. UNASSIGN <val>. - DATA(lv_assign) = `OVIEWMODEL->OVIEWMODEL->QUANTITY->*`. + DATA(lv_assign) = `OVIEWMODEL->QUANTITY->*`. ASSIGN lo_data->(lv_assign) TO <val>. IF <val> <> `500`. cl_abap_unit_assert=>fail( msg = 'data binding - initial set oUpdate wrong' quit = 5 ). @@ -548,7 +548,7 @@ CLASS ltcl_unit_02_app_start IMPLEMENTATION. FIELD-SYMBOLS <val> TYPE any. UNASSIGN <val>. - DATA(lv_assign) = `OVIEWMODEL->OVIEWMODEL->OUPDATE->QUANTITY->*`. + DATA(lv_assign) = `OVIEWMODEL->OUPDATE->QUANTITY->*`. ASSIGN lo_data->(lv_assign) TO <val>. IF <val> <> `500`. cl_abap_unit_assert=>fail( msg = 'data binding - initial set oUpdate wrong' quit = 5 ). @@ -907,7 +907,7 @@ CLASS ltcl_unit_03_app_ajax IMPLEMENTATION. data = lo_data ). UNASSIGN <val>. - lv_assign = `OVIEWMODEL->OVIEWMODEL->OUPDATE->QUANTITY->*`. + lv_assign = `OVIEWMODEL->OUPDATE->QUANTITY->*`. ASSIGN lo_data->(lv_assign) TO <val>. IF <val> <> `600`. cl_abap_unit_assert=>fail( msg = 'data binding - frontend updated value wrong after roundtrip' quit = 5 ). @@ -1071,7 +1071,7 @@ CLASS ltcl_unit_04_deep_data IMPLEMENTATION. UNASSIGN <val>. FIELD-SYMBOLS <tab> TYPE STANDARD TABLE. FIELD-SYMBOLS <row> TYPE REF TO data. - DATA(lv_assign) = `OVIEWMODEL->OVIEWMODEL->T_TAB->*`. + DATA(lv_assign) = `OVIEWMODEL->T_TAB->*`. ASSIGN lo_data->(lv_assign) TO <tab>. ASSIGN <tab>[ 1 ] TO <row>. @@ -1119,7 +1119,7 @@ CLASS ltcl_unit_04_deep_data IMPLEMENTATION. UNASSIGN <val>. FIELD-SYMBOLS <tab> TYPE STANDARD TABLE. FIELD-SYMBOLS <row> TYPE REF TO data. - DATA(lv_assign) = `OVIEWMODEL->OVIEWMODEL->OUPDATE->T_TAB->*`. + DATA(lv_assign) = `OVIEWMODEL->OUPDATE->T_TAB->*`. ASSIGN lo_data->(lv_assign) TO <tab>. ASSIGN <tab>[ 1 ] TO <row>.