Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

h1. Introduction

I learned two very important things this morning that I thought that I would share.  The first is that when you cook a frozen breakfast burrito in a microwave for nearly 15 minutes; that is a bad thing!  The second is that I found some great new functionality in BSP Model View Binding.  Amazingly these two discoveries are quite intertwined.

How my morning started

My morning started with a programming challenge (as all good days should start).  I wanted to dynamically build a screen full of input fields on a BSP page.  I will not know how many fields until runtime.  I needed to retrieve the values for all these fields and use them in a dynamic query upon user request.  None of this sounded impossible, but I thought I was in for a morning of a lot of coding. 

To prepare myself for the task at hand, I decided that a breakfast burrito would hit the spot.  I headed to the break room around the corner from my office and began to warm the frozen breakfast treat in the microwave.  This is where important lesson #1 really comes into play.  Little did I know that when you punch in 60 and press start, that is actually 60 minutes on this particular microwave. 

Rather than wait the 60 seconds that I thought it would take to prepare my breakfast, I decided to head back to my desk and check out an idea that had come to me while cooking (I use the term cooking lightly.  As if you can call throwing a frozen stick of eggs and sausage into a microwave cooking).  Inspiration at arrived.  I wondered if I could data bind directly into a particular cell in aninternal table.  That way I could build an internal table with my field name in one column and the value for that field in another.  Data binding would take care of all the really hard work for me. 

As I got excited by the concept, I started to look for example programs that might help me understand how to format my binding string.  I didn’t have much luck, so I decided to look inside the code for the inputField BSP Extension itself.  The answer I was looking for came inside the method RESOLVE_MODEL_BINDING

.  There is a call to model->get_attribute_name

inside this method.  Inside this method, some nice programmer had left me a comment that told me exactly what I was looking for:

<!code>  * path syntax:

<!code>  *

<!code>  * [me->owner_id ":"] me->id ":" name [ "[" row "]" ] [ "." column ]

<!code>  *

<!code>  *

</pre>

The burning mess

I was so excited about important lesson number #2 (that data binding to a particular cell in an internal table is possible) that I had completely forgotten about my cooking burrito.  I fully expected to return to the break room to either find that someone had stole the finished burrito or that it would be sitting there getting cold.  To my surprise, I found a still-cooking, burning, stinking mess.  My excitement over Model View Binding had nearly caused me to burn down our offices (my co-workers say that if I get that excited about MVC and Binding that I really need to get out more often).  I wanted to include a picture of the steaming pile, but I’m afraid that the fire marshal has confiscated all the evidence as part of his investigation.

Binding Closer Look

Now that we have survived the burrito story, let’s get serious and take a closer look at the binding example.  My internal table that will hold all of my dynamic input fields looks like the following:

Notice that I have a place for the name of my field as well as columns to hold my sign and option.  I have the sign and option because I am going to be turning these input fields’ entries into ranges.  Low and High will be the actually cells that I will bind to.  These will obviously fill the low and high parts of my range.  Finally I have three strings. Two to hold each of the binding strings and one to hold the title I want to use for my input field.

I am getting the fieldname and description via a RFC call to R/3 (the BAPI - BAPI_HELPVALUES_GET

).  I just have to build my binding string for each entry in this table.  The following is my code sample to do this.  Me->shlp_mvc is the name of my internal table in question. I start this code sample by setting my inputField description.  I then Build the Binding string according to the specification I had found:

<!code>  loop at me->shlp_mvc assigning .

<!code>      move sy-tabix to tabix.

<!code>      read table description_for_helpvalues assigning

<!code>           with key fieldname = -select_fld.

<!code>      -scrtext_m.

<!code>     

<!code>      concatenate '//model/shlp_mvc['

<!code>                  tabix

<!code>                  '].low'

<!code>                  into -bind_low.

<!code>      concatenate '//model/shlp_mvc['

<!code>                  tabix

<!code>                  '].high'

<!code>                  into -bind_high.

<!code>      condense -bind_low no-gaps.

<!code>      condense -bind_high no-gaps.

<!code>    endloop.

</pre>

View Coding

I started to code up my View by just looping through my internal table and generated an inputField Tag for each entry.  The first time through I mapped the +value +attribute of the inputField to my model variable that had my binding string.  I ran my page and guess what I saw: the binding string was being displayed as the value in the inputField on the screen.  I guess I still had some smoke from the burrito fire clogging up my brain!  

I needed a way to dynamically specify the binding string through a variable.  However when I pass this variable to the value attribute, the tag thinks this it he variable I want to use directly.  The solution I came up with was to create my HTMLB inputField directly in ABAP code using the factory class. That way I can directly access the _value attribute.  If you debug a BSP view and look at the code that gets generated, you will see that when you directly supply a value, it goes to the attribute value.  However when you bind to an attribute it always goes to a shadow attribute that begins with an underscore.  You won’t see these in the BSP Extension attributes view.  However if you look at the public attributes of the factory class, they will be there.  The following is the coding in my View:

<!code>              <%

<!code>    if not model->shlp_mvc is initial.

<!code>                %>

<!code>                <%

<!code>    field-symbols: shlp_mvc.

<!code>    data: input_string type string.

<!code>    data: input type ref to CL_PHTMLB_FORMLAYOUTINPUTFIELD.

<!code>    data: input2 type ref to cl_htmlb_inputfield.

<!code>    data: input_id type string.

<!code>    data: tabix type string.

<!code>    data: label type string.

<!code>                %>

<!code>                <xhtmlb:overflowContainer mode   = "CUTOFF"

<!code>                                          height = "170px"

<!code>                                          width  = "380px" >

<!code>                  <phtmlb:containerTitle id            = "TabStrip1"

<!code>                                         collapsed     = "<%= model->t1_collapsed %>"

<!code>                                         collapsible   = "TRUE"

<!code>                                         scrollingMode = "SHOW"

<!code>                                         onCollapse    = "myCollapse"

<!code>                                         title         = "<%= model->SHLPDESC %>" >

<!code>                    <phtmlb:containerContentItem border="TRUE" >

<!code>                      <xhtmlb:overflowContainer mode   = "SCROLL"

<!code>                                                height = "120px"

<!code>                                                width  = "360px" >

<!code>                        <phtmlb:formLayout labelAlignment         = "LEFT"

<!code>                                           design                 = "SOLID"

<!code>                                           verticalLineSeparation = "TRUE"

<!code>                                           fieldToLabelFactor     = "1.0"

<!code>                                           customizationKey       = "ZE0002" >

<!code>                          <%

<!code>    loop at model->shlp_mvc assigning .

<!code>    move sy-tabix to tabix.

<!code>    clear input2.

<!code>    create object input2.

<!code>    clear input_id.

<!code>    concatenate -select_fld tabix '_low' into input_id.

<!code>    condense input_id no-gaps.

<!code>    input2->id = input_id.

<!code>    input2->_value = -bind_low.

<!code>    input2->size   = 15.

<!code>    input2->maxLength = 30.

<!code>    label = -TITLE.

<!code>    clear input_string.

<!code>    input_string = input2->IF_BSP_BEE~RENDER_TO_STRING( page_context ).

<!code>                          %>

<!code>                          <phtmlb:formLayoutItem idOfItem = "<%= input2->id %>"

<!code>                                                 label    = "<%= label %>" >

<!code>                            <%= input_string %>

<!code>                          </phtmlb:formLayoutItem>

<!code>                          <%

<!code>    clear input2.

<!code>    create object input2.

<!code>    concatenate id.

<!code>    condense input2->id no-gaps.

<!code>    input2->_value = -bind_high.

<!code>    label = model->to_text.

<!code>    input2->size   = 15.

<!code>    input2->maxLength = 30.

<!code>    clear input_string.

<!code>    input_string = input2->IF_BSP_BEE~RENDER_TO_STRING( page_context ).

<!code>                          %>

<!code>                          <phtmlb:formLayoutItem idOfItem = "<%= input2->id %>"

<!code>                                                 label    = "<%= label %>"

<!code>                                                 pos      = "asNeighbour" >

<!code>                            <%= input_string %>

<!code>                          </phtmlb:formLayoutItem>

<!code>                          <%

<!code>    endloop.

<!code>                          %>

<!code>   <phtmlb:formLayoutItem idOfItem = "maxRows"

<!code>                                                 label    = "<%= model->Max_rows_desc %>" >

<!code>                            <htmlb:inputField id         = "maxRows"

<!code>                                              value      = "//model/max_rows"

<!code>                                              type       = "INTEGER"

<!code>                                              doValidate = "TRUE" />

<!code>                          </phtmlb:formLayoutItem>

<!code>                        </phtmlb:formLayout>

<!code>                      </xhtmlb:overflowContainer>

<!code>                      <htmlb:button id      = "QUERY"

<!code>                                    text    = ""

<!code>                                    onClick = "QUERY" />

<!code>                      &nbsp &nbsp

<!code>                      <htmlb:button id      = "MORE"

<!code>                                    text    = ""

<!code>                                    onClick = "MORE" />

<!code>   

<!code>  </phtmlb:containerContentItem>

<!code>                  </phtmlb:containerTitle>

<!code>                </xhtmlb:overflowContainer>

<!code>                <%

<!code>    endif.

<!code>                %>

<!code>   

</pre>

Closing

Because I am using Model Binding, there is nothing I need to do to get the input values back into my internal table.  The Binding will place all the values back into their correct position.  I then have an internalready to generate ranges off of.  In case you are interested, here is what the finished product looks like:

!https://weblogs.sdn.sap.com/weblogs/images/1918/BMVCB_004.JPG|height=413 height=265 |width=413 height=265 |src=https://weblogs.sdn.sap.com/weblogs/images/1918/BMVCB_004.JPG!</body>