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.