Skip to Content
Author's profile photo John Moy

Build your first Mobile web app using jQuery Mobile and ABAP – Part 3

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.

Abhinav Tayal

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 …

  • Add a new Public instance method SET_ADDRESS
  • Add the following parameter declarations to this method …

SET_ADDRESS parameters 

  • Now insert the following logic for this method (note that this is simplified somewhat for the purpose of the exercise and would ordinarily include additional error handling) … 

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.

  • A few comments about this method … it calls a standard BAPI to execute the address change.  If a BAPI return is received, the return message is propogated back to the caller of the method, otherwise the M_ADDRESS_DATA attribute for the model class is updated with the new address.
  • Save and activate the changes 

CONTROLLER

Extend the BSP controller class ZCL_MOBILE_DEMO_CONTROLLER as follows …

  • Add a new instance method PROCESS_INPUT.
  • Add the following parameter declaration to this method …

PROCESS_INPUT parameters

  • Now insert the following logic for this method (once again this is simplified somewhat for the purpose of the exercise and would ordinarily include additional error handling) …

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.

  • The PROCESS_INPUT method performs the task of extracting the address fields from the HTTP POST (which will be declared later below) and then executing the SET_ADDRESS method that we declared against the model class.  The return message is then passed to a new view ‘message.xml’ (which we will define shortly) and the view is called and returned back as the HTTP response.
  • Of course in reality you would architect a method such as PROCESS_INPUT to handle multiple possible scenarios to allow this approach to scale.
  • We need to update the DO_REQUEST method which we implemented in Part 2 so that it now executes PROCESS_INPUT when input form fields are detected

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.

  • Note that this approach deviates from the standard call to DISPATCH_INPUT which is an existing provided method for input processing.  We could have alternatively chosen to re-implement this method instead of creating a separate one.
  • Save and activate the changes.

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 …

  • Right click on the BSP application ZMOBILE_DEMO and select to create a Page.  Enter the page name as ‘message.xml’, enter a description, and select the page type as View.
  • For the page, select the tab Page Attributes and enter the following attributes …

/wp-content/uploads/2010/11/22211_view_attributes_81125.png

  • For the page, select the tab Layout and overwrite the default HTML with the following …

<?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).

  • Maintain the layout for the original view ‘main.htm’ which we created in Part 2, and insert the Javascript specified below (note that best practice in reality is to code the Javascript into a separate file and reference it from the HTML, but for simplicity of the blog I have declared it as inline Javascript here) …

<!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.

  • I have tried to comment the Javascript to help you understand it better.  In basic terms, we use a jQuery (not jQuery Mobile) API to register an event listener for the Address Update submit event.  When this event fires, jQuery funnels it into our Javascript function.  The function firstly formats the raw data to send to the server, initiates the animation (so the user sees that server communication is occurring), and initiates a HTTP POST to the BSP application.  The response received is captured and the page loader animation is terminated.  At this stage we hope to have an XML return page in the Javascript variable ‘xml’.  We evaluate this page for a result code.  If it is 0 (success) then we update the address values in our HTML DOM accordingly.  Finally we extract the return message, insert that into the HTML DOM for the Message ‘dialog’ (I referred to that briefly in Part 2) and execute a page transition to display the message dialog.
  • The end result is that we successfully execute a basic UPDATE scenario using Ajax against our ABAP server.  If you test this, you can use transaction PA20 and evaluate infotype 0006 to see that the address record was indeed updated in the system.

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 …

  • How much information to return in the response page.  At the moment the solution documented here is very basic and minimalist, but you could choose to also return the HTML fragment for the area you have updated and when receiving this in Javascript you update the HTML DOM accordingly.  This would alleviate the need for the manual Javascript updates that are being made to update the address values in our HTML DOM.
  • On the Javascript side the solution here manually encodes values relating to address.  You would want to abstract this in some manner such that the Javascript function can be called more generically without having to duplicate it for each scenario. That’s my next task …

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 …)

  • Other Employee Self Service functions such as display leave balances (quotas), book absences (leave), display bank accounts etc.
  • Manager Self Service functions, such as displaying leave bookings of subordinates (eg. to find out who is booked to be absent today) etc.
  • Workflow listing and approvals.
  • Customer lookup, opportunities and activities details.
  • Asset maintenance functions.
  • etc. etc.

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 next blog series where I explore a more advanced architectural style with jQuery Mobile and extend it with HTML5/CSS3 and native device features.

Assigned Tags

      36 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Nigel James
      Nigel James
      Hi John,
      When I am not so frantic I will look further into what you have done here. I have also done a bit of BSP and jQuery work so it will be interesting to compare and contrast.

      Cheers,
      Nigel

      Author's profile photo Simon Kemp
      Simon Kemp
      John,

      Thank you for sharing this blog series with the community. It is insightful and comprehensive and I am sure will spark much thought, discussion and activity. I know it has already got me thinking! 🙂

      Cheers,
      Simon

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Simon,

      Thanks for your comments.  One thought that came to my mind is .... you could almost build a mobile portal using this approach!  If you think about it, most people interact with a portal for just a few specific reasons (eg. enter leave request, approve workflows).  If you took the highest usage items from a portal and mobilized them using something like this, then you could have some very happy people.  No need to be in the office to book your sick leave!
      And certainly the main thing I am excited about is the evolution of these new open source frameworks such as jQuery Mobile.  You could still take the same concept and implement it with a Java server.  Although if you are looking at HCM type scenarios I would have thought that ABAP BSP would make more sense.

      Cheers

      John

      Author's profile photo Simon Kemp
      Simon Kemp
      For sure John, I'll look into it! One thing that will be interesting to see next year is the this so called project "Phoenix" from SAP that apparently will introduce a new lightweight rendering framework - I wonder if that will be mobile friendly??? I certainly hope so.
      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Simon,

      In relation to project Phoenix, when I interpret the TechEd slides it looks to incorporate jQuery, so it has the same lineage (jQuery Mobile is built on jQuery also).  I have not seen any mention of jQuery Mobile in SAP slides, nor would I expect to given how new it is.  The first alpha release was launched at the same time that SAP TechEd 2010 Las Vegas was being held.

      Cheers

      John

      Author's profile photo Former Member
      Former Member
      That's what I'm talking about!

      These JavaScript built-in libraries such as JQuery can really improve the user experience in HTML Pages, and when it comes to BSP it really makes our work distinguish from the others.

      Thank you for sharing your experience! This blog will be my home page for a while... 🙂

      Author's profile photo John Maas
      John Maas
      Nice piece of work. I did this also before using BSP and plain HTML for safari.
      But the question that keeps me busy is, how to secure this all for users you don't want on your SAP system. Fact is that you go over Http(s).
      May be you can make an extra block for good authentication ?

      Suc6. John

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi John,

      I am not a security expert.  What I can say is that for the demonstration I am using a SonicWall Aventail SSL VPN connection (to my iPhone) which supports mobile solutions.  This approach was deemed satisfactory by my security colleagues.  If anyone else has thoughts on this I would encourage them to comment.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      hi john,
      I'm building your application in bsp(mvc) using jquery mobile. The start page of my site is main.htm. If user enter personal number,and click a button  he goes to main1.htm and  get entered employee details on that page. how to write button click event  using  jquerymobile to retrieve data .

      Please help.

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Raju,

      I question why you would want users to enter personal numbers. This is poor usability, as people never remember these numbers. And if we are talking about Employee Self Service, you should never have to enter a personal number anyway.
      With respect to your question, it is important to remember that jquerymobile hijacks any http request and inserts the resulting contents into the original html file. This way, it only ever works with a single html file on the client. So the results of main1.htm would be appended to main.htm. This means that main1.htm would only need to contain the page declaration for the result (ie.

      ....

      ).
      In order to call main1.htm, there are several approaches you could use. One option could be to declare a button link as per the jquerymobile documentation ...


      Link button

      Using this approach, you need to parse for the specific event in your controller, retrieve data from your model class, and then return the 'main1.htm' view.

      Hope this helps.

      Rgds

      John

      Author's profile photo Former Member
      Former Member

      Hi John,raju

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Raju,

      What you are missing here is you need to use jQuery to register an event handler for the form submission.  You would need javascript code something like the following (I can't guarantee this is 100% correct, since I am making this up on the fly) ...

        // Event registration
        $(function() {
            // Register event
            $('#get_details').submit(function() {

                // Compile data to send to SAP server
                var dataString = '&event=event_get_details' +
                                 '&pernr=' + $("input#pernr").val();

                // Initiate page loading animation
                $.mobile.pageLoading();

                // Get results from SAP server
                $.mobile.changePage({
                    url: "mobilemain.do",
                    type: "get",
                    data: dataString
                });
            }); // Submit handler
        }); // Event registration

      Please don't ask me for the ABAP as well!!!  This code should take you into the DO_REQUEST and then the PROCESS_INPUT method (based on the blog).  You will notice I included an attribute 'event=event_get_details'.  If you check for the value of 'event' in PROCESS_INPUT you can then process accordingly and return the appropriate view.  I included this because as you extend the application you may have many events passing through PROCESS_INPUT.

      Hope this helps.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      HI JOHN ,

           when will you submit your next application using this approach.

      Author's profile photo Former Member
      Former Member
      Hi Johh,
      Thank you very much for your blogs. very usful. Using this I was trying to create one. How can pass one internal table back to the HTML based on the data from the input. Here based on the address update, passing back some message on an xml page, instead of that, I want to pass back one internal table and display it in the html, what are the setting I have to do for that?
      Author's profile photo John Moy
      John Moy
      Blog Post Author

      Hi Mathew,    Back <br/>    h1. Listing

      <br/>  </div><!-- /header ><br/>  <div data-role="content"><br/>    <ul id="yourlist" data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>        <% field-symbols: <fs_data> like line of lt_yourlist.<br/>           loop at lt_yourlist assigning <fs_data>.<br/>        %><br/>           <li> <a href="mobilemain.do?&event=event_get_detail&data=<%= <fs_data>-key %>" target="_top"><br/>                <small><br/>                <%= <fs_data>-name %> <br/><br/>                <%= <fs_data>-desc %><br/>                </small><br/>                </a><br/>           </li><br/>        <%<br/>           endloop.<br/>        %><br/>    </ul><br/>  </div><br/>  <div data-role="footer"><br/>  </div><br/></div><! /Your List --><br/><br/>It is important to understand that jQuery Mobile will absorb the returned HTML and INSERT it into the document object model for the original HTML page, then execute a transition to that page.  This allows it to transition smoothly, as if the listing was part of the original web app.<br/><br/>Hope this helps.<br/><br/>Rgds<br/><br/>John

      Author's profile photo Former Member
      Former Member
      After testing this program. I suggest the followings:

      1. DO_REQUEST method
      method DO_REQUEST.
        CALL METHOD SUPER->DO_REQUEST
          .
        " if input is available, dispatch this input to subcomponent.
        " this call is only necessary for toplevel controllers.
        " (if this is not a toplevel controller or no input is present,
        "  this call returns without any action)
        dispatch_input( ).

        " if any of the controllers has requested a navigation,
        " do not try to display, but leave current processing.
        if is_navigation_requested( ) is NOT INITIAL.
          return.
        endif.

          view = create_view( view_name = 'main.htm' ).

          " set the attributes
          IF M_MOBILE_MODEL is NOT INITIAL.
            view->set_attribute( name = 'xxxxx' value = M_MOBILE_MODEL->xxxxx ).
          ENDIF.

          " call the view
          call_view( view ).
      endmethod.

      2. DO_HANDLE_EVENT
      method DO_HANDLE_EVENT.

        " let super do it first
        CALL METHOD SUPER->DO_HANDLE_EVENT
          EXPORTING
            EVENT           = event
            HTMLB_EVENT     = htmlb_event
            HTMLB_EVENT_EX  = htmlb_event_ex
            GLOBAL_MESSAGES = global_messages
          RECEIVING
            GLOBAL_EVENT    = global_event.

        IF event is NOT INITIAL.
          CASE event.
            WHEN 'submit'.
              method_todo_forsubmit( ).
            WHEN OTHERS.
          ENDCASE.
        ENDIF.

      endmethod.

      3. Javascript:

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Mac,

      Excellent.  Thanks!  There are some nice additions here.

      I should have submitted this to code exchange, but for now your comment response gives everyone some nice enhancements to the approach.

      Interestingly, I have recently followed the same approach of adding an extra parameter to the ajax POST (in your example ... "&oninputprocessing=submit") and then evaluating this with a CASE statement in the ABAP.  It gives me more confidence that it is a good path to follow.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      Hi Mac,
      Thank you very much for your blogs. very useful.
      can you provide this application briefly.
      "Manager Self Service functions" like manager Enter employee personal number in first page then  he get information in second page.How to write this approach.
      regards
      raju
      Author's profile photo Former Member
      Former Member
      Hi,
      I've implemented a copy of your example to list roles.
      It works fine in Safari (PC), and fine in iphonetester.com in Safari.
      But the page is not loaded on my iPhone; I only get the title, and an hourglass.
      I first suspected a proxy issue, but I can access the portal.
      Any idea will be welcome !
      Laurent
      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi,

      Not sure why you are seeing this behaviour.  I can assure you that it works on my iPhone, via a secure proxy service (using Sonicwall Aventail).  If you can access the portal but not this app then I would presume your firewalls are not configured to expose these resources through to your phone.  Also, maybe it is trying to download the jQuery javascript framework but for some reason it cannot 'see' that via yuor proxy?

      Tell me if you get it working.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      Hi John,
      Thank you very much for your blogs. very useful. Using this I was trying to create one.
      can you provide this application briefly.
      "Manager Self Service functions" like manager Enter employee personal number in first page then he get information in second page.How to write this approach. I am trying to develop this approach i got some errors.

      code:
      method DO_INIT.
      M_MOBILE_MODEL ?= CREATE_MODEL( CLASS_NAME = 'ZCL_MOBILE_DEMO_MODEL'
      MODEL_ID = 'MODEL').
      * M_MOBILE_MODEL->refresh_model_data( ).
      endmethod.

      method DO_REQUEST.

      DATA : VIEW TYPE REF TO IF_BSP_PAGE.

      DISPATCH_INPUT( ).

      " CREATE VIEW
      view = create_view( view_name = 'MAIN.HTM' ).

      " set the attributes
      IF M_MOBILE_MODEL is NOT INITIAL.
      view->set_attribute( name = 'lv_pernr'
      value = M_MOBILE_MODEL->m_emp_number ).

      ENDIF.

      " call the view
      call_view( view ).

      ENDMETHOD.

      METHOD DO_HANDLE_EVENT.
      IF HTMLB_EVENT IS BOUND AND
      HTMLB_EVENT->SERVER_EVENT = 'get_details'.

      ME->M_MOBILE_MODEL->REFRESH_MODEL_DATA( ).

      IF NOT ME->M_MOBILE_MODEL->M_EMP_NUMBER IS INITIAL.
      ME->VIEW_NAME = 'MAIN1.HTM'.
      ENDIF.
      ENDIF.
      ENDMETHOD.

      // Event registration
      $(function() {
      // Register event
      $('#get_details').submit(function() {

      // Compile data to send to SAP server
      var dataString = '&event=event_get_details' +
      '&pernr=' + $("input#pernr").val();

      // Initiate page loading animation
      $.mobile.pageLoading();

      // Get results from SAP server
      $.mobile.changePage({
      url: "mobile.do",
      type: "get",
      data: dataString
      });
      }); // Submit handler
      }); // Event registration



      Get Details


      if i execute this application i got this error.
      please solve this errors and modify the code if possible.

      error:

      The following error text was processed in the system: BSP Exception: Object = mobile.do_event event_get_details in the URL / sap (bD1lbiZjPTgwMA ==) / bc / bsp / sap

      / zmobile_pernr / mobile.do & event = event_get_details not valid.

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Raju,

      Unfortunately I don't think I can address such a detailed error for you.  Note however that in the course of my work I have come across a multitude of errors.  The best way for me to learn is to persist with analysis and debugging and eventually I resolve my errors.  I have shared the end result with the community via this blog, however I don't have the time to resolve your own.  The best advice here that I can give is to learn the standard debug techniques with BSP.  The problem you have here can be analysed and fixed using these standard techniques.

      Sorry, that is the best advice I can provide right now.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      Hi John,
      I created one application with the help of your blog, and I was able to display 5 fields in the safari browser and when I tried to display in the iphone, not displaying all the fields. also it is wrapping up.

      Here is the example which displays in the browser

      Order no           Description              Start Date    End date     Actual qty     Remaining Qty
      345676          Sample order        01/02/2011     02/02/2011     15.00     8.00

      But when it comes to the iphone it is showing like this
      Order no           Description              Start  End
      Date     date  
      345676          Sample order        01/     02/
      02/     02/
      2011     2011
      Not sure why it comes like this. Is there any way I can display in the iphone exactly like the browser (all the fields in one line ) ?
      Thanks
      Thomas

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Thomas,

      I think you need to be very careful about fitting this much information on one line for a mobile device, especially something like a phone.
      If I were you I would force a break (eg. using the 'BR' tag in the html) and layout the data on multiple lines.  You could also encapsulate the data in 'small' tag so the font size is reduced.

      Alternatively have a list view that just shows a couple of fields of information, and then when you press on a line you navigate to a full page view whereby everything is laid out vertically.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      I have total around 15 fields, but I want to display these 6 fields in the first screen, and from there details will display in another page by naviating from here.  when we use Iphones, we can flip/slide to next screen if we have a long line of data. is it possible we can make that kind of technique to display the whole line? how can I achieve it?

      Thanks
      Thomas

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Mathew,

      Email me directly and I may give some ideas.  Unfortunately cutting and pasting HTML into blog comments is not good.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      Hi,

         It is really good..I have tried to update address..It is working fine.Then i have tried one more scenario in addition to it , like updating absence infotype..But it is not getting updated.Can anybody help me in creating this..Please..

      Author's profile photo Former Member
      Former Member
      It continues to emp_address page.

      I am using jquery.mobile-1.0b1

      Thanks!

      Author's profile photo Former Member
      Former Member
      hi,

      i have followed all the steps and tested in IE. all the data is displayed perfectly. i went to android emulator and pasted the URL in the default web browser app and try to access it. i got a pop up for user id and password. after the entering the details i am getting the below error

      "log on performed for client =00, my user id, langaue EN"

      where do i enter client?

      thanks

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Sankara,
      Perhaps you should go to SICF, navigate to your service, and enter the client in the 'Logon Data' tab?
      Rgds
      John
      Author's profile photo Former Member
      Former Member

      hi,
      i am building a simple BSP/jquery application, where i enter the business partner and get some details. when i run this application in IE, it is working fine(even though UI is bad). when i run the application using google chrome or testiphone.co, i am not able to see the result. when i click on button browser says "loading" and thats it. nothing happens.

      i have created two views

      main.htm - where i have input field and button "getdata"

      // Event registration
      $(function() {
      // Register event for handling submit of address updates
      $('#address_update').submit(function() {

      // Compile data to send to SAP server
      var dataString = '&businesspartner=' + $("input#businesspartner").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

      Businesspartner

      second view is details.view

      <!-- Home Page ><br/><div data-role="page" data-theme="b" id="home"><br/>  <div id="homeheader"><br/>    <div style="text-align:center"><br/>    <h1 id="jqm-logo"><div style="color:#ffffff; background-color:#aec5db">Selecr BP details</div></h1><br/>    <p><br/><br/>    </p><br/>    </div><br/>  </div><br/><br/>  <div data-role="content"><br/>    <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="a"><br/>      <li>[central data | #emp_svc]</li><br/>    </ul><br/>    <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="a"><br/>      <li>[centraldataperson | #emp_org]</li><br/>      <li>[centraldataorganisation | #emp_address]</li><br/>    </ul><br/>  </div><br/><br/>  <div data-role="footer"><br/>  </div><br/><br/></div><! /Home Page ><br/><br/><br/><! Employee Services -->

          Back <br/>    h1. Emp Services
      <br/>  </div><br/> <div data-role="content"><br/>    <ul data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>      <li data-role="list-divider">Organisational Unit</li><br/>      <li><%= CENTRALDATA-SEARCHTERM1 %> </li><br/>    </ul><br/>    <ul data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>      <li data-role="list-divider">Position</li><br/>      <li><%= CENTRALDATA-PARTNEREXTERNAL%> </li><br/>    </ul><br/><br/>  </div><br/>  <div data-role="footer"><br/>  </div><br/><br/></div>
      <!-- /Employee Services ><br/><br/><br/><br/><! Org Assignment -->

          Back <br/>    h1. Org Assignment
      <br/>  </div><br/>  <div data-role="content"><br/>    <ul data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>      <li data-role="list-divider">central org</li><br/>      <li><%= CENTRALDATAORGANIZATION-NAME1 %>  </li><br/>    </ul><br/>    <ul data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>      <li data-role="list-divider">Position</li><br/>      <li><%= CENTRALDATAORGANIZATION-NAME2 %>  </li><br/>    </ul><br/><br/>  </div><br/>  <div data-role="footer"><br/>  </div><br/></div>
      <!-- /Org Assignment ><br/><br/><br/><! Address -->

          Back <br/>    h1. Address

      <br/>    Edit <br/>  </div><br/>  <div data-role="content"><br/>    <ul data-role="listview" data-inset="true" data-theme="d" data-dividertheme="c"><br/>      <li data-role="list-divider">validity</li><br/>      <li><br/>          <span id="valid from"><%= CENTRALDATAVALIDITY-VALID_FROM %></span><br><br/>          <span id="valid to"><%= CENTRALDATAVALIDITY-VALID_TO %></span><br><br/><br/>      </li><br/>    </ul><br/>  </div><br/>  <div data-role="footer"><br/>  </div><br/> </div><!-- /Address --><br/></body><br/></html><br/><br/>is there anything wrong in ajax calling. surprisingly it works in IE perfectly.<br/><br/>thanks

      Author's profile photo Former Member
      Former Member
      hi,

      i have debugged the application when running in chrome. inside the process_input method, lt_fields contains "undefined" as the value for businesspartner column. i have changed it in debug mode but the problem is still there. apparently when i debug through IE, the business partner value is coming correctly in lt_fields table.

      thanks

      Author's profile photo John Moy
      John Moy
      Blog Post Author
      Hi Sankara,
      Yes sadly these are the types of hurdles you typically encounter when building these things.  The problem could be in your Chrome browser settings (for instance, maybe javascript support is turned off?).  The very simplest thing I can suggest is that you place some trace statements in your Javascript to see where it might be failing.  To begin with, start by writing out the value of dataString immediately after it is assigned it's value.  ie. alert(dataString);
      If you don't see anything, then Chrome is failing to get to that line of code.  Gradually place your trace statement earlier in the source code until you get something, then work from there.
      Hope this helps.  Tell me if you resolve it.

      Rgds

      John

      Author's profile photo Former Member
      Former Member
      hi,

      i figured out why "undefined" is coming in datastring. i was using name of the input field instead of the id. as you mentioned i have alert(datastring) inside the javascript function and it is bringing correct value. but the problem is still not solved. in chrome it is still not working. i am suspecting something wrong with the ajax call.

      what i want to do here is to call a BAPI which takes business partner as input and return some data.

      thanks

      Author's profile photo Dipak Khatavkar
      Dipak Khatavkar
      hello sir,

      i have created one simple BSP page for retrive material details using pages with flow logic using jquery mobile framwork.
      i have taken two input field and on submit button.
      but no any output showing when click on button.
      so please  help me.

      Author's profile photo Dipak Khatavkar
      Dipak Khatavkar

      <br/><!DOCTYPE html><br/><br/><html><br/><br/><head><br/><title> Mobile</title><br/><br/>   <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.css"/><br/>  <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script><br/>  <script src="http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js"></script><br/><br/><br/></head><br/><br/><body ><br/><br/><div data-role="page" data-theme="a" id="Displaysales"><br/>      <div data-role="header" data-theme="a"><br/><br/>    h1. MATERIAL DETAILS 
      <br/>    </div><br/><br/><div data-role="content"><br/><br/><form action="#" method="post"><br/><ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="a"><br/><br/>     <div data-role="fieldcontain"><br/>      <label for="matnr">Material No:</label><br/>       <input type="text" name="matnr" id="matnr" value=""/><br/><br/>     </div><br/><br/>     <div data-role="fieldcontain"><br/>     <label for="matnr2">Material No:</label><br/>       <input type="text" name="matnr2" id="matnr2" value=""/><br/>       </div><br/><br/>        </ul><br/><br/>          <INPUT class="submit" type="submit" name="onInputProcessing(select)" value="Get details"><br/><br/>          <INPUT class="submit" type="submit" name="onInputProcessing(materials)" value="Get All"><br/><br/><br/><p> <center><br/><table border=1><br/><% data: wa_mara type mara. %><br/><% if i_mara is not initial. %><br/><tr><td><b>MATNR</b></td><br/><td><b>ERSDA</b></td><br/><td><b>LAEDA</b></td><br/><td><b>VPSTA</b></td><br/></tr><br/><% loop at i_mara into wa_mara. %><br/><tr><br/><td> <%= wa_mara-matnr %> </td><br/><td> <%= wa_mara-ersda %> </td><br/><td> <%= wa_mara-laeda %> </td><br/><td> <%= wa_mara-vpsta %> </td><br/></tr><br/><% endloop. %><br/><% else. %><br/><tr> <td><b>MATNR</b></td><br/><td><b>ERSDA</b></td><br/><td><b>LAEDA</b></td><br/></tr><br/><% loop at it_mara into S_mara. %><br/><tr><br/><td> <%= S_mara-matnr %> </td><br/><td> <%= S_mara-ersda %> </td><br/><td> <%= S_mara-laeda %> </td><br/></tr><br/><% endloop. %><br/><% endif. %><br/></table><br/><br/></form><br/></div><br/></body><br/></html>