This example show a training application list with multi level approval and email alerts – all handled within one list and powered by DFFS.
The requester fill in the form by selecting training or conference from a autocomplete lookup (DFFS Plugin) in another list of training activities and conferences (screenshot at the bottom of this article).
When selected, the script pulls in the event name, start and end date, cost and number of hours.
When the “Program” is selected from another autocomplete lookup, the program name and the manager for this program is pulled in from another list (screenshot at the bottom of this article).
Use this as a guide to make your own customized approval workflow in DFFS, and post any questions of feedback in the forum.
The training application list has these fields:
The status field that controls the workflow has these options:
- Draft
- Awaiting approval by manager
- Rejected by manager
- Awaiting approval by finance
- Rejected by finance
- Fully approved
In the email messages in this example the “manager”, “finance” and the end user are all the same person.
Please let me know if you are missing some steps, or you need some more details.
NewForm
Tabs
Rules
Custom JS
// Autocomplete on training / conference spjs.ac.textField({ "applyTo":"Title", "helpText":"Type to search open training and conferences", "loadText":"", "listGuid":"Conference_Training", "listBaseUrl":"/DFFS/DFFS_Demo", "showField":"Title", "searchFields":["Title"], "filterCAML":"", "useREST":true, "filterREST":"Status eq 'Open'", "optionDetailFields":["StartDate","EndDate","NumberOfHours","Cost"], "optionDetailPrefix":["Start: ","End: ","Number of hours: ","Cost ($): "], "enforceUniqueValues":true, "rowLimit":15, "listOptionsOnFocus":false, "minLengthBeforeSearch":3, "reValidateOnLoad":false, "allowAddNew":false, "isLookupInSelf":false, "addNewAdditionalFields":[], "multiselect":false, "multiselectSeparator":"; ", "orderBy":[], "setFields":[ { "fromFIN":"StartDate", "toFIN":"StartDate", "parseFunction":"parseDateFunc" }, { "fromFIN":"EndDate", "toFIN":"EndDate", "parseFunction":"parseDateFunc" }, { "fromFIN":"Cost", "toFIN":"Cost" }, { "fromFIN":"NumberOfHours", "toFIN":"NumberOfHours" } ], "debug":false }); function parseDateFunc(a){ // Set the desired format in the variable "f" var f = "MM/dd/yyyy hh:mm" , d = new Date(a); f = f.replace("MM",(d.getMonth()+1) < 10 ? "0"+(d.getMonth()+1) : (d.getMonth()+1)); f = f.replace("dd",d.getDate() < 10 ? "0"+d.getDate() : d.getDate()); f = f.replace("yyyy",d.getFullYear()); f = f.replace("yy",d.getFullYear().toString().substring(2)); f = f.replace("hh",d.getHours() < 10 ? "0"+d.getHours() : d.getHours()); f = f.replace("mm",d.getMinutes() < 10 ? "0"+d.getMinutes() : d.getMinutes()); return f.split(/ |:/); } // Autocomplete on program spjs.ac.textField({ "applyTo":"Program", "helpText":"Type to search programs", "loadText":"", "listGuid":"Programs", "listBaseUrl":"/DFFS/DFFS_Demo", "showField":"Title", "searchFields":["Title"], "filterCAML":"", "useREST":true, "filterREST":"Status eq 'Open'", "optionDetailFields":["Manager/Title"], "optionDetailPrefix":["Manager: "], "enforceUniqueValues":true, "rowLimit":15, "listOptionsOnFocus":false, "minLengthBeforeSearch":3, "reValidateOnLoad":false, "allowAddNew":false, "isLookupInSelf":false, "addNewAdditionalFields":[], "multiselect":false, "multiselectSeparator":"; ", "orderBy":[], "setFields":[ { "fromFIN":"Manager/Name", "toFIN":"Manager", "parseFunction":"" } ], "debug":false }); function showApprovalStatus(){ var b = [], label, labelColor, status, spjsStatusArr = [ {"label":"Draft","icon":"①","color":"#107c10"}, {"label":"Awaiting approval by manager","icon":"②","color":"#107c10"}, {"label":"Rejected by manager","icon":"③","color":"#e81123"}, {"label":"Awaiting approval by finance","icon":"④","color":"#107c10"}, {"label":"Rejected by finance","icon":"⑤","color":"#e81123"}, {"label":"Fully approved","icon":"⑥","color":"#107c10"} ]; status = getFieldValue("Status"); jQuery.each(spjsStatusArr,function(i,c){ b.push("<div title='"+c.label+"' class='statusBannerIcon'"); if(status === c.label){ b.push(" style='color:"+c.color+"'"); label = c.label; currStatusIndex = i; labelColor = c.color; } b.push("'>"+c.icon+"</div>"); }); jQuery(".approvalWfStatus").html(b.join("")); jQuery(".approvalWfLabel").html("<span style='color:"+labelColor+"'>Current status: "+label+"</span>"); } setTimeout(function(){ showApprovalStatus(); },500);
Custom CSS
.ms-formlabel{ width:250px; } .statusBannerIcon{ display:inline-block; font-size:35px; margin:5px; color:#cccccc; } .approvalWfLabel{ font-size:18px; font-weight:bold; border-bottom:1px silver solid; padding:0 0 10px 5px; } .customHeading{ background-color: #1B619B; color: #EFF2F6; font-size:16px; padding:5px 10px; }
DispForm
Tabs
Custom JS
function showApprovalStatus(){ var b = [], label, labelColor, status, spjsStatusArr = [ {"label":"Draft","icon":"①","color":"#107c10"}, {"label":"Awaiting approval by manager","icon":"②","color":"#107c10"}, {"label":"Rejected by manager","icon":"③","color":"#e81123"}, {"label":"Awaiting approval by finance","icon":"④","color":"#107c10"}, {"label":"Rejected by finance","icon":"⑤","color":"#e81123"}, {"label":"Fully approved","icon":"⑥","color":"#107c10"} ]; status = getFieldValue("Status"); jQuery.each(spjsStatusArr,function(i,c){ b.push("<div title='"+c.label+"' class='statusBannerIcon'"); if(status === c.label){ b.push(" style='color:"+c.color+"'"); label = c.label; currStatusIndex = i; labelColor = c.color; } b.push("'>"+c.icon+"</div>"); }); jQuery(".approvalWfStatus").html(b.join("")); jQuery(".approvalWfLabel").html("<span style='color:"+labelColor+"'>Current status: "+label+"</span>"); } setTimeout(function(){ showApprovalStatus(); },500);
Custom CSS
.ms-formlabel{ width:250px; } .statusBannerIcon{ display:inline-block; font-size:35px; margin:5px; color:#cccccc; } .approvalWfLabel{ font-size:18px; font-weight:bold; border-bottom:1px silver solid; padding:0 0 10px 5px; } .customHeading{ background-color: #1B619B; color: #EFF2F6; font-size:16px; padding:5px 10px; }
EditForm
The first step in EditForm is “Approval by manager”, then “Approval by finance”. Both steps can either be approved or rejected.
If the manager approves, an email is sent to “finance”.
If the manager rejects, an email is sent to the author and the status set to “Rejected by manager”.
If it is approved, the finance representative follows the link in the email to this form:
Finance can reject or approve. If it is rejected, this email will be sent to the author of the request form:
If it is approved, this email is sent:
Tabs
Rules
Please note that the checkbox “Use custom list with workflow to send E-Mails” is checked. This is necessary to be able to postpone the sending of the email “eventFollowUp” that has this “Send date”:
{EndDate}+14
If you use the REST email option (by not checking this checkbox) your email will be sent immediately.
Please refer the user installation manual for details on the DFFS_Email list and workflow.
Custom JS
function showApprovalStatus(){ var b = [], label, labelColor, status, spjsStatusArr = [ {"label":"Draft","icon":"①","color":"#107c10"}, {"label":"Awaiting approval by manager","icon":"②","color":"#107c10"}, {"label":"Rejected by manager","icon":"③","color":"#e81123"}, {"label":"Awaiting approval by finance","icon":"④","color":"#107c10"}, {"label":"Rejected by finance","icon":"⑤","color":"#e81123"}, {"label":"Fully approved","icon":"⑥","color":"#107c10"} ]; status = getFieldValue("Status"); jQuery.each(spjsStatusArr,function(i,c){ b.push("<div title='"+c.label+"' class='statusBannerIcon'"); if(status === c.label){ b.push(" style='color:"+c.color+"'"); label = c.label; currStatusIndex = i; labelColor = c.color; } b.push("'>"+c.icon+"</div>"); }); jQuery(".approvalWfStatus").html(b.join("")); jQuery(".approvalWfLabel").html("<span style='color:"+labelColor+"'>Current status: "+label+"</span>"); } setTimeout(function(){ showApprovalStatus(); },500);
Custom CSS
.ms-formlabel{ width:250px; } .statusBannerIcon{ display:inline-block; font-size:35px; margin:5px; color:#cccccc; } .approvalWfLabel{ font-size:18px; font-weight:bold; border-bottom:1px silver solid; padding:0 0 10px 5px; } .customHeading{ background-color: #1B619B; color: #EFF2F6; font-size:16px; padding:5px 10px; }
Lookup lists for the Autocomplete plugin
The datasource for “Training/Conference” and “Program” is is two separate lists in the same site.