FAQ round the <htmlb:*> rendering library.
How to Cancel a <htmlb:form> Submit?
Specify an onClientClick event. This string is pure JavaScript code, that must contain all the necessary code to determine whether the submit should be cancelled or not. With this JavaScript code, an additional object called htmlbevent is placed inside a JavaScript function. On this htmlbevent object there are two interesting attributes cancelSubmit and returnValue. The cancelSubmit influences whether the form is submitted or not. The other is the return value to the real onclick event in DOM. This is usually false to cancel further event processing.
Here an example:
<%@page language="abap"%> <%@extension name="htmlb" prefix="htmlb"%> <htmlb:content><htmlb:page><htmlb:form> <htmlb:button text = "Submit Form" onClick = "myClickHandler" onClientClick = "htmlbevent.cancelSubmit = !window.confirm('Submit?');" /> </htmlb:form></htmlb:page></htmlb:content>
The JavaScript function window.confirm()
will display a popup with the specificied text, and offer two buttons OK and Cancel. Depending on the selected button, the htmlbevent.cancelSubmit
flag is set. This flag is to prevent the <htmlb:form> from submitting.
How to Hook into Every Form Submit?
The HTMLB library is calls pre and post JavaScript methods just before the actual form is submitted. These functions can be "intercepted" and enhanced with additional logic.
<%@page language="abap"%> <%@extension name="htmlb" prefix="htmlb"%> <htmlb:content> <htmlb:page> <script> var origPre = htmlbSubmitPre; var origPost = htmlbSubmitPost; </script> <script> function htmlbSubmitPre() { window.status = 'Posting...'; origPre(); } function htmlbSubmitPost() { window.status += 'Waiting Answer'; origPost(); } </script> <htmlb:form> <htmlb:button text = "Submit Form" onClick = "myClickHandler" /> </htmlb:form></htmlb:page></htmlb:content>
The important part of this example code is that there must be two script blocks. In the first block references to the original functions are hooked. In the second block the functions are overwritten, and supplied with their additional functionality. As a last step, the original functions are still called.
How to use a Carriage Return in a <htmlb:textEdit>?
Sometimes you must generate a text string in ABAP that contains carriage return and linefeed sequences. This is interesting in cases where (JavaScript) source code is dynamically built together, or where a specific layout is required.
This can be easily achieved by using the constant CL_ABAP_CHAR_UTILITIES=>CR_LF. One example coding could be:
DATA: text TYPE STRING. CONCATENATE 'Problem:' 'Cause:' 'Remedy:' INTO text SEPARATED BY CL_ABAP_CHAR_UTILITIES=>CR_LF.
Or:
DATA: text TYPE STRING. CONCATENATE 'Problem:' CL_ABAP_CHAR_UTILITIES=>CR_LF 'Cause:' CL_ABAP_CHAR_UTILITIES=>CR_LF 'Remedy:' INTO text.
How to printing BSP Pages that Contain HTMLB Elements?
Question: With the browser print button, how to print the colours and grid of the <htmlb:tableView>?
Answer: Enable the printing of background colors and pictures in the browser. From the IE Menu: Tools -> Internet Options -> Advanced -> Printing, set checkbox.
Client-Side onClick Eventing
Question: I'd like to do some client-side checks before submitting a form and maybe do a JavaScript alert instead of allowing the event to be submitted.
Answer: Just define both the onClick
and onClientClick
events. The onClientClick string will be rendered into a function, which will also get as parameter the htmlbevent
object. Set htmlbevent.cancelSubmit
if you don't want to trigger the server event (which will follow the client side onClientClick
event).
On the BSP page:
<htmlb:button id = "SaveChanges" onClick = "SubmitChange" text = "Submit Button" onClientClick = "do_checks(htmlbevent);" />
This is your code:
<script language="JavaScript" defer="defer"> function do_checks(htmlbevent) { var Check = confirm('MyOnClientClick'); if(Check == false){ htmlbevent.cancelSubmit = true; } } </script>
In your own written do_checks
method, do all required work to validate the data, decide to submit or not by clearing or setting htmlbevent.cancelSubmit
.
<htmlb:content design="DESIGN2003">
Three different designs are supported for HTMLB family of rendering libraries. This can be set with <htmlb:content design> attribute.
CLASSIC |
Deprecated. First initial design. Not recommended at all for use anymore. Only the HTMLB library can run in CLASSIC mode. |
---|---|
DESIGN2002 |
Deprecated. Added as a second version of rendering. Both HTMLB and newer XHTMLB libraries are available in this design. |
DESIGN2003 |
Newest rendering library and only rendering mode still supported. This mode also supports accessibility and Right-to-Left (RTL). All three libraries HTMLB, XHTMLB and new PHTMLB works in DESIGN2003. |
Problem is that often applications are slowly changed from one design to the next, making it required to have more than one design supported at the same time. Also, from the side of BSP rendering, we can not automatically switch designs, as we do not know whether the application has been tested with the next higher up design. Thus, the design attribute can have more than one value. This means that the application has been tested with all listed designs, and at runtime the best design is picked. It is also possible to force a specific design with the URL parameter sap-htmlb-design=CLASSIC|2002|2003
. Note that the URL parameter can only switch between those designs listed as supported in the <htmlb:content> tag.
The typical code will be for a fallback approach will be: <htmlb:content design="DESIGN2002+DESIGN2003">
. Whereas for all new development, or after extensive testing, only the newest design 2003 is recommended: <htmlb:content design="DESIGN2003">
.
<htmlb:tableView> Iterator
Often it is required to custom render a specific cell or column within a standard <htmlb:tableView>. This can be achieved via the use of an iterator. This is effectively a callback interface (IF_HTMLB_TABLEVIEW_ITERATOR
) whereby the <htmlb:tableView>
will give the application the opportunity to custom render each individual cell. Iterators are discussed in BSP Programming: HTMLB TableView Iterator.
What the iterator can return is a BSP Element Expression (BEEs). This is effectively any BSP control, or any collection of BSP controls, or can even be packaged handwritten HTML. The BEE is then rendered out in a specific cell. See BSP Programming: BSP Element Expressions (BEEs) for a description off BEEs.
How to render an empty cell via iterator?
When a cell is completely empty, the cell will not have borders in the table, making for an Anartic landscape in the middle of the table. This is the normal behaviour of the HTML <table>
tag. To prevent this, the HTMLB library will never render out empty cells or cells with only space characters, as these have no meaning in HTML. The solution that we use, is to render out
sequences (non-breaking space) into cells that should be empty, so that the table borders are still displayed. How to achieve this when an iterator is in use? The simple solution is just to use an HTML bee (you definitely want to read BSP Programming: BSP Element Expressions (BEEs)).
DATA: nbsp_bee TYPE REF TO CL_BSP_BEE_HTML. CREATE OBJECT nbsp_bee. nbsp_bee->ADD( html = ` ` ). p_replacement_bee = nbsp_bee.
How to render a clickable image in iterator?
Do I have the possibility to create an construct like <htmlb:link><htmlb:image/></htmlb:link>
inside a tableView iterator? I know that I can create only one {}p_replacement_bee
.
One simple way is to use a table bee.
DATA: link TYPE REF TO CL_HTMLB_LINK. link = CL_HTMLB_LINK=>FACTORY(...). DATA: image TYPE REF TO CL_HTMLB_IMAGE. image = CL_HTMLB_IMAGE=>FACTORY(...). DATA: table_bee TYPE REF TO CL_BSP_BEE_TABLE. CREATE OBJECT table_bee. table_bee->ADD( bee = link level = 1 ). table_bee->ADD( bee = image level = 2 ). p_replacement_bee = table_bee.
The table bee is effectively a table of bees, where you can set the level as-if you are writing the controls on a BSP page. The level is used to decide which controls are children to other controls.
However, specifically for the situation of having an image within a link, the <htmlb:image>
was extended with onClick
and onClientClient
attributes, so that this wrapping should not be required anymore.
Behaviour of edit fields in cells
At some stage the <htmlb:tableView>
added an inner border around a specific cell if it was in edit mode. Effectively, one had then a cell border in a cell border. Reference picture. However, from our HTML design ideas, this behaviour was deemed an error, and the rendering was changed to NOT have this cell border in cell border.
As we expect that there might be customers that actually like this form of rendering, the code was not deleted, but just disabled. To enable the code again, set the flag p_isreadonly = `X`
within the iterator method render_cell_start
. (For the record: we did torture the developer for 30 minutes of no coffee about the name of this flag attached to this semantics. He had a cup of tee, and has since then not said anything that we would dare to publish here.)
METHOD if_htmlb_tableview_iterator~render_cell_start . CASE p_column_index. WHEN 1. p_replacement_bee = cl_htmlb_inputfield=>factory( id = p_cell_id value = '123' ). P_ISREADONLY = 'X'. WHEN 2. p_replacement_bee = cl_htmlb_inputfield=>factory( id = p_cell_id value = '123' ). CLEAR P_ISREADONLY. ENDCASE. ENDMETHOD.
How to attach javascript functions to htmlb:inputField events?
Ever wondered how to attach javascript functions to events of htmlb:inputField. Here is the sample code which shows javascript alert attached to onchange event of htmlb:inputField.
<%@page language="abap" %> <%@extension name="htmlb" prefix="htmlb" %> <htmlb:content design="design2003" > <htmlb:page title=" " > <htmlb:form> <htmlb:inputField id="IP1" /> <script for="IP1" event=onchange type="text/javascript"> alert(this.value); </script> </htmlb:form> </htmlb:page> </htmlb:content>