on 2024 Feb 23 3:47 PM
Hello experts,
I am struggling with the syntax to embed UDF values in FSM HTML Checkout report.
I analyzed the data.js file and the UDF value are displayed in this format:
However, how should the syntax in the template.js look like? I tested different versions (e.g. udf.MILEAGE_NOTES) but they are not working...
Can someone please help?
Thanks a lot!
Best regards,
Deborah
@krzysztof_szalach Do you have a tip?
Request clarification before answering.
Okay, so it took me a while, but @DAcker I've found some sort of generic solution.
In template.js add for getMileagesTableDescriptor new column:
{
headerKey: 'Mileage_Udf_Notes_L', udfValue: 'MILEAGE_NOTES',
}
then in template.html in genericTableTemplate for <td> entry:
{{else if udfValue}}
{{#each data-row.udfValues}}
{{#compare meta.name "==" column.udfValue}}
{{value}}
{{/compare}}
{{/each}}
Nów, how it works:
- when generating generic table it will check if attribute "udfValue" in column is set. If yes, it iterates through all udfValues for this row and checks if meta.name matches the attribute value. This way you can use it in any table.
Full code:
genericTableTemplate
<script id="genericTableTemplate" type="text/x-handlebars-template">
{{#if dataGroups}}
{{#gt dataGroups.length 0}}
<section class="generic-table">
<h2>{{ localize titleKey }}</h2>
<table>
<thead>
<tr>
{{#each columns}}
<th>{{ localize headerKey }}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each dataGroups as |data-group|}}
{{#each . as |data-row|}}
<tr>
{{#each ../../columns as |column|}}
<td>
{{#if propertyName}}
{{formatValue (get propertyName data-row) column }}
{{else if aggregate}}
{{formatValue (aggregateValues data-row column) column }}
{{else if udfValue}}
{{#each data-row.udfValues}}
{{#compare meta.name "==" column.udfValue}}
{{value}}
{{/compare}}
{{/each}}
{{/if}}
</td>
{{/each}}
</tr>
{{/each}}
<tr>
{{#each ../columns as |column|}}
<td>
{{#if column.footer}}
<div class="column-footer">
{{#if column.footer.formatFooter}}
{{formatValue (callFunction column.footer.valueProvider ../this/this) column}}
{{else}}
{{callFunction column.footer.valueProvider ../this/this}}
{{/if}}
</div>
{{/if}}
</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
</section>
{{/gt}}
{{/if}}
</script>
getMileagesTableDescriptor
const getMileagesTableDescriptor = (mileages, localization) => ({
titleKey: 'EntityPluralName_Mileage',
columns: [
{
headerKey: 'Mileage_StartDate', propertyName: 'travelStartDateTime', templateId: 'dateTimeTemplate', templateOptions: {formatString: 'L'},
footer: {
valueProvider: _ => localization.total,
formatFooter: false
}
},
{headerKey: 'ExpenseMaterialMileage_Detail_CreatePerson_L', aggregate: ['createPerson.firstName', 'createPerson.lastName'], operator: 'concat'},
{headerKey: 'Mileage_Detail_From_L', propertyName: 'source'},
{headerKey: 'Mileage_Detail_To_L', propertyName: 'destination'},
{
headerKey: 'Mileage_Detail_Distance_L', propertyName: 'distance', templateId: 'numberTemplate',
footer: {
valueProvider: mileages => mileages.map(mileage => mileage.distance).reduce((acc, current) => acc + current, 0),
formatFooter: true
}
},
{
headerKey: 'Mileage_Detail_TravelDuration_L', aggregate: ['travelEndDateTime', 'travelStartDateTime'], operator: 'difference', templateId: 'durationTemplate',
footer: {
valueProvider: mileages => mileages.filter(mileage => mileage.travelStartDateTime && mileage.travelEndDateTime).map(mileage => mileage.travelEndDateTime - mileage.travelStartDateTime).reduce((acc, current) => acc + current, 0),
formatFooter: true
}
},
{headerKey: 'Mileage_Udf_Notes_L', udfValue: 'MILEAGE_NOTES'}
],
dataGroups: mileages && mileages.length ? [mileages] : []
});
Although for me column header is not displayed even I've added key to localization file, but I will leave it up to you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
As addition for the community - here the code if there are multiple UDF value and you have to loop over it:
if (columnDefinition.operator == 'concat') {
return columnDefinition.aggregate.map(prop => {
//Custom, UDF handling (line 25-33 custom)
if (prop.startsWith('udfValue.')) {
let udfValue = prop.split('.')[1];
for (const element of context.udfValues){
if (element.meta.name === udfValue){
return element.value;
}
} return "";
} else {
return Handlebars.helpers.get(prop, context);
}
}).reduce((acc, current) => acc + ' ' + current, '');
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello @Krzysztof_szalac,
this is unfortunately not working. I added a custom method to the template.js (see screenshot).
In the webbrowser development mode I can see the correct UdfValue in the console (see screenshot). However, the column is not displaying the correct value - only [object]. If I just to test maintain udfValues[0].value it is not showing anything (empty).
However, mileage details with the other SAP standard fields are implemented in an existing loop in html (each dataGroups...) and with the getMileagesTableDescriptor constant in template.js, see screenshot. I tried to add another parameter for the const getMileagesTableDescriptor (line 166), not working. Inside the 'propertyName' to call the method doesnt work.
template.js
loop, template.html
So the simple request to read from a JSON a certain value is possible and works (see browser console log), but within in the context of the SAP HTML report for checkout in FSM, is is complicated...
Do you have another tip?
Best regards, Deborah
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
deleted
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@DAcker although I'm not an expert in html reports, what I can suggest - as you already noticed udf values are stored as json object with some well understandable template. It's not possible to access it directly as you want, but rather you should create custom js function to retrieve the needed value from that json. SOmething like this:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
3 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 | |
1 | |
1 | |
1 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.