Delete a Workflow on the Host Web from the App Web

below is some sample code to delete a workflow on the host web from your app web. This would be useful in the event you want your App to remove a workflow that you have deployed to the host web.

NOTE: you must include a reference to “/_layouts/15/SP.WorkflowServices.js”

this file can be downloaded here

   1: var deleteWorkflow = function (workflowName) {

   2:  

   3:     //Using the App Web as the client context

   4:     clientContext = new SP.ClientContext.get_current();

   5:  

   6:     //Get the host web URL from the query string params

   7:     //I have a function getHostWebUrl() - which is not included.

   8:     //http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

   9:     var hostWebUrl = getHostWebUrl();

  10:     

  11:     //Using the hostWebContext as an AppContextSite

  12:     hostWebContext = new SP.AppContextSite(clientContext, hostWebUrl);

  13:  

  14:     //Get the Workflow Services Manager for the Host web, NOTE: you initialize it with the clientContext & the hostWebContext Web)

  15:     var hostWebWorkflowServicesManager = new SP.WorkflowServices.WorkflowServicesManager.newObject(clientContext, hostWebContext.get_web());

  16:     var hostWebWorkflowDeploymentService = hostWebWorkflowServicesManager.getWorkflowDeploymentService();

  17:     var hostWebDefinitionsCollection = hostWebWorkflowDeploymentService.enumerateDefinitions(false);

  18:  

  19:     //load all the workflow definitions from the host web 

  20:     clientContext.load(hostWebDefinitionsCollection);

  21:     clientContext.executeQueryAsync(function () {

  22:  

  23:         //get the enumerator for all the workflow definitions

  24:         var workflowDefinitions = hostWebDefinitionsCollection.getEnumerator();

  25:         while (workflowDefinitions.moveNext()) {

  26:             

  27:             //set the current definition to a variable

  28:             var workflowDefinition = workflowDefinitions.get_current();

  29:             

  30:             //uncomment to see all the workflows that it finds

  31:             //console.log("Found Workflow : " + workflowDefinition.get_displayName());

  32:             

  33:             //looking for a match on the name of the workflow

  34:             if (workflowDefinition.get_displayName() === workflowName) {

  35:                 //using the host web workflow deployment service to delete the workflow definition

  36:                 

  37:                 hostWebWorkflowDeploymentService.deleteDefinition(workflowDefinition.get_id());

  38:                 //this comment will just display what workflow WILL BE deleted 

  39:                 console.log("Deleted workflow : " + workflowName + ", " + workflowDefinition.get_id().toString());

  40:                 

  41:                 //if more than one workflow with the same name is found it will delete all of them

  42:                 //the delete will get queued up and executed by the .executeQueryAsync

  43:                 //if you don't want that then you have to break out of the while loop

  44:             }

  45:         }

  46:         //this query will execute the delete action

  47:         clientContext.executeQueryAsync(function () {

  48:             //Successfully deleted   the workflow

  49:         }, function (sender, args) {

  50:             console.log("Unable to delete workflow : " + workflowName);

  51:             console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  52:         });

  53:     }, function (sender, args) {

  54:         console.log("Failed to load workflows");

  55:         console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  56:     });

  57: };

Provision a Workflow to the Host Web from the App Web

below is some sample code to provision a workflow on the host web from your app web. This sample code is in one block for demo purposes. It makes 4 asynchronous calls to SharePoint to complete successfully.

In the event you’d want to define in your App a workflow that would run on a list in the host web this is the code you would use to deploy (move it from App to Host) and attach it to a list in the host web.

NOTE: you must include a reference to “/_layouts/15/SP.WorkflowServices.js”

this file can be downloaded here

   1: var attachWorkflow = function(workflowName, workflowListName, workflowHistoryListName, workflowTasksListName) {

   2:  

   3:      //Using the App Web as the client context

   4:      clientContext = new SP.ClientContext.get_current();

   5:  

   6:      //Get the host web URL from the query string params

   7:      //I have a function getHostWebUrl() - which is not included.

   8:      //http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

   9:      var hostWebUrl = getHostWebUrl();

  10:      

  11:      //Using the hostWebContext as an AppContextSite

  12:      hostWebContext = new SP.AppContextSite(clientContext, hostWebUrl);

  13:      

  14:      //Get the Workflow Services Manager for the Host web, NOTE: you initialize it with the clientContext & the hostWebContext Web)

  15:      var hostWebWorkflowServicesManager = new SP.WorkflowServices.WorkflowServicesManager.newObject(clientContext, hostWebContext.get_web());

  16:      var hostWebWorkflowDeploymentService = hostWebWorkflowServicesManager.getWorkflowDeploymentService();

  17:      var hostWebSubscriptionService = hostWebWorkflowServicesManager.getWorkflowSubscriptionService();

  18:  

  19:      //Get the Workflow Services Manager for the App web 

  20:      var workflowServicesManager = new SP.WorkflowServices.WorkflowServicesManager(clientContext, clientContext.get_web());

  21:      var workflowDeploymentService = workflowServicesManager.getWorkflowDeploymentService();

  22:      var workflowDeploymentServiceDefinitions = workflowDeploymentService.enumerateDefinitions(false);

  23:  

  24:      //Load all the Workflow Definitions from the App web

  25:      clientContext.load(workflowDeploymentServiceDefinitions);

  26:      clientContext.executeQueryAsync(function () {

  27:  

  28:          //Get the enumerator for all the workflow definitions in the App web

  29:          var workflowDefinitions = workflowDeploymentServiceDefinitions.getEnumerator();

  30:          while (workflowDefinitions.moveNext()) {

  31:  

  32:              //set the current definition to a variable

  33:              var workflowDefinition = workflowDefinitions.get_current();

  34:              //test, trying to locate your workflow in the App web

  35:              if (workflowDefinition.get_displayName() === workflowName) {

  36:  

  37:                  //now grab the xaml definition of the selected workflow

  38:                  var workflowXaml = workflowDefinition.get_xaml();

  39:  

  40:                  //define a new workflow and assign it xaml & name

  41:                  var newWorkflow = new SP.WorkflowServices.WorkflowDefinition.newObject(clientContext, hostWebContext.get_web());

  42:                  newWorkflow.set_xaml(workflowXaml);

  43:                  newWorkflow.set_displayName(workflowName);

  44:                  

  45:                  //using the host webs Workflow Deployment Service, save the workflow.

  46:                  hostWebWorkflowDeploymentService.saveDefinition(newWorkflow);

  47:                  

  48:                  //load the new workflow and initialize the Id

  49:                  clientContext.load(newWorkflow, "Id");

  50:                  //this query will save your workflow to the host web

  51:                  clientContext.executeQueryAsync(function() {

  52:  

  53:                      //publish the workflow on the host web

  54:                      hostWebWorkflowDeploymentService.publishDefinition(newWorkflow.get_id());

  55:                      

  56:                      //getting all the lists that the workflow will attach to

  57:                      //these lists already created on the host web

  58:                      var targetList = hostWebContext.get_web().get_lists().getByTitle(workflowListName);

  59:                      var historyList = hostWebContext.get_web().get_lists().getByTitle(workflowHistoryListName);

  60:                      var tasksList = hostWebContext.get_web().get_lists().getByTitle(workflowTasksListName);

  61:  

  62:                      //loading the lists & initialize the Id

  63:                      clientContext.load(targetList, "Id");

  64:                      clientContext.load(historyList, "Id");

  65:                      clientContext.load(tasksList, "Id");

  66:  

  67:                      //this query will publish the workflow and get the required list id's for the next step

  68:                      clientContext.executeQueryAsync(function() {

  69:  

  70:                              //creating a new workflow subscription

  71:                              var subscription = new SP.WorkflowServices.WorkflowSubscription(clientContext, hostWebContext.get_web());

  72:  

  73:                              //setting some properties of the subscription

  74:                              subscription.set_name(workflowName + "-ItemAdded");

  75:                              subscription.set_enabled(true);

  76:                              subscription.set_definitionId(newWorkflow.get_id().toString());

  77:                              subscription.set_eventSourceId(targetList.get_id());

  78:                              subscription.set_eventTypes(["ItemAdded"]);

  79:  

  80:                              subscription.setProperty("TaskListId", tasksList.get_id().toString());

  81:                              subscription.setProperty("HistoryListId", historyList.get_id().toString());

  82:                              subscription.setProperty("FormData", "");

  83:  

  84:                              //attaching the subscription to the target list 

  85:                              hostWebSubscriptionService.publishSubscriptionForList(subscription, targetList.get_id());

  86:  

  87:                              //this query will execute the creation of the new subscription and adding attaching the subscription to the target list on the host web

  88:                              clientContext.executeQueryAsync(function() {

  89:                                  console.log("Workflow : \"" + workflowName + "\" successfully added to list : \"" + workflowListName + "\"");

  90:                              }, function(sender, args) {

  91:                                  console.log("Workflow : " + workflowName + " not successfully added to list : " + workflowListName);

  92:                                  console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  93:                              });

  94:                          },

  95:                          function(sender, args) {

  96:                              console.log("Failed to get workflow list IDs");

  97:                              console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  98:                          });

  99:  

 100:                  }, function(sender, args) {

 101:                      console.log("Failed to create the workflow definition");

 102:                      console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

 103:                  });

 104:              }

 105:          }

 106:      }, function (sender, args) {

 107:          console.log("Could not find workflow : " + workflowName);

 108:          console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

 109:      });

 110:  };

Deleting a List on the Host Web from the App Web with JavaScript Object Model (JSOM)

Below is some sample code of how to delete a list on the host web from the app web via SharePoint JavaScript object model
 
   1: function DeleteList(listName) {

   2:  

   3:     //Using the App Web as the client context

   4:     clientContext = new SP.ClientContext.get_current();

   5:  

   6:     //Get the host web URL from the query string params

   7:     //I have a function getHostWebUrl() - which is not included.

   8:     //http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

   9:     var hostWebUrl = getHostWebUrl();

  10:     //Using the hostWebContext as an AppContextSite

  11:     hostWebContext = new SP.AppContextSite(clientContext, hostWebUrl);

  12:  

  13:     //get the list using the host web context

  14:     var list = hostWebContext.get_web().get_lists().getByTitle(listName);

  15:     list.deleteObject();

  16:     

  17:     //Always use the context of the app web to do the work or load and executing

  18:     clientContext.executeQueryAsync(function() {

  19:         console.log("Deleted List : \"" + listName + "\"");

  20:     }, function(sender, args) {

  21:         console.log("Failed to delete list : " + listName);

  22:         console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  23:     });

  24:  

  25: }

  26:  

  27: // parameters : List Name

  28: DeleteList("My Test List");

Provisioning a List on the Host Web from the App Web with JavaScript Object Model (JSOM)

Below is some sample code of how to provision a list from the app web via SharePoint JavaScript object model

   1: function CreateList(title, url, templateType, hidden) {

   2:  

   3:     //Using the App Web as the client context

   4:     clientContext = new SP.ClientContext.get_current();

   5:  

   6:     //Get the host web URL from the query string params

   7:     //I have a function getHostWebUrl() - which is not included.

   8:     // Some Ideas Here: http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

   9:     var hostWebUrl = getHostWebUrl();

  10:     //Using the hostWebContext as an AppContextSite

  11:     hostWebContext = new SP.AppContextSite(clientContext, hostWebUrl);

  12:  

  13:     //Create List Code

  14:     var listCreation = new SP.ListCreationInformation();

  15:     listCreation.set_title(title);

  16:     listCreation.set_templateType(templateType);

  17:     listCreation.set_url(url);

  18:  

  19:     //must use the hostWebContext to get the list in that site

  20:     var lists = hostWebContext.get_web().get_lists();

  21:     var list = lists.add(listCreation);

  22:     list.set_hidden(hidden);

  23:     list.set_onQuickLaunch(false);

  24:     list.update();

  25:  

  26:     //Always use the context of the app web to do the work or load and executing

  27:     clientContext.load(list);

  28:     clientContext.executeQueryAsync(function() {

  29:         console.log("Created List : \"" + title + "\"");

  30:     }, function(sender, args) {

  31:         console.log("Failed to create list : " + title);

  32:         console.log("<span style='color:red'>Reason : " + args.get_message() + "</span>");

  33:     });

  34:  

  35: }

  36:  

  37: // parameters : List Name, List Url, Template Type (can be ListTemplateType or Template ID, Hidden)

  38: CreateList("My Test List", "Lists/MyTestList", SP.ListTemplateType.genericList, false);

  39: CreateList("My Test List", "Lists/MyTestList", 171, false);

Content Query Web Part + Calendar = Mad Problems

I recently had to assemble a content query web part (my least favorite thing) pulling data from a Calendar list and experienced hours of pain trying to get it to pull the locations field as well as the start/end time consistently. I share my pain so that other won’t have to endure, and hopefully some tips so that you can skip all the BS and just make a quick web part that should have took about 30 minutes.

I had an extremely painful time working with the Location field for some reason. It would show on ctrl-f5 or the first load of the web part. Then disappear or show intermittently. It was basically unreliable until I used the ID and renamed the fields as described below.

Getting the fields right

Step 1 – Calendar list settings

If you go to the list settings and copy or inspect the link to the Start Time field you’ll see something like this.

/_layouts/15/FldEdit.aspx?List=%7BE84FD6F2%2D11AD%2D443B%2D84A2%2DA6E1B198458D%7D&Field=EventDate

This is good to give you what the field name is but we actually just want the field ID. Next I move up to the parent content type and click “Event”

image

In these columns I copy or inspect Start Time field again and you’ll see this

/_layouts/15/ManageContentTypeField.aspx?ctype=0x010200D536EDB0AB69A047B200ABF60FFE33EF&List=e84fd6f2-11ad-443b-84a2-a6e1b198458d&Field=EventDate&Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

This is what I want – I’ll get the actual field ID. using a url decoder [http://meyerweb.com/eric/tools/dencoder/]

Fid=%7B64cd368d%2D2f95%2D4bfc%2Da1f9%2D8d4324ecb007%7D

Fid={64cd368d-2f95-4bfc-a1f9-8d4324ecb007}

Step 2 – Content Query

Once you’ve exported the content query so we can edit it in notepad, search for CommonViewFields

Add the Start Time field to this property

<property name=”CommonViewFields” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;</property>

Next search for DataColumnRenames, add the following. The EventStartDateTime is what you would use in the xslt to pull this property. You can call it what you like at this point.

<property name=”DataColumnRenames” type=”string”>{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

Below is a snippet of me using the EventStartDateTime in my xslt. I’m assigning it to a variable to i can further manipulate it.

image

Step 3 – Repeat

You can repeat the following steps for a fool proof method of getting the fields you want into your content query web part. If you use the column ID and rename it you should have no issues.

 

Location Field

{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;

Start Time

{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;

End Time

{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;

 

<property name=”CommonViewFields” type=”string”>{288f5f32-8462-4175-8f09-dd7ba29359a9},Text;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},DateTime;{2684f9f2-54be-429f-ba06-76754fc056bf},DateTime;</property>

<property name=”DataColumnRenames” type=”string”>{2684f9f2-54be-429f-ba06-76754fc056bf},EventEndDateTime;{288f5f32-8462-4175-8f09-dd7ba29359a9},EventLocation;{64cd368d-2f95-4bfc-a1f9-8d4324ecb007},EventStartDateTime;</property>

 

Troubleshooting

From this day forward I vowed to always include this debugging template in my ItemStyle.xsl. It will basically just dump the raw data to your screen, so you can see what fields you have

   1: <xsl:template name="DisplayRawData" match="Row[@Style='DisplayRawData']" mode="itemstyle">

   2:   <xsl:for-each select="@*">

   3:     <xsl:value-of select="name()"/>

   4:     <xsl:text> = </xsl:text>

   5:     <xsl:value-of select="."/>

   6:     <br/>

   7:   </xsl:for-each>

   8:   <br/>

   9:   <br/>

  10:   <br/>

  11: </xsl:template>

If you set the Item style: DisplayRawData, you’ll get a dump of the fields and values that are available. In the screen shot below you’ll notice then fields that we’ve renamed and they data

image

Permanently Removing the Recent Node from Quick Launch for SharePoint 2013

Introduction

Yesterday I was tasked to remove the “Recent” node from the quick launch for a customers SharePoint online site. I’ve decided to release the solution in hopes that other people could take advantage of it. The picture below will show you the “Recent” node.

Recent Node

This node was undesired by the user because they wanted to have control over the quick launch navigation. They mentioned that every time they add a new list or library then new items will be added under the “Recent” node. When they go and delete it from the Navigation section in Look & Feel, it will just re-appear when they create a new list or library. Basically they wanted it gone.

Approach

I chose an approach similar to this blog article http://www.jasperoosterveld.com/2013/02/sharepoint-2013-remove-recent-in-quick.html however, I needed it to work on sandbox for o365 and SPO. I also decided to sharpen my JavaScript Client Object model skills and write a small script that will remove the “Recent” node whenever it is created.

I paired this with the jQuery as suggested in the article to hide the “Recent” node. Except I made one modification to it you can see below. I’ve added the id #sideBox to have this only search in the Quick Launch. I explain more about why I remove and hide it in the next section.

this > jQuery(“.ms-core-listMenu-item:contains(‘Recent’)”).parent().hide();

to this > jQuery(“#sideBox .ms-core-listMenu-item:contains(‘Recent’)”).parent().hide(); 

The Solution

The entire solution & the pre-built .wsp can be downloaded from CodePlex – http://rr.codeplex.com

The sandbox solution is composed of two components:

  1. RemoveRecent.js – JavaScript Client Object Model code which removes the “Recent” node from the quick launch if detected on page refresh.
  2. HideRecent.js – jQuery code to hide the “Recent” node

Why remove and hide?

Since the RemoveRecent.js runs client side there is a case where you may see the “Recent” node. For example you just finished creating a new list and the page refresh. The code to remove the node in RemoveRecent.js is called asynchronously. The list or library is removed from the back end but on the client side is not updated. This could be handled with a refresh but that causes a double refresh once you create a new list and there is a delay between the refreshes. I felt that this created a bad user experience. The answer to that was to also hide the node using HideRecent.js

 

Hope this may be useful to some of you out there.

Reuse DataForm Web Part, change ListId to ListName, and scrub GUIDs

Intro

I know there are quite a few posts out there on this, but i’m writing this here for myself as a rollup of the information and highlighting what needs to be done in order for this to work perfectly.

For those not familiar with the issue let me re-hash it quickly. When you create a Data View Web Part (DVWP) or New/Display/Edit form in SharePoint Designer you’ll be directly binding those web parts to your list. If you look at the code you’ll see the list GUIDs below.

<WebPartPages:DataFormWebPart runat=”server” EnableOriginalValue=”False” DisplayName=”My Links” ViewFlag=”8″ ViewContentTypeId=”” Default=”FALSE” ListUrl=”” ListDisplayName=”” ListName=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” ListId=”62f19be4-6465-4293-b580-36c49ec8f35b” PageType=”PAGE_NEWFORM”………………………

Copying this to another site collection or environment won’t work unless your lists have exactly the same GUID. Basically these web parts are non-reusable. Well there is a way to move them.

Two articles that I ALWAYS refer too – but they don’t do it partially or not as cleanly as I want.

http://sympmarc.com/2008/12/16/replacing-listids-with-listnames-in-data-view-web-parts/

http://blogs.msdn.com/b/joshuag/archive/2008/11/10/easily-making-the-data-form-web-part-reusable.aspx

There are a few places you need to rename the ListId from in order for this to work.

  1. The <DataFormWebPart>
  2. The <DataSources>
  3. The <ParameterBindings>
  4. The <XSL:StyleSheet><Params>

Step 1 – DataFormWebPart

This is an original:

<WebPartPages:DataFormWebPart runat=”server” EnableOriginalValue=”False” DisplayName=”My Links” ViewFlag=”8″ ViewContentTypeId=””
Default=”FALSE” ListUrl=”” ListDisplayName=”” ListName=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” ListId=”62f19be4-6465-4293-b580-36c49ec8f35b”
    PageType=”PAGE_NEWFORM” PageSize=”-1″ UseSQLDataSourcePaging=”True” DataSourceID=”” ShowWithSampleData=”False” AsyncRefresh=”False”
ManualRefresh=”False” AutoRefresh=”False” AutoRefreshInterval=”60″ NoDefaultStyle=”TRUE” InitialAsyncDataFetch=”False” Title=”My Links”
FrameType=”None” SuppressWebPartChrome=”False” Description=”” IsIncluded=”True” PartOrder=”2″ FrameState=”Normal” AllowRemove=”True”
AllowZoneChange=”True” AllowMinimize=”True” AllowConnect=”True” AllowEdit=”True” AllowHide=”True” IsVisible=”True” DetailLink=”” HelpLink=””
HelpMode=”Modeless” Dir=”Default” PartImageSmall=”” MissingAssembly=”Cannot import this Web Part.” PartImageLarge=”” IsIncludedFilter=””
ExportControlledProperties=”True” ConnectionID=”00000000-0000-0000-0000-000000000000″ ID=”g_b881fc6c_50db_4108_825a_a5b252da499d”
ChromeType=”None” ExportMode=”All” __MarkupType=”vsattributemarkup” __WebPartId=”{B881FC6C-50DB-4108-825A-A5B252DA499D}” __AllowXSLTEditing=”true”
WebPart=”true” Height=”” Width=””>

Remove ListId and ListName completely.

Step 2 – Data Sources

These are the original data sources. I ALWAYS remove the one’s I’m not using. If your DVWP or List Form does not use the delete then remove it. In my current working example I’m working with an add new item form so all I need it the <InsertParameter>

<DataSources>
<SharePoint:SPDataSource runat=”server” DataSourceMode=”ListItem” SelectCommand=”&lt;View&gt;&lt;Query&gt;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name=&quot;ContentType&quot;/&gt;&lt;Value Type=&quot;Text&quot;&gt;Link&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;/View&gt;” UseInternalName=”True” UseServerDataFormat=”True” ID=”My_x0020_Links2″>
<SelectParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
<WebPartPages:DataFormParameter ParameterKey=”MaximumRows” PropertyName=”ParameterValues” DefaultValue=”10″ Name=”MaximumRows”/>
</SelectParameters>
<UpdateParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</UpdateParameters>
<InsertParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</InsertParameters>
<DeleteParameters>
<WebPartPages:DataFormParameter ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″ Name=”ListItemId”/>
<WebPartPages:DataFormParameter ParameterKey=”ListID” PropertyName=”ParameterValues” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}” Name=”ListID”/>
</DeleteParameters>
</SharePoint:SPDataSource>
</DataSources>

My updated XML below. I’ve changed the DataFormParameter, Name & ParameterKey to “ListName” and in DefaultValue I’m using the “Links” as the internal name of my list. I’m also specifying the an asp:Parameter of the “WebUrl” so that this can connect to the proper list. This {sitecollectionroot} was pulled from this article – http://blogs.msdn.com/b/joshuag/archive/2008/11/10/easily-making-the-data-form-web-part-reusable.aspx

<DataSources>
<SharePoint:SPDataSource runat=”server” DataSourceMode=”ListItem” UseInternalName=”true” UseServerDataFormat=”True” selectcommand=”&lt;View&gt;&lt;Query&gt;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name=&quot;ContentType&quot;/&gt;&lt;Value Type=&quot;Text&quot;&gt;Link&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&lt;/Query&gt;&lt;/View&gt;” id=”My_x0020_Links1″>
<InsertParameters>
<WebPartPages:DataFormParameter Name=”ListItemId” ParameterKey=”ListItemId” PropertyName=”ParameterValues” DefaultValue=”0″/>
<WebPartPages:DataFormParameter Name=”ListName” ParameterKey=”ListName” PropertyName=”ParameterValues” DefaultValue=”Links”/>
<asp:Parameter runat=”server” Name=”WebUrl” DefaultValue=”{sitecollectionroot}” />
        </InsertParameters>
</SharePoint:SPDataSource>
</DataSources>

Step 3 – Parameter Bindings

Your ParameterBindings should normally look similar to this. I just completely remove the ListId line as it’s not needed in MY xslt

<ParameterBindings>
<ParameterBinding Name=”dvt_apos” Location=”Postback;Connection”/>
<ParameterBinding Name=”ManualRefresh” Location=”WPProperty[ManualRefresh]”/>
<ParameterBinding Name=”UserID” Location=”CAMLVariable” DefaultValue=”CurrentUserName”/>
<ParameterBinding Name=”Today” Location=”CAMLVariable” DefaultValue=”CurrentDate”/>
<ParameterBinding Name=”ListItemId” Location=”QueryString(ID)” DefaultValue=”0″/>
    <ParameterBinding Name=”ListID” Location=”None” DefaultValue=”{62F19BE4-6465-4293-B580-36C49EC8F35B}”/>
<ParameterBinding Name=”MaximumRows” Location=”None” DefaultValue=”10″/>
</ParameterBindings>

Step 4 – XSL Style Sheet Params

In the very top of the XSL:StyleSheet you see a list of xsl:params. I just remove the ListID param as I’m not normally using it in my XSL.

<xsl:stylesheet …………[cut for brevity] ……………………>
<xsl:output method=”html” indent=”no”/>
<xsl:decimal-format NaN=””/>
<xsl:param name=”dvt_apos”>&apos;</xsl:param>
<xsl:param name=”ManualRefresh”/>
<xsl:param name=”ListItemId”>0</xsl:param>
<xsl:param name=”ListID”>{62F19BE4-6465-4293-B580-36C49EC8F35B}</xsl:param>
            <xsl:param name=”MaximumRows”>10</xsl:param>
<xsl:param name=”FavoriteLink” />
<xsl:variable name=”dvt_1_automode”>0</xsl:variable>

Finished…

Each step of the way you can save and test. When you are finished you should be GUID free.

Conclusion

This may not be a silver bullet for all scenarios of using the DVWP or some of the list form web part through designer. This is what I’ve found to work for me time after time. There may be cases when you need the ListID in the XSLT and you’d want to keep it there and replace the ListID with ListName there.

If you find this not to work please contact me and we’ll sort it out and keep this post current.