Skip to Content
Technical Articles

Hide/Display a specific table column using JavaScript in Nested Tables scenarios

In this article, we will see the use of Java script to hide or display a specific column in a table in Adobe forms. It’s very common requirement and there are many ways to achieve this but mostly, we stuck to handle column header and column field together. We will see a simple Java script which will help to hide column header and column field altogether.

Business requirement:

Table Data Structure is as follow:

At run time,

  • When Product is “E”, column Territory should be hidden
  • When Product is “R”, column ISBN should be hidden

Expected result should be as follow:

Let’s try with a simple example rather than nested table structure as above.

Step 1:

Create an Adobe form ZPB_HIDE_TABLE_COLUMN with an interface with import parameter as IV_PRODUCT and IT_DETAILS.

  • IV_PRODUCT  :               Product Type entered from driver program
  • IT_DETAILS     :               Detail table with following structure

Step 2:

Create a table from data view using IT_DETAILS in Adobe layout as follow:

As per the business requirement, Column Territory should be hidden when product type entered by user is “E”. So whenever each body row of table will be initialized, we need to read product type IV_PRODUCT and corresponding column for the same data row should be hidden.

Step 3:

Create a driver program to call Adobe form functions and fill this table with test data and pass that table into Adobe form generated FM.



DATA: gt_details TYPE zpb_test_details,
      gs_details LIKE LINE OF gt_details.

DATA: ie_outputparams TYPE sfpoutputparams,
      i_funcname TYPE funcname.
DATA: fp_docparams    TYPE sfpdocparams.
DATA: fp_formoutput   TYPE fpformoutput.
DATA ls_result TYPE sfpjoboutput.

SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS: p_form TYPE fpname.
SELECTION-SCREEN END OF BLOCK b1.

SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS: p_prod   TYPE char20.
SELECTION-SCREEN END OF BLOCK b2.

** Get Test Data for Detail Table
DO 2 TIMES.
  gs_details-product_type     =  p_prod.
  gs_details-sales_type       = 'E-Book'.
  gs_details-territory        = 'US HardCover'.
  gs_details-isbn             = '978-981-13-5058-0'.
  gs_details-net_units        = '8'.
  gs_details-royalities_basis = '100'.
  gs_details-royality_rate    = '10% of Net'.
  gs_details-total_royalities = '10'.
  gs_details-roy_share        = '100'.
  gs_details-earnings         = '10'.
  APPEND gs_details TO gt_details.
  CLEAR: gs_details.
ENDDO.

CALL FUNCTION 'FP_JOB_OPEN'
  CHANGING
    ie_outputparams = ie_outputparams.

TRY.
    CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
      EXPORTING
        i_name     = p_form
      IMPORTING
        e_funcname = i_funcname.
  CATCH cx_fp_api_repository.
  CATCH cx_fp_api_usage.
  CATCH cx_fp_api_internal.
ENDTRY.

CALL FUNCTION i_funcname
  EXPORTING
    /1bcdwb/docparams  = fp_docparams
    iv_product         = p_prod
    it_details         = gt_details
  IMPORTING
    /1bcdwb/formoutput = fp_formoutput
  EXCEPTIONS
    usage_error        = 1
    system_error       = 2
    internal_error     = 3.

CALL FUNCTION 'FP_JOB_CLOSE'
  IMPORTING
    e_result       = ls_result
  EXCEPTIONS
    usage_error    = 1
    system_error   = 2
    internal_error = 3
    OTHERS         = 4.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

Test data would be displayed as follow:

Step 4:

In the script editor, Write the below Java script code in initialization event of body row of table GT_DETAILS_SIMPLE as follow:

 data.sbf_details.GT_DETAILS_simple.DATA::initialize - (JavaScript, client)
	
	var product = xfa.resolveNode("data.sbf_details.IV_PRODUCT").rawValue;
	
	if(product == "E")
	{
		this.TERRITORY.presence = "hidden";
	}
	else
	{
		this.ISBN.presence = "hidden";
	}	

Let’s try to understand the above script code.

XFA stands for Adobe’s XML Form Architecture and it’s the root element of xml file for adobe PDF. If we want to access a specific object in the hierarchy, we can access it by passing its path as parameter in resolveNode method. This method would return the reference of the object passed as parameter and we can use the appropriate properties of that object.

  • In the highlighted script, we got the reference of IV_PRODUCT context field and using property rawValue, we got the user entered product type value in a local variable product.
  • Based on product value, we tried to set the visibility property (presence) of respective columns as “hidden”.

Step 5:

Test program creation and result of adobe form print-preview:

  • Create a selection-parameter P_PROD which will be passed by user in the test driver program for calling Adobe form.

  • Test the program and observe the result:

If you compare the above result with actual test data from step 3, you will observe that actually Java script has worked out to hide the column value (Territory as Product type entered as E) but column header “Territory” was not removed. Therefore, all the columns have been shifted 1 place to the left and therefore resulted into a wrong PDF form. How to correctly display the data?

We have to hide corresponding column headers from Table header row as well so we need to write another Java script in initialization event of table header row.

Step 6:

In the script editor, Write the below Java script code in initialization event of header row of table GT_DETAILS_SIMPLE as follow:

 data.sbf_details.GT_DETAILS_simple.header::initialize - (JavaScript, client)

	var product = xfa.resolveNode("data.sbf_details.IV_PRODUCT").rawValue;
	
	xfa.resolveNode("data.sbf_details.txtHeader").rawValue = product;
	
	if(product == "E")
	{
		this.txt_territory.presence = "hidden";
	}
	else
	{
		this.txt_isbn.presence = "hidden";
	}

this will always refer to the current object in which event has been written. In the highlighted sentence above, this would refer to “data.sbf_details.GT_DETAILS_simple.header”.

Since we want to hide a specific field of the header, script code is written to set the presence property of territory and isbn texts.

  • txt_territory :           Text field name in header in hierarchy for Territory column
  • txt_isbn :                 Text field name in header in hierarchy for ISBN column

 

Step 7:

Test the program and observe the form result in “Print-Preview”:

Two important observations if we compare the above result with actual test data in step 3:

  • We achieved the requirement as Territory column is completely hidden as Product entered is “E”.
  • However, column width of the columns has been disturbed. We didn’t set NET_UNITS column as wide as shown above. It has been replaced with column width of ISBN and same applicable for subsequent columns afterwards.

What would be the exact solution now?

We observed that apart from hiding a column field and column header, we also need to adjust the column width dynamically. For that, rather than writing multiple Java Scripts on multiple objects ( BodyRow, HeaderRow, Table Column Width changes ), we can achieve this by writing Java Script code at single place and it will handle everything at once.

Step 8:

After step 3, Follow this step and write the below Java script code in initialization event of table GT_DETAILS_SIMPLE as follow:

data.sbf_details.GT_DETAILS_simple::initialize - (JavaScript, client)
// Get Product Type
	var product = xfa.resolveNode("data.sbf_details.IV_PRODUCT").rawValue;
// Get Detail table all columns width as string	
	var width = this.columnWidths;
// Split in Array. Each index of array will refer to individual column width	
	var array = width.split(" ");
	
	if(product == "E")
	{
// Remove column width of third column
		array[2] = "0.001mm";
	}
	else
	{
// Remove column width of third column
		array[3] = "0.001mm";
	} 
// Set the new set of column width to current table	
	this.columnWidths = array.join(" ");

Explanation of above Script code is as follow:

  • var width = this.columnWidths – Return the whole string as set of all column’s width
  • var array = width.split(” “)        – Split the width string by space, return an array
  • array[2] = ‘”0.001mm”              – Replace third column width with 0.001mm.
  • array.join(” “)                            – Concatenate all the array data sets and return a string.

Step 9:

Now all the column’s widths are correctly displayed and Territory column has also hidden as product entered is “E”.

But now, column header height has been adjusted automatically. We can’t change the layout properties of a “Text” UI dynamically so we have to change its type to “Text Field” and re-check the results.

Step 10:

Change the type of the Header columns to “Text Field” as follow:

  • Select column header and goto Object palattes:

  • Set the default column header text as follow:

  • Follow the above steps for all column headers.

Step 11:

Repeat step 9 and check the result in print-preview:

  • When Product = E

  • When Product = R

Conclusion:

We have now observed many ways to hide or display a specific column in Table UI in Adobe forms using Java Script code and the best and easy way to control it using Table’s Property columnWidth. With the above simple table use case, we can apply the same rules on complex business environments.

We will check now a short description for handling a nested Table columns controlled by Java Script.

Step 12:

  • Extend the above Adobe form with new context created in form interface:

IT_NESTED              :               Detailed Product structure with Table type as follow:

 

  • Create a table from data view using IT_NESTED in Adobe layout as follow:

  • Set the PRODUCT_TYPE column in table IT_NESTED as invisible.

Now, for each DATA record in IT_NESTED, we have to read Product field and based on that, we have to adjust columnWidth property of DETAILS Table (which would hide/display corresponding columns in details table).

Step 13:

Write the below Java script code in initialization event of table DETAILS as follow:

data.sbf_nested.IT_NESTED.DATA.DETAILS::initialize - (JavaScript, client)

 	var product = xfa.resolveNode("data.sbf_nested.IT_NESTED.DATA.PRODUCT_TYPE").rawValue;
 
	var width = this.columnWidths;
	var array = width.split(" ");
	
	if(product == "E")
	{
		array[1] = "0.001mm";
	}
	else
	{
		array[2] = "0.001mm";
	} 
	
	this.columnWidths = array.join(" ");

 

Step 14:

Check the result in print-preview:

 

You can see that with a single Java Script code block , we can achieve the complex business scenarios very easily. That’s the power of Java Script in Adobe Forms.

1 Comment
You must be Logged on to comment or reply to a post.
  • Very nice!   I’m using this one.  Adobe forms are newish to me.   I have never tried adding specific javascript.  It never stops amazing me that such an “simple” language can do so much.

    Newish = Modify a lot of them, but haven’t created one of my own yet.  It’s coming.

    Thank you!

    Michelle