Redirect to Another Page from NewForm.aspx with the New Item’s ID

UPDATE 2009-10-19: I solved this for real in the jQuery Library for SharePoint Web Services function called $().SPServices.SPRedirectWithID.  Feel free to read this post, but this is the solution you’re looking for.

UPDATE 2009-10-01: I’ve posted an update on this idea.  It’s possible to simplify the interstitial page using the Web Services from the jQuery Library for SharePoint Web Services, but I’m still not satisfied: Redirect to Another Page from NewForm.aspx with the New Item’s ID: Redux.

Here’s a good question from prostration in the MSDN SharePoint – Design and Customization forum:

I need to go from the newform page to the editform page of the item I just created. So when I click save I want it to create the item and take me to it’s editform page. How can I do this?

My first answer was bollocks, but I do have a workable approach.

The problem is that the ID for the new item is unknown before the item has been created.  I came up with a scheme about a year ago to deal with this, and some Binging tells me that there aren’t any spiffier ideas out there, at least that I could find.

The trick is to commit the new item and then determine its ID to pass to whatever page you want on the Query String.  I did this by creating an intermediate page which just finds the ID with a DVWP and then redirects to the other page.

So first convert the NewForm.aspx to XSLT.  (I usually just create a new DVWP from scratch so that I can keep the page code clean.)  Then, change the Save button behavior like so:

<input type="button" value="Save" name="btnSave" onclick="javascript: {ddwrt:GenFireServerEvent('__commit;__redirect={GetLastID.aspx?RedirectURL=EditForm.aspx}')}" />

The code for my intermediate page is below.  Note that I’ve constructed it so that you can pass in the redirect page (RedirectURL) so that you can use it to do other things.  All this page does in its DVWP is find the most recent item in the list which was created by the current user and redirect to RedirectURL with the ID on the Query String.

<%@ Page Language="C#" inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<html>

<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

<body>
<form id="form1" runat="server">
<WebPartPages:DataFormWebPart runat="server" IsIncluded="True" FrameType="None" NoDefaultStyle="TRUE" ViewFlag="0" Title="Events" __markuptype="vsattributemarkup" __WebPartId="{020AF483-2135-4D37-B6C7-CD6A6FD6AF5D}" id="g_a8a4d070_e7c0_4105_a113_acff9dea3328" pagesize="1" __AllowXSLTEditing="true" WebPart="true" Height="" Width="">
    <DataSources>
        <SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" selectcommand="<View><Query><Where><Eq><FieldRef Name=&quot;Author&quot;/><Value Type=&quot;Integer&quot;><UserID/></Value></Eq></Where><OrderBy><FieldRef Name=&quot;Created_x0020_Date&quot; Ascending=&quot;FALSE&quot;/></OrderBy></Query></View>" id="dataformwebpart2">
            <SelectParameters>
                <WebPartPages:DataFormParameter Name="ListName" ParameterKey="ListName" PropertyName="ParameterValues" DefaultValue="Assignments"/>
            </SelectParameters>
        </SharePoint:SPDataSource>
    </DataSources>
   
<parameterbindings>
        <ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
        <ParameterBinding Name="RedirectURL" Location="QueryString(RedirectURL)" DefaultValue=""/>
    </parameterbindings>
    <datafields>@Title,Title;@Start_x0020_Time,Start Time;@End_x0020_Time,End Time;@ZIP_x0020_Code,ZIP Code;@Amount,Amount;@Nominee,Nominee;@ID,ID;@ContentType,Content Type;@Modified,Modified;@Created,Created;@Author,Created By;@Editor,Modified By;@_UIVersionString,Version;@Attachments,Attachments;@File_x0020_Type,File Type;@FileLeafRef,Name (for use in forms);@FileDirRef,Path;@FSObjType,Item Type;@_HasCopyDestinations,Has Copy Destinations;@_CopySource,Copy Source;@ContentTypeId,Content Type ID;@_ModerationStatus,Approval Status;@_UIVersion,UI Version;@Created_x0020_Date,Created;@FileRef,URL Path;</datafields>
    <XSL>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
    <xsl:output method="html" indent="no"/>
    <xsl:param name="UserID">CurrentUserName</xsl:param>
    <xsl:param name="RedirectURL" />
	<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
        <xsl:call-template name="dvt_1"/>
    </xsl:template>

    <xsl:template name="dvt_1">
        <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
        <xsl:for-each select="$Rows">
            <xsl:call-template name="dvt_1.rowview" />
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="dvt_1.rowview">
        <script type="text/javascript">
            document.location.href = &apos;<xsl:value-of select="$RedirectURL" />&apos; +
                &quot;?ID=&quot; + &apos;<xsl:value-of select="@ID" />&apos;;
        </script>   
    </xsl:template>
    </xsl:stylesheet>
</XSL>
</WebPartPages:DataFormWebPart>
</form>
</body>
</html>

Similar Posts

63 Comments

  1. This is a very useful code and appreciate you sharing it with us. I had to spend 3 hours trying to figure out why the code you listed above didn’t work. I guess when you put it on the site, it somehow added stuff to it. The xsl:stylesheet tag has added “href=” tags. Could you somehow clean it up so the next person doesn’t have to spend hours figuring it out?

    Thanks again for the code! It makes SharePoint a little more useful.

    1. tsquareweb:

      I’m really sorry that you had trouble with it. Looking at the code, you are absolutely right. I’ve noticed that some of the upgrade to the sourcecode shortcodes here at WordPress have caused some problems over time. I’ll clean it up now. Hopefully I saved you more time than I cost you!

      Based on your description on your first comment above, couldn’t you have the redirect happen just by setting the Source Query String parameter to the current DispForm.aspx’s URL?

      M.

      1. Marc,
        Yes your code allowed me to do what I needed to do. I just wrote you to thank you and to prevent the next person from going through the troubles I did.

        Thanks again!

  2. Hi Mark,

    I have just posted about redirection from NewForm.aspx in my blog. You may be interested how you can implement this without SharePoint Designer, Custom Forms and XSL Stylesheets.

    Mindaugas

    1. Mindaugas:

      Your solution is fairly similar to mine to date (though you went one step further by using the SPAPI. My goal in this is to make it work by making a change in NewForm.aspx (a COPY of NewForm.aspx, of course) *only* to include in our jQuery Library for SharePoint Web Services (http://spservices.codeplex.com). I think I’ve got a solution framed up in my head; just need to bang it out. I have high hopes that it will work.

      Thanks for the comment and stay tuned!

      M.

  3. There is actually an easier way of achieving the requested functionality. The following shows the basics of the method which will give you the actual ID (instead of a best guess).

    SaveButton.SaveItem(SPContext.Current, false, "");
    int newid = SPContext.Current.ListItem.ID;
    
    1. CJ:

      Your point is valid, but only if you’re writing code on the server side. My solution is entirely script-based and requires no changes to the server whatsoever.

      M.

  4. I get the following error when clicking on save and the page redirects.

    Access denied. You do not have permission to perform this action or access this resource.

    1. Tyler:

      You’ve given very little to go on here, but if you’re getting an Access Denied error, then it’s a permissions issue with *something*.

      M.

  5. Marc – Thank you for this wonderful work-around. It indeed made my day.
    By the way you deserve the MVP status and thank you for all your marvelous work for that you are doing for the SharePoint community.

    Sincerely.

  6. Hello Marc,

    I wanted to thank you for putting the great logic together for getting last item from a list.

    I have a additional reqirement where I have to redirect the page to newform.aspx page if NO item exists from a particular user.

    In cuurent configuration it shows a blank page if there is no item in the list created by a particular user id. I need to redirect user to newform.aspx page if there is no item created by a user.

    Hope to hear from you soon.

    Thanks,
    Mahinder Gola

    1. Mahinder:

      I don’t think I understand your requrement fully. Also, it’s not clear to me if you are using the logic in this post or the SPRedirectWithID function in SPServices. Can you explain more? If it’s a question about the SPServices function, then please use the Discussions on the Codeplex site.

      M.

      1. Thanks so much for the quick response on this.

        I am using “Intermediate page” methode to get latest ID created by user and its working fine but ….

        it shows blank page if there is no item created by a current user. I want to add a functionality to this Intermediate page that it can redirect current user to newform.aspx if no item (ID) found for the current user.

        Thanks,
        Mahinder Gola

        1. Mahinder:

          OK, then you’ll need to put some conditional logic into the DVWP to handle the instance where there are no items returned for the current user.

          M.

          1. Thanks Marc,

            I thought same and trying to put a logic into DVWP since this moring but could not get it working… it seems complicated to my small brain and really need your help.

          1. Hello Marc,

            Thanks for your great help.

            By chance, Can this be achived via “Intermediate page” method?

            1. Yes, I think you can make it work by adding some code below line 38. It would be something like (but totally untested):

                  <xsl:template name="dvt_1">
                      <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
              	<xsl:choose>
              		<xsl:when test="count($Rows) = 0">
              		       <script type="text/javascript">
                      		    document.location.href = &apos;NewForm.aspx&apos;;
              		       </script> 
              		</xsl:when>  
              		<xsl:otherwise>
              	        	<xsl:for-each select="$Rows">
              	            		<xsl:call-template name="dvt_1.rowview" />
              		        </xsl:for-each>
              		</xsl:otherwise>
              	<xsl:choose>
                  </xsl:template>
              

              M.

  7. Hello Marc,

    I have a scenario where in I would like to give user permissions to add,edit and view items created using newform or editform but should not able to see Site Actions menu ,

    The problem I am facing is once I give all the above permissions to user it display Site Actions menu with View All Site Content option.

    If you could please help me out to find solution would be appreciable.

    Thanks,
    Anjalee

    1. Anjalee:

      The built-in SharePoint permissions and the impact they have on specific page components are not always able to meet every odd requirement people throw out there. For instance, by default if you have contribute permissions you see the View All Site Contents link, on the theory that you might like to navigate to the items.

      It depends on whether you really need security or just obscurity. If it’s the latter, you can hide the components with script or by altering the master page. If it’s the former, it’s a more difficult problem to solve.

      M.

      1. Hello Marc,

        Thanks for the reply…

        yes I would like to have this functionality for the security as the portal we are building would be accessible to global users and we dont want to give them aceess to View All site content …

        User should be able to fill newform or editform of particular list though..Is there any way we can just hide the Site Actions Menu if can not completely remove for the user?

        Thanks,
        Anjalee

        1. Anjalee:

          The Site Actions menu and View All Site Content come from the master page. To secure them you’ll need to devise a new scheme to: 1) Remove them from the master page, and 2) Secure the pages in _layouts which provide the functionality the permissions you have granted provide.

          This is non-trivial and beyond a simple comment here.

          M.

          1. Marc, Thanks for the reply .Would it be possible to do with SPSecurityTrimmedControl settings in master page?

            I tried some options but didnt work out…

            Thanks,
            Anjalee

            1. Yes, but the will simply hide the controls, and will impact the entire site or sites which use the master page.

              A savvy user who knows that the _layouts/viewlsts.aspx page exists can still get there. Thus my question about security vs. obscurity.

              M.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.