Copy contact info to clipboard by one click in Dynamics CRM

Microsoft Dynamics CRM 2016 is a very efficient application for storing contacts and accounts data. CRM users often need to share some contact or account data with another person. Sharing with other employees of the same company is easy and can be done by Email a link command. But users need to share data also with a person outside their companies. For example, employees want sometimes send a salesman contact to a potential customer.

copy-contact-info

We have developed a workflow which sends contact data to user’s e-mail and then the user can resend this e-mail to another person. However, users demanded faster and more efficient way. So I have created a button which is situated on Contact and Account entity forms. After clicking on this button the data are copied into Windows Clipboard. The user can paste the data anywhere he wants just by pressing Ctrl+V. This is a much more straightforward way and we have received positive reviews from our customers.

The button is inserted into the forms as Iframe. The button page is written in pure XHTML and JavaScript so it can be saved directly on the CRM application server. Just make sure that IIS can access the folder. If you are using Dynamics CRM Online you can save this page in Azure, on your company web server etc.

I used an easy clipboard.js library which you can download here https://clipboardjs.com/. Make sure to save the library to the same folder as the XHTML file.

Loading entity field data is quite simple and it can be done by Xrm.Page.data.entity attribute. I load two custom fields of the Contact entity: new_degree, new_suffix. I also have a custom entity new_location which gathers address data (like street, city, country etc.). I have lookup fields new_locationid and new_defaullocationid with location’s id. It’s not possible to load lookup entity data directly by Xrm.Page.data.entity, so I use CRM Web API, which has been supported since CRM 2016. This is implemented in RetrieveLocationData function. I create a request with a list of attributes which I want to show. Then I parse the request reply.

This is a sample output for the Contact entity:

Ing. Jiří Pešík
AIMTEC Outsourcing s.r.o.
Consultant

Jiri.Pesik@aimtec.cz
+420 TELEPHONENUMBER

Hálkova 32
Plzeň
301 22
CZECH REPUBLIC

And this is a sample output for the account entity:

AIMTEC Outsourcing s.r.o.
Hálkova 32
Plzeň
301 22
CZECH REPUBLIC

And this is the source code of the page.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <title>Title of document</title>
    <script src="clipboard.min.js"></script>
</head>

<body>
    <button id="btn" data-clipboard-text="">Copy details to clipboard</button>

    <script src="clipboard.min.js"></script>
    <script>
        var btn = document.getElementById('btn');
        var clipboard = new Clipboard(btn);

        var CrmEncodeDecode = top.CrmEncodeDecode;

        function GetQueryString(url, name) {
            var regEx = new RegExp("[?|&]" + name + "=([^&|$]*)", "ig");
            if (regEx.exec(CrmEncodeDecode.CrmUrlDecode(url)) != null) {
                return RegExp.$1;
            }
            return null;
        }

        var entityId = GetQueryString(location.search, "id");
        entityId = entityId.replace("%7b", "");
        entityId = entityId.replace("%7d", "");
        var clientURL = location.origin + "/AIMTEC";
        console.log(clientURL);
        var data = null;

        function RetrieveLocationData(locationId) {
            var req = new XMLHttpRequest()
            req.open("GET", encodeURI(clientURL + "/api/data/v8.1/new_locations(" + locationId + ")?$select=new_street1,new_street2,new_city,new_zip,new_state,new_countryid&$expand=new_countryid($select=new_name)"), true);
            req.setRequestHeader("Accept", "application/json");
            req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
            req.setRequestHeader("OData-MaxVersion", "4.0");
            req.setRequestHeader("OData-Version", "4.0");
            req.onreadystatechange = function() {
                if (this.readyState == 4 /* complete */ ) {
                    req.onreadystatechange = null;
                    if (this.status == 200) {
                        data = JSON.parse(this.response);
                        textToCopy += data.new_street1 || "";
                        textToCopy += "\n";
                        if (data.new_street2 != null) {
                            textToCopy += data.new_street2;
                            textToCopy += "\n";
                        }
                        if (data.new_city != null) {
                            textToCopy += data.new_city;
                            textToCopy += "\n";
                        }
                        if (data.new_zip != null) {
                            textToCopy += data.new_zip;
                            textToCopy += "\n";
                        }
                        if (data.new_state != null) {
                            textToCopy += data.new_state;
                            textToCopy += "\n";
                        }
                        if (data.new_countryid.new_name != null) {
                            textToCopy += data.new_countryid.new_name;
                            textToCopy += "\n";
                        }

                        document.getElementById("btn").setAttribute("data-clipboard-text", textToCopy);
                    } else {
                        var error = JSON.parse(this.response).error;
                    }
                }
            };
            req.send();
        }

        var entityTypeName = GetQueryString(location.search, "typename");

        var textToCopy = "";

        if (entityTypeName === "contact") {
            if (window.parent.Xrm.Page.getAttribute("new_degree") != null) {
                textToCopy += window.parent.Xrm.Page.getAttribute("new_degree").getText();
                textToCopy += " ";
            }
            textToCopy += window.parent.Xrm.Page.getAttribute("firstname").getValue() || "";
            textToCopy += " ";
            textToCopy += window.parent.Xrm.Page.getAttribute("lastname").getValue() || "";
            if (window.parent.Xrm.Page.getAttribute("new_suffix").getValue() != null) {
                textToCopy += ", ";
                textToCopy += window.parent.Xrm.Page.getAttribute("new_suffix").getText() || "";
            }
            textToCopy += "\n";

            var accountLookup = window.parent.Xrm.Page.getAttribute("parentcustomerid").getValue();
            var accountName = accountLookup[0]["name"];
            textToCopy += accountName;
            textToCopy += "\n";

            textToCopy += window.parent.Xrm.Page.getAttribute("jobtitle").getValue() || "";
            textToCopy += "\n\n";
            textToCopy += window.parent.Xrm.Page.getAttribute("emailaddress1").getValue() || "";
            textToCopy += "\n";
            textToCopy += window.parent.Xrm.Page.getAttribute("mobilephone").getValue() || "";
            textToCopy += "\n";
            if (window.parent.Xrm.Page.getAttribute("telephone2").getValue() != null) {
                textToCopy += window.parent.Xrm.Page.getAttribute("telephone2").getValue() || "";
                textToCopy += "\n";
            }

            textToCopy += "\n";

            var addressLookup = window.parent.Xrm.Page.getAttribute("new_locationid").getValue();
            var addressId = addressLookup[0]["id"].replace("{", "").replace("}", "");
            RetrieveLocationData(addressId);
        } else if (entityTypeName === "account") {
            textToCopy += window.parent.Xrm.Page.getAttribute("name").getValue() || "";
            textToCopy += "\n";
            var addressLookup = window.parent.Xrm.Page.getAttribute("new_defaullocationid").getValue();
            var addressId = addressLookup[0]["id"].replace("{", "").replace("}", "");
            RetrieveLocationData(addressId);
        }

        document.getElementById("btn").setAttribute("data-clipboard-text", textToCopy);

        clipboard.on('success', function(e) {});
        clipboard.on('error', function(e) {});
    </script>
</body>

</html>

Leave a Reply

Name and email address are required. Your email address will not be published.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

You may use these HTML tags and attributes:

<a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <pre> <q cite=""> <s> <strike> <strong> 

%d bloggers like this: