Following on from Part 1 (Build your first Mobile web app using jQuery Mobile and ABAP - Part 1) and Part 2 (Build your first Mobile web app using jQuery Mobile and ABAP - Part 2), we finally explore a basic UPDATE scenario for our Mobile web app using jQuery Mobile and ABAP BSP.
Firstly I should acknowledge my good colleague Abhinav Tayal (below) with whom I collaborated to produce this final part of the blog series. Abhinav previously worked with SAP Labs developing BSP applications and so I appreciated his thoughts and guidance on the server-side processing to bring this final part of the blog series to completion.
OK, in Part 2 we built 3 HCM employee self-service display scenarios (display Org details, Address details, Absence bookings) for our Smartphone / Tablet using jQuery Mobile and BSP ABAP. If you followed the steps you should have accomplished this within an hour or two. We ended up with a functioning Mobile Web App and appreciated the power that a lightweight framework such as jQuery Mobile (along with HTML5/CSS3) could bring to the UI. And did you notice we didn't need to write a single line of Javascript? The jQuery Mobile framework did the heavy lifting in this respect.
In this part we will need to add a little Javascript. We will deal with that when we extend the view layout.
To begin with however we will commence with extending the model class with a method to be able to update your Address ...
MODEL
Extend the model class ZCL_MOBILE_DEMO_MODEL that you created in Part 2 as follows ...
METHOD set_address.
DATA: lock_return TYPE bapireturn1,
bapi_return TYPE bapireturn1.
* Lock the employee record
CALL FUNCTION 'BAPI_EMPLOYEE_ENQUEUE'
EXPORTING
number = address_data-pernr
IMPORTING
return = lock_return.
IF lock_return IS NOT INITIAL.
message = 'Cannot lock employee record - please try again later'.
RETURN.
ENDIF.
* Execute the address change
CALL FUNCTION 'BAPI_ADDRESSEMP_CHANGE'
EXPORTING
employeenumber = address_data-pernr
subtype = address_data-subty
objectid = address_data-objps
lockindicator = address_data-sprps
validitybegin = address_data-begda
validityend = address_data-endda
recordnumber = address_data-seqnr
* CONAME =
streetandhouseno = address_data-stras
* SCNDADDRESSLINE =
city = address_data-ort01
* DISTRICT =
postalcodecity = address_data-pstlz
state = address_data-state
* COUNTRY =
* TELEPHONENUMBER =
* NOCOMMIT =
IMPORTING
return = bapi_return.
* Capture the return message
if bapi_return is initial.
m_address_data = address_data.
message = ''.
else.
message = bapi_return.
return.
endif.
* Unlock the employee record
CALL FUNCTION 'BAPI_EMPLOYEE_DEQUEUE'
EXPORTING
number = address_data-pernr.
ENDMETHOD.
CONTROLLER
Extend the BSP controller class ZCL_MOBILE_DEMO_CONTROLLER as follows ...
METHOD process_input.
* Data declaration
DATA: l_view TYPE REF TO if_bsp_page,
ls_field TYPE ihttpnvp,
new_address TYPE BAPIP0006.
* Refresh model if necessary
IF m_mobile_model IS NOT BOUND.
do_init( ).
ENDIF.
* Initialise new_address to be the same as the existing address
new_address = m_mobile_model->m_address_data.
* Street
READ TABLE lt_fields WITH KEY name = 'street' INTO ls_field.
IF sy-subrc = 0.
new_address-stras = ls_field-value.
ENDIF.
* City
READ TABLE lt_fields WITH KEY name = 'city' INTO ls_field.
IF sy-subrc = 0.
new_address-ort01 = ls_field-value.
ENDIF.
* State
READ TABLE lt_fields WITH KEY name = 'state' INTO ls_field.
IF sy-subrc = 0.
new_address-state = ls_field-value.
ENDIF.
* Postcode
READ TABLE lt_fields WITH KEY name = 'postcode' INTO ls_field.
IF sy-subrc = 0.
new_address-pstlz = ls_field-value.
ENDIF.
CALL METHOD m_mobile_model->set_address
EXPORTING
address_data = new_address
RECEIVING
message = m_message.
l_view = create_view( view_name = 'message.xml').
* Set the message
l_view->set_attribute( name = 'lv_message' value = m_message ).
* Call the view
call_view( l_view ).
ENDMETHOD.
METHOD do_request.
.... where we previously had ...
ELSE.
* Process input fields
* Ignore this at this stage for Part 2 of the blog
ENDIF.
.... change this to ...
ELSE.
* Process input fields
process_input( lt_fields ).
ENDIF.
VIEW
Now hopefully in the controller class method PROCESS_INPUT you noticed we are calling a new view 'message.xml'. We now need to declare this as follows for the BSP Application ZMOBILE_DEMO ...
<?xml version="1.0" encoding="UTF-8" ?>
<return>
<% if lv_message is initial. %>
<result>0</result>
<message>Record updated successfully</message>
<% else. %>
<result>1</result>
<message><%= lv_message %></message>
<% endif. %>
</return>
Finally, we need to enrich the original view layout for 'main.htm' with some Javascript. I made the decision to hijack the form submission when a user presses the 'Save' button for the Address Update page using jQuery and to submit the data explicitly via an Ajax call to the ABAP server. In this case the call is made directly back to the BSP application controller and handled there (via DO_REQUEST and subsequently PROCESS_INPUT), however the call could just as readily have been made to an alternate web service, such as (for instance) the future Gateway product which is released in 2011 (although the calls would need to be framed around REST principles).
<!DOCTYPE html>
<html>
<head>
<title>Mobile Demo</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css"></link>
<script src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script>
<!-- New script declaration for Part 3 below ... -->
<script type="text/javascript">
// Event registration
$(function() {
// Register event for handling submit of address updates
$('#address_update').submit(function() {
// Compile data to send to SAP server
var dataString = '&street=' + $("input#street").val() +
'&city=' + $("input#city").val() +
'&state=' + $("input#state").val() +
'&postcode=' + $("input#postcode").val();
// Initiate page loading animation
$.mobile.pageLoading();
// Perform posting to SAP server
$.ajax({
type: "POST",
url: "mobilemain.do",
data: dataString,
success: function(xml){
// Disable page loading animation
$.mobile.pageLoading(false);
// Process return page
// Evaluate the return code from the return xml
if ($(xml).find("result").text() == "0") {
// If successful update the relevant address in the HTML DOM
$('#display_street').text($("input#street").val());
$('#display_city').text($("input#city").val());
$('#display_state').text($("input#state").val());
$('#display_postcode').text($("input#postcode").val());
}
// Extract the return message text from the return xml
var msg = ($(xml).find("message").text());
// Set the return message
$('#return_message').text(msg);
// Popup the message dialog
$.mobile.changePage("#message", "pop");
// Return to the employee address page
$.mobile.changePage("#emp_address", "slide");
} // Return message
}); // Ajax posting
}); // Submit handler
}); // Event registration
</script>
</head>
.... etc etc.
Execute your BSP application. If you are able to visualise it using a browser such as Safari (avoid Internet Explorer because the user experience is very poor) or even better a Smartphone such as an iPhone or Android, it should behave something like this YouTube video ...
ARCHITECTURAL THOUGHTS
In reality there are a multitude of architectural design approaches that could be used to execute the UPDATE scenario, and the one described in this blog is simplistic and would need additional work to enable it to scale for multiple scenarios. Nonetheless I have this working and have decided to document it rather than waiting to build the perfect architecture.
In my discussions with Abhinav some of the concerns we toyed with included ...
CONCLUSION
Notwithstanding that the solution we have built would need additional work to make it deployable (as indicated throughout the blog I have simplified it here, removing error handling etc), you can see that with a relatively small quantity of ABAP, HTML and Javascript, you can build a fully functional Mobile web app from your ABAP server. It took only a couple of days to build this solution which includes 3 scenarios (and documented here it should take you less than a couple of hours to do the same). Think about how many you could build in a couple of weeks, and the value that this could bring to your organisation.
Here are some possibilities (all of which are very achievable - I already have pursued some of these ...)
There are also additional HTML5 FEATURES that you could incorporate to extend this solution, to improve the offline capability of the web application. Some of these include the offline database storage capabilities of HTML5, as well as the cache manifest concept which permits web pages to be stored locally on the client and accessed when there is no network connection. In fact it was leveraging these features which helped SAP Mentor Matt Harding and Alisdair Templeton to win the Las Vegas TechEd 2010 Demo Jam prize this year.
Hopefully you have found this blog series to have been somewhat useful. It documents my experience investigating the world of mobile web app development (in an SAP context), after having explored native and hybrid iPhone application development. Certainly I was surprised with how quickly the web app was able to be constructed. I hope you can take this, build upon it, and share your experiences with the community also. Please feel free to comment below on how you went ...
PS: If you enjoyed this blog series please see my john.moy3/blog/2011/01/17/extend-your-sap-jquery-mobile-web-app-with-html5-concepts-and-native-device-features--part-1 blog series where I explore a more advanced architectural style with jQuery Mobile and extend it with HTML5/CSS3 and native device features.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
37 | |
10 | |
5 | |
4 | |
4 | |
3 | |
3 | |
3 | |
2 | |
2 |