Skip to Content
0

C4C Form Ticket Summary logic using FormCalc in Adobe Lifecycle Designer (ALD)

Jan 03 at 03:46 PM

200

avatar image

Hi experts,

I am creating a form in Adobe Lifecycle Designer for a Ticket Summary. I want to print the item postions in the ticket in two tables dependent on the Product's InternalID. So one table for the time product and another for the kilometer product.

See Screenshot below for an example of the script in Row 1 of the table for time (here was the plan to hide all items with the product ID of kilometers; and for the other table the the other way round):

I created two dynamic tabels depended on the data and for the logic in the Script Editor I took the SAP Standard survey summary as example. Here is a logic in the section description field (certain Survey Type Code).

But it doesn't work...In the table for time all items appear and in the second one everything is empty except of 2 columns. What is wrong within this script?

If the data binding for the product's internal ID is:

ServiceRequest - Item - Product - InternalID - #data

Do I need to use in the script $data.ServiceRequest.Item.Product.InternalID or $data.ServiceRequest.Item.Product.InternalID.#data?

Thanks for help!

Best regards,

Deborah

10 |10000 characters needed characters left characters exceeded

How is it handled when I have to chose "#data " in the data binding (see screenshot)? How does the name of this then look like in the script editor?


Dhruvin Mehta Vandre Philippsen Former Member do you perhaps can help? I read your names in other ALD questions... :)

Best regards,

Deborah

0
* Please Login or Register to Answer, Follow or Comment.

3 Answers

Dhruvin Mehta Mar 07 at 11:26 AM
0

Hello Deborah,

Sorry for being late in reply! I hope you have achieved what you wanted.

First of all, I wanted a breif understaing when you say its not working. i.e No data is coming or something is coming in correct?

For basic binding you don't require formcalc/js. ( TBH I have no experience in FormCalc , I use JS only for ALC)

Suppose if u want to bind a simple field with a TextField , you can go to your DataConnection and select the field and #data.

For Item ,

1. create a bodypage with Flowed

2. create a subform (optional ) with flowed content

3. add table

in DataRow , bind it with $.<<Bo>>.item[*]

4. in column specify the field from item and bind it ( bind it with #data )

$.<<Bo>>.item[*].<<anyfield>>

Above will generate a very basic table , now in order to playaround with it i did below code for JS in ALC.

	if (ltype.value == "101"){ //Work
		wRow = this.frmTableItems.tblItems.rowItemContent.instanceManager.addInstance(1);
		wlength = wlength + 1;
		wRow.colItemDate.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;	
		wRow.colItemStartTime.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;
		wRow.colItemEndTime.rawValue = ItemList.item(i).ActualDatePeriod.EndDateTime.value;
		wRow.colItemLineQty.rawValue = ItemList.item(i).ActualQuantity.value;
		wRow.colItemLineDesc.rawValue = ItemList.item(i).Description.value;
		this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue = this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue + wRow.colItemLineQty.rawValue;
	}

So basically based on itemType i am doing some manupulation. I hope it clarifies ur doubts.

cheers.

Dhruvin

Show 3 Share
10 |10000 characters needed characters left characters exceeded

Dhruvin Mehta thanks for your reponse! I'm happy even if it's a late reply. :)

I tried to do it based on your example manupulation JS code. But it is not working, I still get the table with all items (time and kilometer items) - not only one of them. See Screenshot for my try.

and also here the adapted code (is easier to read):

 FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow::initialize - (JavaScript, client)
 if (FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtProduct == "Montage"){
    wRow = this.FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.instanceManager.addInstance(1);
    wlength = wlength + 1;
    wRow.txtID.rawValue = ServiceRequest.Item[i].ID.value;    
    wRow.txtProduct.rawValue = ServiceRequest.Item[i].Description.value;
    wRow.txtProduct.rawValue = ServiceRequest.Item[i].activity_D69RE3TX8TIX738N4U9BIZ85RDescription.value;
    wRow.txtProduct.rawValue = ServiceRequest.Item[i].ServicePerformerParty.FormattedName.value;
    wRow.txtProduct.rawValue = ServiceRequest.Item[i].ActualDatePeriod.StartDateTime.value;
    wRow.txtProduct.rawValue = ServiceRequest.Item[i].ActualDatePeriod.EndDateTime.value;
}

In the screenshot you can see the names of the textfields (Hierarchy below Data.Row) and that I have a data binding $.ServiceRequest.Item[*] in the Data.Row. Furthermore, I set the table dynamic (checkbox ticked "Repeat Row for each Data Item").

The data bindings of the single fields are:

  • txtID: $.ID
  • txtProduct: $.Description
  • txtActivity: $.activity_D69RE3TX8TIX738N4U9BIZ85RDescription
  • txtServicetechnician: $.ServicePerformerParty.FormattedName
  • txtStart: $.ActualDatePeriod.StartDateTime
  • txtEnd: $.ActualDatePeriod.EndDateTime
  • txtvehicletype: $.vehicle_type_D69RE3TX8TIX738N4U9BIZ85RDescription
  • txtAmount: $.ActualQuantity

I put the code in the initialize event, is this right? And I address the fields via the SOM (similar to the name in the hierarchy tree)...

What am I doing wrong?

Warm greetings,

Deborah

screenshot-alc.png (139.0 kB)
0

Hello, First of all initialize is correct place.

However I am little confused with your approach , below is what i think please correct me if am wrong.

1. You binded the row with the table in BO ( our case SR.Items) 2. You also binded the columns with appropriate datafileds from SR.Items.<<field,ie:Description>>

3. You write the code in the intialize method but without looping , ServiceRequest.Item[i].Description.value; ( What is i ) , you need to loop though it. But first of all why you need to do this complex manipulation without writing code also you have bound the row with correct table and also the columns is bound correctly. I think you dont need the code at all. And its coming as blank since JS is throwing error , if you have acrobat reader you can debug this JS! :) i think you should do following.

1. Comment code in method.

2. Check which data is coming straight up from binding, Only for manipulation use JS. ( lets do everything step by step )

1

Hi Dhruvin Mehta,

the first 2 statements (1+2) are right. I just started to use js for binding because of your first answer. Now all data binding is again defined in the "Binding" tab of the object. I tried a second approach and comment the code. See screenshot below:

 FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow::initialize - (JavaScript, client)

//Number of repeated DataRows (-1 because count from zero)
var vRows = TableTime.DataRow.instanceManager.count-1;

//Count Down-Loop deleting every Row that is not a Time Item (product unequal "Montage")
for(var i=vRows;i>=0;i--){
if(FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow[i].txtProduct != "Montage"){
TableTime.DataRow.instanceManager.removeInstance(i);
}
}

But it's still not working. As result I still get a complete table with all time and kiometer items. See screenshot below:

Do you have an idea what's wrong?

Best regards,

Deborah

0
Dhruvin Mehta Mar 13 at 08:14 PM
0

Hi i am not on my sysyem but a silly suggestion may be FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow[i].txtProduct here add ".rawValue" and check if it works

Show 7 Share
10 |10000 characters needed characters left characters exceeded

Hi Dhruvin Mehta,

I got the loop working with the following code (FormCalc in the initialize event of the TableTime - not in the DataRow) so that I'm now seeing one table with just time items. :)

Don't know why, but with addition ".rawValue" in js it does not work to address the field. So I used FormCalc and there this expression to address the txtProduct Field works.

FormServiceRequestConfirmation.Page2.frmZeiten.TableTime::initialize - (FormCalc, client)
//Number of repeated DataRows (-1 because count from zero)
var vRows = FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.instanceManager.count-1;

//Count Down-Loop deleting every Row that is not a Time Item (product unequal "Montage")
for i=vRows downto i >= 0 do
if (FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow[i].txtProduct ne "Montage")
then
FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow[i].presence = "hidden"
endif
endfor

Next problem is that the second table for kilometer items (TableKilometer) is completely empty, although I put in the same logic. :(

Is this because I have hidden the kilometer data in the first table (TableTime)?? Do you have an idea how to solve this?

All the best,

Deborah

0

Oh great, at least Time Table works now.

So now you need another table to be filled with another "type" of items. So just wanted to check below things.

1. Did u bind the ServiceRequest.items[*] to Kilometer table and ticked that repeat for each item?

because it should work since now we a re binding the same Table from data connection with just another table.

And for first do comment out the code in initialize method of kilometre table so that we know that JS is not at all impacting.-----------

I don't want you to go to another path , but few days ago I had the Same requirement, We had two types of items and we wanted them to get displayed in different table in form.

How we did was we didn't bind the table at all , We populate all the data in runtime in the initialize event of body via JS.

I will post the main code also if you want. But that seems more simpler at that time.

( This is just a suggestion )

I hope its clear! :)

1

Hi Dhruvin Mehta,

yes, the TableKilometer.DataRow has the data binding $.ServiceRequest.Item[*], and the single cells are also binded. I justed copied the first table :) Also the row has checked the repeat for each item. Then I tested to comment out the code of the TableKilometer, but the result was that the data binding is not working. I see an empty table Kilometer.

Then I also tested, just for fun, to comment out the code in the first TableTime and deleted the data binding there. Then, I see an empy TableTime and the kilometer items in the second TableKilometer expect of one time item (item ID 10) - strangely enough. See screenshot:

Perhaps you can send me your code / xdp file as personal message and I can also send you me xdp file.

Best regards,

Deborah

0

Hi I cant send the xdp file here in SCN , since its not allowed attachment type.Please check below code in my XDP file. I will mail also but posting the code here for fellow C4C consultants.

var ItemList = xfa.record.ServiceRequest.resolveNodes("Item[*]");
var ilength = ItemList.length;
var DateArray = new Array();
var IndexArray = new Array();
var tlength;
var wlength;
var tRow;
var wRow;
var sdate;
// Initialization the array for sorting
for(var i = 0 ; i < ilength; i++) {
	if (ItemList.item(i).ActualDatePeriod.StartDateTime != null) {
		sdate = ItemList.item(i).ActualDatePeriod.StartDateTime.value;
		sdate = sdate.replace(":", "");
		sdate = sdate.replace(":", "");
		sdate = sdate.replace("-", "");
		sdate = sdate.replace("-", "");
		sdate = sdate.replace("T", "");		
		DateArray[i] = sdate;
	}else {
		DateArray[i] = 0;
	}
	IndexArray[i] = i; 
}


// Sort in ascending order
for (var i = 0; i < ilength; i++ ) {
	for(var j = 0; j < ilength - i - 1; j ++ ) {
		if(DateArray[j]>DateArray[j+1]) {
			temp = DateArray[j];
			DateArray[j] = DateArray[j+1];
			DateArray[j+1] = temp;
			
			temp = IndexArray[j];
			IndexArray[j] = IndexArray[j+1];
			IndexArray[j+1] = temp; 
		}				
	}
}
//  Populate the travel time and work time tables
this.frmTravelTable.frmTravelRow.frmTravelTotal.TravelTotal.rawValue = 0;
this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue = 0;
wlength = 0;
tlength = 0;
for(var k = 0 ; k < ilength; k++) {
	i = IndexArray[k];
	// Skip non-relevant lines
	// Get the line type	
	var ltype = ItemList.item(i).resolveNode("Type_D69RE3TX8TIX738N4U9BIZ85R");
	var enotes = ItemList.item(i).resolveNodes("ItemTextCollection.Text[*]");
	var itemNotes;
	var itemNotesFound = false;
	if( enotes != null)
	{
		if (enotes.length > 0){
			itemNotes = enotes.item(0).ContentText.value;
			itemNotesFound = true;
		}
	}
	// Travel lines
	if (ltype.value == "111"){ //Travel
	tlength = tlength + 1;
	tRow = this.frmTravelTable.frmTravelRow.frmDynamic.instanceManager.addInstance(1);
	if (ItemList.item(i).ActualDatePeriod.StartDateTime != null) {
		tRow.tblTravel.rowTravelContent.colTravelDate.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;
		tRow.tblTravel.rowTravelContent.colTravelStartTime.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;
	}
	if (ItemList.item(i).ActualDatePeriod.EndDateTime != null) {
		tRow.tblTravel.rowTravelContent.colTravelEndTime.rawValue = ItemList.item(i).ActualDatePeriod.EndDateTime.value;
		tRow.tblTravel.rowTravelContent.colTravelDesc.rawValue = ItemList.item(i).Description.value;
	}
	tRow.tblTravel.rowTravelContent.colTravelLineQty.rawValue = ItemList.item(i).ActualQuantity.value;		
	this.frmTravelTable.frmTravelRow.frmTravelTotal.TravelTotal.rawValue = this.frmTravelTable.frmTravelRow.frmTravelTotal.TravelTotal.rawValue + tRow.tblTravel.rowTravelContent.colTravelLineQty.rawValue;		
	if (itemNotesFound == true)
	{
		tRow.tblTravelNotes.rowTravelNotes.colTravelDescLong.rawValue  = itemNotes;
	} else {
		tRow.tblTravelNotes.presence = "hidden";
		}
}


	// Work lines
	if (ltype.value == "101"){ //Work
		wRow = this.frmTableItems.tblItems.rowItemContent.instanceManager.addInstance(1);
		wlength = wlength + 1;
		wRow.colItemDate.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;	
		wRow.colItemStartTime.rawValue = ItemList.item(i).ActualDatePeriod.StartDateTime.value;
		wRow.colItemEndTime.rawValue = ItemList.item(i).ActualDatePeriod.EndDateTime.value;
		wRow.colItemLineQty.rawValue = ItemList.item(i).ActualQuantity.value;
		wRow.colItemLineDesc.rawValue = ItemList.item(i).Description.value;
		this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue = this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue + wRow.colItemLineQty.rawValue;
	}
}
this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue = this.frmTableItems.frmTableItemTotal.WorkTravelTotal.rawValue + this.frmTravelTable.frmTravelRow.frmTravelTotal.TravelTotal.rawValue;


if (tlength > 0){
	if (tlength < this.frmTravelTable.frmTravelRow.frmDynamic.instanceManager.count){
 		this.frmTravelTable.frmTravelRow.frmDynamic.instanceManager.removeInstance(0);		
 	}
}


if (wlength > 0){
	if (wlength < this.frmTableItems.tblItems.rowItemContent.instanceManager.count){
		this.frmTableItems.tblItems.rowItemContent.instanceManager.removeInstance(0);
	}
}



1

I now get the answer in the Adobe forum that it's unpossible with just data binding. It needs to be done with scripting to copy every value from TableTime to TableKilometer... (https://forums.adobe.com/message/10244840#)

1

Thanks this looks perfect...

0

Hi Dhruvin Mehta,

I decided not to use the copy function, because I think this is more complicated than to define the data binding in the script and just read out that data in the table that is relevant. So my plan is to insert an if-test before the data is read out in the time table and also an if-test for the kilometer table. Here is my code for the time table:

FormServiceRequestConfirmation.Page2.frmZeiten.TableTime::initialize - (JavaScript, client)
var ItemList = xfa.record.ServiceRequest.resolveNodes("Item[*]");
var ilength = ItemList.length;

for(var i = 0; i < ilength; i++){
var vProduct = xfa.record.ServiceRequest.Item(i).Description.value;
       if (vProduct = "Montage"){
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.instanceManager.addInstance(1);
       var ItemID = xfa.record.ServiceRequest.Item(i).ID.value;
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtID.rawValue = ItemID;
       var ItemDescription = xfa.record.ServiceRequest.Item(i).Description.value;
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtProduct.rawValue = ItemDescription;
       var ItemActivity = xfa.record.ServiceRequest.Item(i).activity_D69RE3TX8TIX738N4U9BIZ85RDescription.value;   
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtProduct.rawValue = ItemActivity;
       var ItemServicetechnician = xfa.record.ServiceRequest.Item(i).ServicePerformerParty.FormattedName.value;   
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtProduct.rawValue = ItemServicetechnician;
       var ItemStart = xfa.record.ServiceRequest.Item(i).ActualDatePeriod.StartDateTime.value;
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtStart.rawValue = ItemStart;
       var ItemEnd = xfa.record.ServiceRequest.Item(i).ActualDatePeriod.EndDateTime.value;
       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtEnd.rawValue = ItemEnd;
       }
}

However, I still have a problem with the definition of data out of XML in the script (especially with muplitle items -> item(i) is not working). That’s the result of my debugging...

If I use the following code (based on your code/your way to define the data out of the XML), I just get an object reference displayed („Object-293420228“).

var ItemList = xfa.record.ServiceRequest.resolveNodes("Item[*]");
var ilength = ItemList.length;

for(var i = 0; i < ilength; i++){
var ItemTest = ItemList.item(i).resolveNode("Description");
this.rawValue = ItemTest;
FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.instanceManager.addInstance(1);
}

And if I try the following code I get the „real“ data of the first item displayed, but I cannot control which one of the multiple item description I’m getting displayed.

var ItemTest = xfa.record.ServiceRequest.Item.Description.value;
this.rawValue = ItemTest;

And if I’m testing it to let a specific description get displayed with the following code, nothing happens at all - the text field stays empty. (tested with round and square clamps after item)

var ItemTest = xfa.record.ServiceRequest.Item(2).Description.value;
this.rawValue = ItemTest;

Any idea on this?

Thanks so much for your help…

Deborah

0
Dhruvin Mehta Apr 09 at 09:25 AM
0

Hi,

First of all, How are u able to debug it :P ?

Secondly, I am trying to understand your issue. You are adding item description on initialize event of the cell? Why do u need to resolve the node?

var ItemTest = ItemList.item(i).resolveNode("Description");
Can you please try below?

ItemList.item(I).Description.value; don t resolve the node.

Show 1 Share
10 |10000 characters needed characters left characters exceeded

Hi Dhruvin Mehta,

firstly: my debugging just is really complicated (every time to upload in C4C and test) and consits of creating a test text field where to test parts of the script...

secondly: you're right! If I leave out the resolve Node it works and I see the data. But my next issue is with the addition of the row (instanceManager.addInstance).

I tested the following script: (put the instanceManager.addInstance Row below the variables...)

var ItemList = xfa.record.ServiceRequest.resolveNodes("Item[*]");
var ilength = ItemList.length;

for(var i = 0; i < ilength; i++){
var vProduct = ItemList.item(i).Description.value;
    if (vProduct = "Montage"){
        
    var ItemID = ItemList.item(i).ID.value;
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtID.rawValue = ItemID;
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtProduct.rawValue = vProduct;
    var ItemActivity= ItemList.item(i).activity_D69RE3TX8TIX738N4U9BIZ85RDescription.value;       FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtActivity.rawValue = ItemActivity;
    var ItemServicetechnician= ItemList.item(i).ServicePerformerParty.FormattedName.value;    
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtServicetechnician.rawValue = ItemServicetechnician;
    var ItemStart= ItemList.item(i).ActualDatePeriod.StartDateTime.value;
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtStart.rawValue = ItemStart;
    var ItemEnd= ItemList.item(i).ActualDatePeriod.EndDateTime.value;
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.txtEnd.rawValue = ItemEnd;
    
    FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.instanceManager.addInstance(1);
    }
}
But the result is 2 table with just 1 row (see screenshot), and the data is also not "right" / not relative to the item product. So e.g. the Row in the Kilometer table displays also ID 10 (don't know why, the ticket just have once a ticket item with the ID 10) and the kilometer amount says 0.0. But in the ticket the first kilometer item is maintained with 200 km ...

In the form I nevertheless put a relative data binding in the DataRow "$.ServiceRequest.Item[*]" (object hierarchy).



//If I try it with the following code(set true), it also wrong... When 
//compiling the form in the C4C ticket it's running very long and just an 
//empty page is displayed.

FormServiceRequestConfirmation.Page2.frmZeiten.TableTime.DataRow.instanceManager.addInstance(true);

0