Wednesday, September 30, 2015

SharePoint 2013 Send email to multiple users in designer workflow


Requirement: We need a form with fields Title, link, attachments and cc users. On form submit, an email notification should be sent to submitted user and CC to "CC Users"

Developer Solution:
1. Create a list / app with fields;
                                 Title - Single line of text
                                 Link - Hyperlink
                                 Attachments - OOTB
                                 CC Users - Person or Group (Allow Multiple)
 2. Create a designer workflow attached to that list

End Result: NO !!!!!!!!!!!!!!!!!!!

What Happened: If multiple users are present in "CC Users" column then SharePoint designer workflow sends an email to only ONE user. This is a major limitation in SharePoint.

Microsoft Support Response: If you want to send an email to dynamic multiple users then use either mention a group in people column or create a text column and enter the user's email address.
https://support.office.com/en-in/article/Send-e-mail-in-a-workflow-11d5f9dd-955f-412c-b70f-cde4214204f4

Developer Reaction: Whaaaaaaaaaaaaaaaaaaaaaaaaat !!!!!!!!!!!! :@

=======================                           ====================

Not to worry. I have found out a solution for this.

My Investigation: In SharePoint 2013, Once the name is resolved in people picker, DIV element is added dynamically with the ID "divEntityData". There is an another div inside it with the attribute "data". If you look at it carefully, you will see a XML with key-value pair nodes. It contains all necessary information like Title, Department, SIPAddress, Mobile and Email. I have attached a sample below [removed few keys since it is confidential ;) ]. That's it !!!!!!!!!!!! We can make use of it.

<ArrayOfDictionaryEntry xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DictionaryEntry><Key xsi:type="xsd:string">Title</Key><Value xsi:type="xsd:string">Contractor: SevalHub</Value></DictionaryEntry>
<DictionaryEntry><Key xsi:type="xsd:string">Department</Key><Value xsi:type="xsd:string">IT</Value></DictionaryEntry>
<DictionaryEntry><Key xsi:type="xsd:string">Email</Key><Value xsi:type="xsd:string">dmahendranme@gmail.com</Value></DictionaryEntry>
</ArrayOfDictionaryEntry>

Solution for the same requirement:
1. Create a list / app with fields;
                                 Title - Single line of text
                                 Link - Hyperlink
                                 Attachments - OOTB
                                 CC Users - Person or Group (Allow Multiple)
                                 ccinternal - Multiple line of text (Hide this column to users)

2. Customize the NewForm and EditForm pages.
    - Add custom CSS class to both fields
    [NewForm.aspx sample below. I have added ccemail and ccinternal CSS classes. You should not copy this code. I added it for your reference.]

<tr>
    <td width="190px" valign="top" class="ms-formlabel">
    <H3 class="ms-standardheader">
        <nobr>CC Users</nobr>
    </H3>
    </td>
    <td width="400px" valign="top" class="ms-formbody ccemail">
    <SharePoint:FormField runat="server" id="ff14{$Pos}" ControlMode="New" FieldName="ccusers" __designer:bind="{ddwrt:DataBind('i',concat('ff14',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@ccusers')}"/>
    <SharePoint:FieldDescription runat="server" id="ff14description{$Pos}" FieldName="ccusers" ControlMode="New"/>
    <span class="tip">Enter name(s) of person(s) to receive a copy of this request</span>
    </td>
</tr>

<tr class="ms-hidden"><!-- class="ms-hidden" is to hide our ccinternal field from end users -->
    <td width="190px" valign="top" class="ms-formlabel">
    <H3 class="ms-standardheader">
        <nobr>ccinternal</nobr>
    </H3>
    </td>
    <td width="400px" valign="top" class="ms-formbody ccinternal">
    <SharePoint:FormField runat="server" id="ff22{$Pos}" ControlMode="New" FieldName="ccinternal" __designer:bind="{ddwrt:DataBind('i',concat('ff22',$Pos),'Value','ValueChanged','ID',ddwrt:EscapeDelims(string(@ID)),'@ccinternal')}"/>
    <SharePoint:FieldDescription runat="server" id="ff22description{$Pos}" FieldName="ccinternal" ControlMode="New"/>
    </td>
</tr>

3. Place the below Javascript function in the page. If you are referencing .js then place it in that file.
    [jQuery is used]

function insertccemail()
{
    var emails='';
    $('.ccemail #divEntityData').each(function(){
        var x = $.parseXML($(this).find('div').attr('data'));
        var profiles = x.getElementsByTagName("DictionaryEntry");
        $.each(profiles, function (index, value){if($(value).find('Key').text()=='Email') if($(value).find('Value').text()!='') emails+=$(value).find('Value').text()+'; ';});
    });

    $('.ccinternal textarea').text(emails); // Used textarea because I have created Multiple line of text field for ccinternal

} // insertccemail - Ends


//alert(profiles[0].getElementsByTagName("Value")[0].childNodes[0].nodeValue);  - In Javascript. This alert sample which I tried for testing.

4. Call this insertccemail() function in PreSaveAction(). This PreSaveAction function should be placed inside the form only. You should not place it in .js file and refer it.

function PreSaveAction()
{
    insertccemail();
    if(ValidateFields()) //Never mind. ValidateFields() is a custom Javascript function to validate my fields on Save
       return true;
    else
       return false;
} // PreSaveAction - Ends

5. In designer workflow, refer the "ccinternal" column in CC field.





We are Creators.  Happy Thinking ! :)


1 comment:

  1. For sharepoint 2019 On premise and sharepoint 2013 platform
    After a long search for a module that sends email, I can recommend a ready-made one. here is their website https://activitydeploy.com

    ReplyDelete