Send an email with a workable link from NewForm.aspx when there is not yet an ID available

In my last post, How do I send an email in JavaScript? I described how to send an email in JavaScript, but what was left unanswered was how do we send an email with a workable link from NewForm.aspx when there is not yet an ID available?

What I have done is create a text field in our Routing and Staffing list called OpenGuid.  Hide the field using JavaScript – NOT by setting the field to Hidden in the content type because we want it to be available in the form, just not visible to the user.

During the PreSaveAction event (after we make sure that this is the NewForm so that it never changes on us later) we populate OpenGuid using the createGuid function is described in How do I show a user with presence with code?.  That OpenGuid value will be inserted into the link’s query string as the ?open= parameter.


"use strict";
function PreSaveAction() {
    if (window.location.href.toLowerCase().indexOf("newform.aspx") > -1) {
        // Make sure that the OpenGuid is assigned so that the initial email can go out
        $("[title='OpenGuid']").val(createGuid());
        
        MyORG.Link = "https://intelshare.intelink.gov/sites/yourcollection/apps/rs/Pages/RoutingStaffingHome.aspx?open=" + $("[title='OpenGuid']").val();
        MyORG.Body = "*****View in HTML*****<br /><br /><br />" + 
                    "A new Routing and Staffing item, \"" + $("[title='Subject Required Field']").val() + "\" is available for review and approval. " +
                    "<br /><br /><a href='" + MyORG.Link + "'>Click here to go to the Routing item</a>";
        if (!sendNotification(MyORG.From, MyORG.To, MyORG.CC, MyORG.BCC, MyORG.Body, MyORG.Subject, true)) {
            alert("Error Sending Mail!  Please notify the Requirement Owner(s) that this item is waiting for them.");
        }
    }
}

Now create a file to inject the code depicted below into your list view or in my case, a page.

The document.ready function looks for an ?open= parameter and if it finds one, it then calls the OpenRoutingItem function which does a quick, targeted REST call to find the ID of the item of interest.

OpenRoutingItem in turn calls the OpenItem function and passes the ID so that the item of interest can be opened in a modal dialog. Take note that there is a commented line in OpenItem that was my first attempt and for the callback I passed SP.UI.ModalDialog.RefreshPage(dialogResult) which I learned the hard way causes the popup to reopen every time it’s closed! As you can see, my second attempt directly sets window.location.href to prevent the undesirable loop.


"use strict";
$(document).ready(function() {
    var openGuid = QueryParameterByName("open");
    if (openGuid != null && openGuid != "")
        OpenRoutingItem(openGuid);
});

function OpenRoutingItem(openGuid) {
    $.ajax({
        url: "/sites/yourcollection/apps/rs/_api/web/lists/getByTitle('Routing_Staffing')/items/" +
             "?$filter=OpenGuid eq '" + openGuid + "'" +
             "&$select=ID",
        type: "GET",
        async: false,
        contentType: "application/json;odata=verbose",
        headers: {"accept": "application/json;odata=verbose"},
        success: function (data) {
            //$("#restResponse").append(JSON.stringify(data));
            try {
                $.each(data.d.results, function (i, item){
                    openItem(item.ID);
                });
            }
            catch(err) {console.log("loadItemArrays Inner: " + JSON.stringify(err))}
        },
        error: function (err) {console.log("loadItemArrays Outer: " + JSON.stringify(err))}
    });
}

function openItem(id) {
    var addressTarget = "/sites/yourcollection/apps/rs/lists/Routing_Staffing/DispForm.aspx?ID=" + id;
    var addressCallback = "https://intelshare.intelink.gov/sites/yourcollection/apps/rs/Pages/RoutingStaffingHome.aspx";
    //OpenPopUpPage(address, function(dialogResult){SP.UI.ModalDialog.RefreshPage(dialogResult)}, 1360, 1300);
    OpenPopUpPage(address, function(dialogResult){window.location.href = addressCallback}, 1360, 1300);
}

Finally, a word of caution: The PreSaveAction event fires BEFORE SharePoint’s field validations. This means that if you have a required field and the user left it empty, PreSaveAction will fire, the email will go out, field validations will fire, the save is refused, the user fixes his oversight, saves again and then another email goes out. There are two ways around this: 1) Set a global variable so that if PreSaveAction gets fired more than once, the email will check for the flag before going out again, or 2) do your own field validations in PreSaveAction before the email is ever sent.

Advertisements

Leave a Reply

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s