Printing filed emails using a custom button (for Sage CRM v7.1sp2 and earlier)

Hints, Tips and Tricks

Technical Hints Tips and Tricks that cover customization and development using Sage CRM. API usage and coding are covered.

Printing filed emails using a custom button (for Sage CRM v7.1sp2 and earlier)

  • Comments 14
  • Likes

Note:  This article discusses techniques relevant for Sage CRM v7.1sp2 and earlier.  If you are using Sage CRM 7.2 please refer to the articles that discuss the new Client Side API.

Jeff wrote previously about using button groups to add a Print button to a system screen. Using window.print() will send the EWARE_MID frame to the printer. But what if you want to print a particular area of the screen, such as your sent emails?

The trick to this is to set the screen focus briefly on the IFrame containing the email body, then send that to the printer. This will allow you to print the full email body, without having to include the rest of the screen objects.

This method requires the additon of a button group and a simple custom content script.

1: As an admin, go to Administration -> Advanced Customisation -> Button Groups.
2: Add a new button group named EmailPrint with an action of Edit Company Email Address. Save the button group.
3: Select the new button group. The group contents window will open.
4: Add an item with a caption of Print, an action of customURL and a URL name of javascript: x=printMailFrame(); void(x);
5: Select print.gif for the bitmap, then save your changes.

For the next part, go to Customisation -> Communication -> Screens -> EmailFilingBox and add the following to the Custom Content:


<script>
function GetElem (a) {
    return document.getElementById(a);
}
function printMailFrame ()
{
// Look for the IFRAME and check to make sure it's the right one
var testURL = /Act=373/;

for (var i=0;i<document.frames.length;i++)
{
    if(testURL.test(document.frames[i].location))
    {
        // test if it's a mass email
        var hasMultipleRecipients = false;
        var multipleRecipientsText = /Act=375/i;
        var links = document.getElementsByTagName('A');
 
        for (var j=0; j<links.length; j++)
        {
            var link = links[j];
            if (link.onclick)
            {
                if (multipleRecipientsText.test(link.onclick))
                {
                    hasMultipleRecipients = true;
                    break;
                }
            }
        }
 
        // Creates a table with the email details
        var emailDetails = document.frames[i].document.createElement('table');
        emailDetails.style.fontFamily='Arial';
        emailDetails.style.fontSize='12';
        var tr1 = emailDetails.insertRow(0);
        var tr2 = emailDetails.insertRow(1);
        var tr3 = emailDetails.insertRow(2);
        var tr4 = emailDetails.insertRow(3);
        var td1 = tr1.insertCell(0);
        var td2 = tr1.insertCell(1);
        var td3 = tr2.insertCell(0);
        var td4 = tr2.insertCell(1);
        var td5 = tr3.insertCell(0);
        var td6 = tr3.insertCell(1);
        var td7 = tr4.insertCell(0);
        var td8 = tr4.insertCell(1);
        td1.innerHTML = sentString + ':';
        td2.innerHTML = GetElem('_Datacomm_datetime').innerText;
        td3.innerHTML = fromString + ':';
        td4.innerHTML = GetElem('_Datacomm_from').innerText;
        td5.innerHTML = recipientString + ':';
 
        // Recipients depends on if it's
        // a mass email
 
        if(hasMultipleRecipients === true)
            td6.innerHTML = massMailString;
        else
            td6.innerHTML = GetElem('_Datacomm_to').innerText;
 
        td7.innerHTML = subjectString;
        td8.innerHTML = GetElem('_Datacomm_note').innerText;
 
        // Add the table as the first item in the email body
        var mailBody = document.frames[i].document.body;
 
        if(mailBody.firstChild)
            mailBody.insertBefore(emailDetails,mailBody.firstChild);
        else
            mailBody.appendChild(emailDetails);
 
        // Set the focus on the email and
        // send it to the printer
        document.frames[i].focus();
        document.frames[i].print();
 
        // Get rid of the email details table
        mailBody.removeChild(mailBody.childNodes[0]);
        break;
    }
}}
</script>

Next, add the following as a Create script for one of the fields on that screen (I used comm_status).

var sentString = CRM.GetContextInfo('Communication','comm_to');
 
if(sentString.length > 100)
{
    sentString = CRM.GetTrans('Email','massemailrecipientstitle')
}
 
var translationsString = '<scrip'+'t>var recipientString="';
translationsString+= CRM.GetTrans('Colnames','comm_to') + '";';
translationsString+= 'var fromString="'+CRM.GetTrans('Colnames','EmailFrom')+'";';
translationsString+= 'var subjectString="'+CRM.GetTrans('Fileit','EmailSubject')+'";';
translationsString+= 'var sentString="'+CRM.GetTrans('Gencaptions','Sent')+'";';
translationsString+= 'var massMailString="'+sentString + '";';
translationsString+= '</scrip'+'t>'
 
CRM.AddContent(translationsString);

 
You'll now have a new Print button when viewing sent emails from the Communications tab.
The disadvantage of using this method is that the email content doesn't have any details of the email, such as who it's from, or when it was sent. The above script adds these details briefly to the email content
while the document is being sent to the printer, then removes them. This is by no means the only way of doing this. The changes are made client-side; no data is altered.
The above should work fine on v6.2 and v7.0.
 
Update: This script has been amended to support mass emails.
 
Updated again: If you want this to work in v6.1, then just change the Create script to match the old coding standard. Code below:
 

var sentString = eWare.GetContextInfo('Communication','comm_to');
 
if(sentString.length > 100) {
    sentString = eWare.GetTrans('Email','massemailrecipientstitle')
}
var translationsString = '<scrip'+'t>var recipientString="';
translationsString+= eWare.GetTrans('Colnames','comm_to') + '";';
translationsString+= 'var fromString="'+eWare.GetTrans('Colnames','EmailFrom')+'";';
translationsString+= 'var subjectString="'+eWare.GetTrans('Fileit','EmailSubject')+'";';
translationsString+= 'var sentString="'+eWare.GetTrans('Gencaptions','Sent')+'";';
translationsString+= 'var massMailString="'+sentString + '";';
translationsString+= '</scrip'+'t>'
eWare.AddContent(translationsString);

 

Comments
  • Hi Rob,

    thank you very much for this piece of code. It works great for me and helps cause some customers already asked if this is even possible with sage crm.

    One problem occured when I tried to use the print button on sent e-mails which were created as a mass mailing from a group ( linked to a campaign ). IE tells me about script errors. I'll see if I can figure out for myself. If you have any suggestions I'd be glad to hear from you!

  • Hi Sebastian,

    Thanks for the feedback, I've fixed the script error. It'll now print out the recipients of a mass email, unless the list of recipients is greater than 100 chars long. This is an arbitrary number - you probably wouldn't want to try and print out a list of 20,000 email addresses when what you're looking for is just the email body.

  • Rob,

    I installed this on a couple clients with 6.2. Is there something like this for 6.1?

  • Your wish, etc... :)

    I didn't test it on 6.1 (in fact, to say I tested it on any version would be stretching the truth), but it turns out it's pretty easy to get working. I've updated the post with an amended Create script for v6.1.

    - Rob

  • Hi Rob,

    I have a client that has this request, and I've tried implementing this customization as described here (thanks for that!), but whenever I try to click on the print button that is now on the form, I get this error message (both in IE 8 and IE 9):

    "Unable to get value of the property 'firstChild': object is null or undefined"

    I am using SageCRM 7.0, with no other customization of the communications screens. The filed emails I am using to test this have only a single sender and recipient. By prodding with IE developer tools script debugger, it appears that line 63 returns the value 'undefined' for firstElement. Unfortunately for me, my knowledge of javascript in particular is limited, so I don't know what I am looking for to fix this line. Any help would be greatly appreciated!

  • Hi Kevin,

    Looks like I didn't take emails filed from Outlook properly into account - originally I'd only checked using mails from Fckeditor. I've updated the Custom Content script above.

    - Rob

  • Thanks Rob! I just needed to remove the <p> and </p> from the updated script for it to work perfectly now!

  • Excellent! I've removed those tags now as well, they're just an artifact that can appear when using the code highlighter.

  • Hi Rob - this seems like an excellent fix!

    We have got as far as adding the Custom Content and Create Script to the comm_status field as suggested and the Print button is appearing on the emails. However, when you click on Print we get the following Javascript error, any ideas why that might be? (NB: Ive masked the first part of the URI for security reasons)

    Webpage error details

    User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; Tablet PC 2.0; .NET4.0E; MS-RTC LM 8)

    Timestamp: Tue, 12 Jul 2011 09:18:36 UTC

    Message: Object required

    Line: 78

    Char: 9

    Code: 0

    URI: xxx.xxxxxxx.com/.../Do

    Message: Object required

    Line: 78

    Char: 9

    Code: 0

    URI: xxx.xxxxxxx.com/.../Do

    PS im not a Jscript expert!

  • Rob ignore the URL above!

    this was the 'URI' (minus the spaces)

    ht tp :  //  xxx . abc . com/ a b c /eware.dll/Do?SID=212037045331304&Act=363&Mode=1&CLk=T&Key-1=1&Key0=1&Key1=324&Key2=7927&Key6=49363&Comm_CommunicationId=49363&HiddenRowCount=3&NextID=49269&GridID=228

  • Hi James,

    I've had a look at this with a copy of v7.0e, and the error seems to refer to line 63 in the Create script. That's the part where it tries to read the email subject.

    Can you tell me what patch and version you're on so that I can take a closer look at this please?

    Thanks,

    Rob

  • Hi Rob,

    I got the same problem as James at line 63 td8.innerHTML = GetElem('_Datacomm_note').innerText;.

    Have you solved this issue yet? If you did, please tell me how to fix it.

    I use IE9 & Sage CRM version 7.1 with no patch.

    Thank you,

    Ek

  • Hi Rob,

    I found out that in my Sage version. The email page doesn't have _Datacomm_note field. The email body renders as iframe as below.

    <IFRAME style="WIDTH: 100%; HEIGHT: 200px" src="/crm/eware.dll/Do?SID=78312058629131&Act=373&Mode=1&CLk=&Key-1=1&Key0=1&Key1=2&Key6=8">

    <HTML><HEAD>

    <META content="text/html; charset=UTF-8" http-equiv=Content-Type>

    <META content=-1 http-equiv=Expires>

    <META content=no-cache http-equiv=Cache-Control></HEAD>

    <BODY>

    <P>Test Sage Email</P></BODY></HTML>

    </IFRAME>

    So the script can not fine _Datacomm_note DOM element.

    Ek

  • In 7.2 they have changed some field names:

    Per example "_Datacomm_note" becomes "_HIDDENcomm_subject", used like "td8.innerHTML = GetElem('_HIDDENcomm_subject').value"

    You can find the outer fieldnames in the source view of the email site.