11

I would like to add a link directly to a start workflow page in a column so that users don't have to go through several clicks to start a workflow. The link needs to change based on the item ID for each item. I know how to do this by inserting javascript into a Script Editor or Content Editor web part but I'm not sure how to insert it into a column. This is the script I have been using for a button that starts a workflow.

<button     onclick="dialogfunction('/sites/MainSite/Subsite/_layouts/15/IniWrkflIP.aspx?List={bc68b081-8590-477e-aff7-55b2b64ad3fb}&TemplateID={F704E402-6DA6-4C75-AA97-FBC6F2BEA69F}&ID='); return false;" class="btn">Collect Signatures</button>
<script type="text/javascript">
JSRequest.EnsureSetup();
var idValue = JSRequest.QueryString["ID"];
function dialogfunction(pageUrl) {

    var options = { url: pageUrl + idValue, width: 800, height: 600 };

    SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);

}
</script>

I looked at using a calculated column but I don't think that would work since the item ID isn't in another column.

5

Note:

in June 2017, Microsoft disabled the use of JavaScript in a Calculated Column

That means given answers may not apply for newer SharePoint versions

For long explanation and work arounds see:
June 13th 2017 Microsoft blocked handling HTML markup in SharePoint calculated fields - how to get the same functionality back


Original answer:

Check out http://www.viewmaster365.com/#/How and http://www.viewmaster365.com/#/Create/ActionDelete

It step by step explains how to execute JavaScript from a Calculated Column.

The ID for an item is available on the Table Row, because a Calculated Formula is displayed inside that TR structure;
all you have to do is:

var TR=this;while(TR.tagName!='TR'){TR=TR.parentNode}

to get to that TR and its iid attribute

var ID=TR.iid.split(',')[1]

Note that you can get the List GUID from the current context.

var ctx = new SP.ClientContext.get_current();
var listGuid = SP.ListOperation.Selection.getSelectedList();

The Workflow GUID you have to do some more JavaScript digging for, but hardcoding is the easiest option.

Please post the code you come up or have problems with; it is on my (long) list of todos to write an Example for this on the ViewMaster365 site

Client Side Rendering

Ofcourse on SharePoint 2013 you can also do this with CSR. But you have to add an extra JS file and JSlinks on every View you want it applied.

In a Calculated Column it just works.

Update #1

This Formula in a Calculated Column set to datatype=Number will get you started;
I haven't tested if the URL from your original post actually starts a workflow.

="<button style=""cursor:pointer;"" onclick=""{"
&"event.preventDefault();"
&"var clientContext=new SP.ClientContext.get_current();"
&"var listGUID=SP.ListOperation.Selection.getSelectedList();"
&"var workflowGUID='{F704E402-6DA6-4C75-AA97-FBC6F2BEA69F}';"
&"var TR=this;while(TR.tagName!='TR'){TR=TR.parentNode}" 
&"var url='https://mysharepointurl/_layouts/15/IniWrkflIP.aspx?List='+listGUID;" 
&"url += '&TemplateID='+workflowGUID;" 
&"url += '&ID='+TR.id.split(',')[1];" 
&"alert(url);"
&"SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog',{url:url});"
&"}"">Collect Signature</button>"

Update #2

Took me a day to wade trhu all the blogs with partial (and bloated) answers out there...

Yes the Workflow GUID changes every time you make a change. So you have to query the Workflow Subscriptions on the List, a matching Name gives you the ID (but you need the 'Subscription' to start a workflow, Not the GUID)
Alas the library sp.workflowservices.js needed for this is not available on the List view page; so some extra scripting is required to load it if needed (only for the first button you click)

This immediatly starts the Workflow, no pages in between

Copy/Paste in a Calculated Column, set the datatype to Number

="<button style=""cursor:pointer;"" onclick=""{"
&"event.preventDefault();"
&"function startWorkflow(itemID, wfName) {"
&"  function __startWorkflow() {"
&"      var ctx = new SP.ClientContext.get_current(),"
&"          wfsManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx,ctx.get_web()),"
&"          wfSubs = wfsManager.getWorkflowSubscriptionService().enumerateSubscriptionsByList(_spPageContextInfo.pageListId);"
&"      ctx.load(wfSubs);"
&"      ctx.executeQueryAsync(function () {"
&"          wfsEnum = wfSubs.getEnumerator();"
&"          while (wfsEnum.moveNext()) {"
&"              var wfSub = wfsEnum.get_current();"
&"              if (wfSub.get_name() === wfName) {"
&"                  wfsManager.getWorkflowInstanceService().startWorkflowOnListItem(wfSub,itemID,new Object());"
&"                  SP.UI.Notify.addNotification('Init Workflow: '+wfName+' on item: '+itemID, false);"
&"              }}});}"
&"  if (!SP.WorkflowServices) {"
&"      var script = document.createElement('script');"
&"      script.src = '/_layouts/15/sp.workflowservices.js';"
&"      script.onload = __startWorkflow;"
&"      document.head.appendChild(script);"
&"  } else {__startWorkflow();}"
&"}"
&"var TR=this;while(TR.tagName!='TR'){TR=TR.parentNode}"    
&"startWorkflow(TR.id.split(',')[1] , 'YOUR_WORKFLOW_TITLE_GOES_HERE');"
&"}"">Collect Signature</button>"

Should work on any site, no need to change URLs, all you need to change is: YOUR_WORKFLOW_TITLE_GOES_HERE
There is no error checking at all, I debugged with a simple Send-Email workflow.

Fun with Calculated Columns

You can apply all your Calculated Formula skills; since Formula contents are beign evaluated on every Item change you are essentially creating a kind of self-modyfing JavaScript code.

&"startWorkflow(TR.id.split(',')[1] , 'YOUR_WORKFLOW_TITLE_GOES_HERE');"

Change it to select different Workflows based on a (task) Status:

&"startWorkflow(TR.id.split(',')[1] , '"
  &IF(Status="Approved","MyUnApproveWF","CollectSignatureWF")
&"');"

ICC IWF

  • Actually, using CSR you could define the column you want the link to appear in as a site column, then attach the JS file to the column using the SPField's JSLink property, then all you have to do is add the column where you want it and the script will follow along. No more difficult than adding a calculated column wherever you want that functionality. – Dylan Cristy Jul 29 '15 at 16:06
  • True, but updating that SPFIELD schema is even more complex coding, or is settable within the UI ? – Danny '365CSI' Engelman Jul 29 '15 at 16:27
  • You are correct there, you would have to use Powershell or some other method to set the JSLink property on an SPField object, AFAIK it is not exposed in the UI. – Dylan Cristy Jul 29 '15 at 18:18
  • Thanks a lot! The code worked after I updated my specific site URL, added [1] after TR.id.split(',') and added & in front of TemplateID and ID= – James11 Jul 29 '15 at 18:35
  • cool, I have fixed the typos. Note the pros and cons of this method; CSR version can be the same JS/HTML code stuffed into an existing Column (and 20 lines more boilerplate code to get it working) – Danny '365CSI' Engelman Jul 29 '15 at 18:48
2

This should be what your looking for: 4 Clicks or 1?

  • I looked at that but I can't use SharePoint designer so I need a solution that doesn't involve creating a custom workflow. – James11 Jul 29 '15 at 15:50
1

Using a calculated column was the answer. Based on this article http://www.concurrency.com/blog/sharepoint-hyperlink-edit-column/ I added this formula and selected number for the data type and it worked!

="https://mysharepointurl/_layouts/15/IniWrkflIP.aspx?List={bc68b081-8590-477e-aff7-55b2b64ad3fb}&TemplateID={F704E402-6DA6-4C75-AA97-FBC6F2BEA69F}&ID="&ID&"'>Collect Signatures"

  • No, ID will most often be 0, plenty written about this – Danny '365CSI' Engelman Jul 29 '15 at 16:20
  • Ok, it is inserting the correct ID number for me though. – James11 Jul 29 '15 at 16:28
  • Add a new item ... ID will be 0 because it gets the ID from the database after your previous Calculated Column Formula is evaluated – Danny '365CSI' Engelman Jul 29 '15 at 16:32
  • Which the blog you reference also states: (The ID field will not be there until the list item is created and the update will work only after an update has happened on the list item. The other option is to use SharePoint Designer to copy the ID field to a text field and use that text field in the formula above.) – Danny '365CSI' Engelman Jul 29 '15 at 16:43
  • Oh yeah, you're right. So with your solution I'm unclear about how I would go about adding both html and javascript in a calculated column since script tags aren't allowed. Or can I do it with just javascript? – James11 Jul 29 '15 at 17:09
1

You need to start a workflow using JSOM on button click or u can redirect to OOTB approver page using column rendering using JS link. If you need help in code please let me know.

0

Sorry to re-open an old thread.

I'm trying to get this to work but I find two problems.

  1. The workflow only launches if you double-click the button. A single click displays the Notification but does not start the workflow.
  2. Ideally, this should also trigger a page refresh at completion to show any changes to the list made by the workflow.

I am using Update #2 with a simple SharePoint 2013 workflow.

  • 1
    You are requested not to ask questions in answers section. You can raise new thread, or add comments as per site guidelines. You can also include reference of the relevant question if you want – Gaurravs May 9 '16 at 10:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.