Create a mailto link with Arcade

4542
3
07-10-2019 01:25 PM

Create a mailto link with Arcade

Recently I was asked to help create an email link in a pop-up to send information about related records. Building on the example about retrieving the maintenance history posted here, Let's add a button that will send an email with that history. 

A mailto link may contain a couple of elements:

  • the email or emails to send the mail to
  • optionally the CC and/or BCC
  • a subject
  • and a body

The HTML we will use for the button is rather simple. It consists of an anchor with the mailto link (espression/expr1) and inside that anchor the button (see lines 5 to 7):

<b>Maintenance history:</b><br />
{expression/expr0}
<br /><br />
<b>Email History:</b> <br />
<a href="{expression/expr1}">
  <img alt="Email" height="50" src="http://icons.iconarchive.com/icons/iynque/ios7-style/1024/Mail-icon.png" width="50" />
</a>‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The pop-up looks like this when the user clicks on a point (sorry for mixing Spanish and English):

When the user clicks on the button this will create an email if you have an email application setup on your machine:

Let's dive into how to create the Arcade expression to get the information and structure it in such a way that it creates this email. The part of connecting to a related table and filter the table based on the ID of the hydrant has already been explained here: (Using FeatureSetBy functions in Arcade to drill-down to other layers and tables) so I won't go into detail. I used the same GetHistory function, with a small but important change on line 13:

Function GetHistory(hydrant_id) {
    var tbl = FeatureSetByName($map, "Maintenance");
    Console(tbl);
    var sql = "COD_HIDRANTE = '" + hydrant_id + "'";
    Console(sql);
    var tbl_filtered = Filter(tbl, sql);
    Console(Count(tbl_filtered));
    if (Count(tbl_filtered)> 0) {
        var history = "Please find below the maintenance history for Hydrant " + hydrant_id + ":";
        for (var maintenance in tbl_filtered) {
            var txt_date = Text(maintenance.Fecha_Mantenimiento, ' - (Y/MM/DD) ');
            var txt_man = txt_date + maintenance.Mantenimiento;
            history += "TextFormatting.NewLine" + txt_man;        
        } 
    } else {
        var history = "No history for Hydrant " + hydrant_id; 
    }
    return history;
}

I am adding "TextFormatting.NewLine" as string and not as constant. In fact this string could have any unique content, but I chose to do it this way. So the resulting string contains all the history on a single line and the text "TextFormatting.NewLine" will be used later on to replace it by something that can be used in an URL as will work as new line in the mail ("%0D%0A").

The other part of the expression is used to call this function and define the other parts of the email:

var hydrant_id = $feature["COD_HIDRANTE"];
var email = "someone@someplace.com";
var cc = "other_one@someplace.com;other_two@someplace.com";
var bcc = "secret_person@someplace.com";
var subject = "Maintenance history of Hydrant " + hydrant_id;
var body = GetHistory(hydrant_id);
var params = {cc: cc,
              bcc: bcc,
              subject: subject,
              body: body};

var url = "mailto:" + email + "?" + UrlEncode(params);
url = Replace(url, "TextFormatting.NewLine", "%0D%0A");
return url;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Let's explain what we do in this second part of the Arcade expression:

  • We read out the ID of the hydrant on line 1
  • Define the emails to send the email to (including 2 CC's and 1 BCC) on lines 2 to 4.
  • The subject is basically a text including the variable hydrant ID
  • The body is generated using the function GetHistory explained above
  • On lines 7 to 10 we create a dictionary called params with the properties cc, bcc, subject and body and we assign the values from the variables cc, bcc, subject and body defined on lines 3 to 6
  • On line 12 we use the new Arcade function UrlEncode (released in version 1.7) that will encode the URL parameters correctly
  • On line 13 we replace the text "TextFormatting.NewLine" by a text "%0D%0A" which will create the new lines where needed in the body of the email. If we would have done this before using the UrlEncode, this would have converted the text to "%250D%250A" and probably caused the new line not to work.

If you have any questions, please use the "Add a Reply" button to let me know.

Final code used is listed below:

Function GetHistory(hydrant_id) {
    var tbl = FeatureSetByName($map, "Maintenance");
    Console(tbl);
    var sql = "COD_HIDRANTE = '" + hydrant_id + "'";
    Console(sql);
    var tbl_filtered = Filter(tbl, sql);
    Console(Count(tbl_filtered));
    if (Count(tbl_filtered)> 0) {
        var history = "Please find below the maintenance history for Hydrant " + hydrant_id + ":";
        for (var maintenance in tbl_filtered) {
            var txt_date = Text(maintenance.Fecha_Mantenimiento, ' - (Y/MM/DD) ');
            var txt_man = txt_date + maintenance.Mantenimiento;
            history += "TextFormatting.NewLine" + txt_man;        
        } 
    } else {
        var history = "No history for Hydrant " + hydrant_id; 
    }
    return history;
}

var hydrant_id = $feature["COD_HIDRANTE"];
var email = "someone@someplace.com";
var cc = "other_one@someplace.com;other_two@someplace.com";
var bcc = "secret_person@someplace.com";
var subject = "Maintenance history of Hydrant " + hydrant_id;
var body = GetHistory(hydrant_id);
var params = {cc: cc,
              bcc: bcc,
              subject: subject,
              body: body};

var url = "mailto:" + email + "?" + UrlEncode(params);
url = Replace(url, "TextFormatting.NewLine", "%0D%0A");
return url;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Comments

@XanderBakker this is very useful - thank you! I'm wondering if you have a way for handling single quotes in fields. We have a content_ field in our data that often includes single apostrophes. Unfortunately, when we click our mailto link from the pop-up, the content_ field will not populate past the '. For example, the content_ field value might be "Michigan's 16 presidential electors have cast their votes...etc." When you click the mailto html link, only "Michigan" will populate. As a temporary fix we have used: 

var content = Replace($feature.content_, "'", "")

However, the grammar is not correct. Any suggestions?

Hi @RiannaAylward ,

 

Sorry for the delay in my reply, I was (and still am) on vacation.

First of all, I have noticed some problems with this arcade expression after an update was applied to ArcGIS Online (more than a year ago), so it might not work anymore.

However, the correct way of changing characters and create a valid URL is not using the Replace function, but the UrlEncode function as shown in the code. This function will replace any invalid characters by its valid representation in a URL: https://developers.arcgis.com/arcade/function-reference/text_functions/#urlencode 

 

Hi @XanderBakker 

This is super useful and I am trying to get it to work with a Survey123 feature edit workflow, where the URL opens automatically the associated feature in Survey123. However, I can't seem to get the globalid to be seen as part of the URL. I've tried a lot of variations at this point combining Arcade field cals as well as use of {globalid} directly in the mailto: field in the pop-ups and haven't had any luck -- do you have any suggestions? 

Example of the issue:

BrittanyBurson_0-1669242946090.png

I'm working in Enterprise 10.8.1.

Thank you!

Version history
Last update:
‎12-12-2021 03:47 AM
Updated by: