I am trying to put the value in the last row of a table in a form in an email without workflow. What is the syntax to grab a specific row value instead of all values separated by a semicolon?
Question
Question
Token Syntax to return value in the last row of a table in forms
Answer
Hi Elexis,
As far as I know, you can't do a negative index or anything.
As a workaround, you could create a hidden field on the form that gets the number of rows. The rows start indexing at 1 so that'll be the index of your last row
=COUNTIF(Source_Table.Column_2,"<>")
Then use that variable in your email
{/dataset/Source_Table/Column_2[{/dataset/Last_Row}]}
If any of those rows can be blank you'll need a different calculation, but you get the idea.
Replies
Something like...
const emailVal = $("#q3 tr td[data-title='column2'] input").last().val();
Thanks but I need the syntax to be used in native forms not java. I know it is something like {/dataset/Table/Column[row#]} but I can't figure out how to get the last row when I don't know how many rows there are. I tried {/dataset/Table/Column[-1]} but it did not return a value.
I also cannot get anything to return when I use 1.
I'm interested if someone else has a better solution...
I would use either Workflow or JS to select/process the value and then store it in a hidden form field to be retrieved by your email service task. Hopefully, there's a more elegant way to do it.
Hi Elexis,
As far as I know, you can't do a negative index or anything.
As a workaround, you could create a hidden field on the form that gets the number of rows. The rows start indexing at 1 so that'll be the index of your last row
=COUNTIF(Source_Table.Column_2,"<>")
Then use that variable in your email
{/dataset/Source_Table/Column_2[{/dataset/Last_Row}]}
If any of those rows can be blank you'll need a different calculation, but you get the idea.
This works well, I just wanted to add that I couldn't use this tokenized index variable directly in the email. I had to create a field to put the indexed token in and then use that field in the email body.
@████████ Interesting. Which version of Forms are you running? I tested this in my test/dev environment which is running Forms 11 Update 2 and it worked from the email so it may be a recent addition.
11.0.2108.10347
I was getting an error (below) and the email task would suspend. So I moved it to a field and them used the new variable. That worked.
An unexpected error has occurred. [LFF502-UnexpectedError] Details: URL: Error: UnexpectedError Date: 2/5/2022 9:01:47 AM (Central Standard Time) HTTP Status Code: 500 Business Process ID: 29 Instance ID: 13277 Business Process Name: Solutions - Order Processing Stack Trace: Caught exception: Laserfiche.Forms.CommonUtils.Exceptions.LFFormsException Message: An unexpected error has occurred. [LFF502-UnexpectedError] Inner exception: System.Xml.XPath.XPathException Message: '/dataset/projectHoursTable/Month<span style="font-size: 14px;">[</span><span style="font-size: 14px;">4</span><span style="font-size: 14px;">]</span><span style="font-size: 14px;">' has an invalid token. at MS.Internal.Xml.XPath.XPathParser.ParseXPathExpresion(String xpathExpresion) at System.Xml.XPath.XPathExpression.Compile(String xpath, IXmlNamespaceResolver nsResolver) at System.Xml.XPath.XPathNavigator.Select(String xpath) at System.Xml.XmlNode.SelectNodes(String xpath) at Laserfiche.Forms.Routing.AttributeToken.ParseTokens(Boolean Encode, XmlDocument xmldoc, String inString, cf_users user, Boolean keepIfNoMatch, String TimeZone, Int32 pos, ConvertToLocalDateFormat ConvertToLocalDateFormat, Boolean translateTokens, Boolean escapeEncode, ICollection`1 fields, Boolean replaceNewlines, ParseTokenOptions tokenOption, Boolean retainCurrentUserToken, Boolean removeGroupSeparators, Int32 currentRow, Boolean useGregianCal, Int32 attempts, Boolean ignoreXPathError) at Laserfiche.Forms.Routing.AttributeToken.ParseTokensEncoded(XmlDocument xmldoc, String inString, cf_users user, Boolean keepIfNoMatch, String TimeZone, Int32 pos, ConvertToLocalDateFormat ConvertToLocalDateFormat, Boolean translateTokens, Boolean escapeEncode, ICollection`1 fields, Boolean replaceNewlines, ParseTokenOptions tokenOption, Boolean retainCurrentUserToken, Boolean removeGroupSeparators, Int32 currentRow, Boolean useGregianCal, Boolean ignoreXPathError) at FormsModel.DomainServices.EmailSendItem.GenerateEmailMessage() at FormsModel.DomainServices.EmailSendItem..ctor(IEntityContext appContext, EmailService emailService, XmlDocument datasetXml, String timezone, cf_bp_worker_instances processInstance) at FormsModel.DomainServices.EmailSendService.PrepareEmailWithRoutingContext(EmailService emailService, Int32 instanceId, IRoutingContext routingContext, RoutingInstanceStatus originalStatus) at Laserfiche.Forms.Routing.EmailService.Execute(Int32 instanceId, IRoutingContext routingContext, RoutingInstanceStatus OriginalStatus) at Laserfiche.Forms.Routing.ServiceTask.Execute(Int32 instanceId, IRoutingContext routingContext)
That's odd. Hard to say for sure, but it could've just been a typo in the token name or syntax, but pulling the value into a field on the form is equally effective and probably easier to manage anyway.