Microsoft InfoPath 2010
The official blog of the Microsoft InfoPath team

Email Submit "To" line (loops in formulas)

Email Submit "To" line (loops in formulas)

Rate This
  • Comments 62
Everyone likes InfoPath's email data connection because it lets you collect forms using email only, no other infrastructure required (no need for Windows SharePoint Services, SQL Server, or even a file share). We've built even more Outlook integration in InfoPath 2007 Beta, but since most of you don't have that yet, let me share a tip that will work in both InfoPath 2003 and 2007.
 
The basics: Single dynamic email address
As your probably know, the To and CC line of the email data connection can come from a textbox in the form by using a formula. To do that, just use the Fx button next to the To line in the data connection wizard:
 
 
The trick: Multiple email addresses from repeating controls
Some forms have a list of names they want to send to, but the simple formula above won't work for that.
 
For example, consider a repeating table that looks like this:
 
 
With this data source (note that "person" is repeating):
 
 
So you want to produce this semicolon-separated list of e-mails:
 
 
 
A good instinct is to use the "concat" function, but unfortunately that only works on the first element in a repeating structure.
 
So then comes the team insight: Our "eval" function returns a list of nodes which actually share an anonymous parent. That means you can use one eval functions to create a list of the email addresses, then wrap it in another eval function that gets the parent of that list.
 
Voila, here's the formula to solve the problem:
eval(eval(person, "concat(my:email, ';')"), "..")
 
(Note that "person" can be inserted from the data source, but "my:email" needs to be typed by hand or you'll get an error.)
 
For the curious: Here's how it's done
Let's break down that XPath formula from the inside out:
 
  • "concat(my:email, ';')" - Adds a semicolon to each email address.
  • eval(person, "concat(my:email, ';')") - Loops through each person to create a list of email addresses
  • eval(eval(person, "concat(my:email, ';')"), "..") - Gets the anonymous parent of the email addresses, and converts them to a string.
 
So the end result returns the contents of that anonymous parent, which is a series of semicolon-delimited email addresses. Phew!
 
In summary
We are using two tricks here:
  • The fields returned by eval() all have the same anonymous parent (feature of InfoPath's function)
  • The string value of a parent is the concatenation of all its children (W3C spec’ed)
 
- David Airapetyan (Software Design Engineer) and Ned
Leave a Comment
  • Please add 2 and 3 and type the answer here:
  • Post
  • Hi,

    First of all, thanks for very useful post.

    It works very good, but I have just a little lack.

    The structure of my secundary dataconnection is like that:

    myFields

    dataFields

     ns1:GetAdmittingDiagnosisResponse

      GetAdmittingDiagnosisResult

       AdmDiagnosis

        Code

        ClinicalPriorityDesc

        ...

    My formula is:

    eval(eval(AdmDiagnosis[ClinicalPriorityDesc != "Secundario"]; 'concat(ns1:Code, "~", ns1:Description, "¬")'); "..")

    In XPath:

    xdMath:Eval(xdMath:Eval(xdXDocument:GetDOM("GetAdmittingDiagnosis")/dfs:myFields/dfs:dataFields/ns1:GetAdmittingDiagnosisResponse/ns1:GetAdmittingDiagnosisResult/ns1:AdmDiagnosis[ns1:ClinicalPriorityDesc != "Secundario"], 'concat(ns1:Code, "~", ns1:Description, "¬")'), "..")

    This formual works perfect, but if I try the equal filter

    [ClinicalPriorityDesc = "Secundario"]

    This error raised:

    "msxml5.dll

    Reference to undeclared namespace prefix: 'ns1'.

    Error occurred during a call to property or method 'Eval'."

    I workaround this issue using the not equal comparision instead the equal, but I'm curious if there is a way to fix that...

    Thanks

  • I am receiving the same issue with the formula: "../my:RepeatingTable/my:NomineesHidden/my:Person" does not point to a valid location path of a field or group.

    I first tried the formula in the main body of the post. When that didn't work, I copied the formula that was given to someone else and adjusted the group names to fit my .xsn. Here is the XPath formula:

    substring(xdMath:Eval(xdMath:Eval(../my:RepeatingTable/my:NomineesHidden/my:Person, 'concat(my:AccountID, ";")'), ".."), 1, string-length(xdMath:Eval(xdMath:Eval(../my:RepeatingTable/my:NomineesHidden/my:Person, 'concat(my:AccountID, ";")'), "..")) - 1)

    My data structure is this:

    NomineeTopGroup (non-repeating Group)

      RepeatingTable (repeating table)

         NomineeHidden (non-repeating Group)

           pc:Person (repeating person group)

              display name (string)

              accountid (string)

              accounttype (string)

    I have tried everything I can think of to fix the formula so that it recognizes the AccountID field, but I have failed.

    I'd appreciate any help you could provide.

  • does not work with people picker sp 2010

  • Hi, thanks for this post, I managed to solve one of my problems :).

    I was trying to get te same result from a multiple-selection listbox, but can't get it to work.

    This is the datastructure :

      group1

        repeating field1

      field2

    I would like to see the checked item from field1 in field2, ';' seperated.

    all help appreciatied :)

    Jan

  • I have been looking for answer to send email to multiple people using InfoPath function ""Person/Group Picker" and data connection.

    Finally, using this formula and adding some tricks I was able to do it.

    My Data Source Looks like this:

    Notification-group

      Notification-send-to

      Notification-send-to-group (Person/Group Picker)

         pc:Person

             DisplayName

             AccountId

             AccountType

    Set default value for "Notification-send-to"

    eval(eval(Person, 'concat(pc:AccountId, ";")'), "..")

    Setup data connection for email and enter following formula to remove domain name in “To” using “fx”

    translate(Notification-send-to, "DOMAIN NAME\", "")

    Thank you,

  • first of all hi!.i have a forma and a people list.

    Structure:

    myFields

       Group

           pc:Person (repeating group)

                   DisplayName

                   AccountId

                   AccountType

    i want so send emails to several DisplayName and cannot make it work :(

  • I am having a form with different sections and the momment the user hits the submit button I need each section in this form to be sent to different e-mails, I mean If I am having 3 sections in the form I need each of these 3 sections to be sent to 3 different e-mails. Any ideas how can I achieve this goal ?

  • Does anybody besides me thinks that InfoPath is not the great tool they promote?

  • Exactly what I needed. Thanks Bunch!!!

  • hi scott

    I really admire you for your good answer

    tanx a lot

  • It worked for me. I used my secondary data source instead of "person" and I used "." (current field value) instead of "my:email". Thanks

  • Solved it with this formula

    eval(eval(Person, 'concat(concat(substring-after(pc:AccountId, "\"), "@domain.com"), ";")'), "..")

  • I am facing a weird issue and do not know how to solve. Please help.

    I am using Infopath and I have one multi-selection listbox with secondary data connection with total 4 columns. There are ID, Title, Email Address, Description.

    The listbox is displaying Title value.

    Purpose: user need to check the listbox and decided which listbox to select. Once tick, the eval formula will look up Email Address column and send email out. This is the formula - eval(eval(Email, 'concat(., ";")'), "..")

    Question: why the email display without check any check box?

    Expectation: User should check the box then email address only show in email To list

    Thank you.

  • Hi Scott,

    I have a master/detail repeating table in my form, and one of fields is "EmailAddress" which shows customer's email address. I created a submit button and put the "EmailAddress" field to "TO" object. When I tested it, the submit button only would return the first row of emailaddress from the repeating table, but not the rest of it.. Even thought I put the XML code like this: current()/dfs:dataFields/d:vw_HZLeadLists/@EmailAddress

    It still just return the first record of emailaddress... Could you give me some ideas? Thanks a lot!

    -Lun

  • Thank you very much! It was a lot of help

Page 4 of 5 (62 items) 12345