Getting Item ID Before Document Saved.

Aug 1, 2013 at 10:57 AM
I have a parent child relationship between an orders and a products list (part of an order). In the order forms you can add products.

That's working fine, but the problem I have is that obviously the new order doesn't get an ID until it's saved, meaning the products can't be related back to an order.

Just wondering if anyone knew a good way to work around this.

The options I've thought of so far are:-
  1. Using an independent counter/field I can increment on form load using SPS, instead of the item ID,
  2. On NewForm.asp load, create a new order on the fly using SPS and then send them to the edit form for that new document.
  3. somehow tag the new products and update them after the order has been submitted with a workflow running on the order list.
Any advice/suggestions?
Aug 1, 2013 at 6:48 PM
Anyone got any thoughts on this please? I thought it'd be a fairly common issue when you're doing stuff behind the scenes with web services.
Aug 2, 2013 at 12:03 AM
You are going to have to describe your List setup a little more. I'm not sure what relationships you are trying to capture.

I think you are trying to create an order that has relationships to products. Yes?

How many lists do you have setup? Just Products and Orders?

_____
Paul

Sent from mobile device.

Aug 2, 2013 at 10:55 AM
The basic problem is getting the item/order ID before it's saved for the 1st time to use to relate the products to that order.

Yes, there's just Products and Orders involved. The products are related to the order by Order.ID. Products are added to the order by clicking a button in the order NewForm.asp and EdtForm.asp forms.

Hence the problem in the new form, as the order won't have been saved yet and won't have an ID to use in the products.
Aug 2, 2013 at 2:17 PM
It's the part "relate products to that order" that is very fuzzy here... but I'm going to leave that alone :) I assume you have a design that you are going with...

You only have a few options here: you either create the item first, or you capture it after creation and use it to relate your products.

Here are a few ideas:

Create item first - use EDIT form for user input

If you can control where the User clicks, then you might be able to just create the order with minimal input (ex. just a Title) behind the scenes using SPServices and use ID of new item to open it in the EDIT Form... Once you are on the Edit form, you already have the ID and thus you can use it to do the relation you speak of.

Example:
  1. User clicks on NEW ORDER
  2. Script, using SPServices creates a new order with minimal input (using UpdateListItems), which returns the new item created (including the ID).
  3. Use the ID of the new item and open it on the EDIT form.
The user never really sees the NEW form... they just go directly to the Edit form. Yes, this does introduce complexities with "what if the user changes their mind and wants to cancel the order"

Get the New item ID after create

The trick with this one is to redirect the NEW form, after the user clicks "OK" to a landing page where you have custom code to retrieve the new ID. This can be achieved by using the &Source=http://... URL param when opening the NewForm.aspx.
Lets say that you have a aspx page called "wait.aspx" that has the javascript code to retrieve the ID of the last Order created by the user (perhaps using the SPSerivces SPGetLastItemId() utility). To get the NewForm to redirect there you would opened it as:
/NewForm.aspx?Source=http://yoursiteUrlEscaped/wait.aspx
When the user Clicked OK on the new form, if all was successful, they will be redirected to the wait.aspx page where your code would then run, get the ID and make the relationship of the order to the Products.

Hope this helps... Good Luck.

Paul.

Ps. Although I was going to leave it alone, I'll just mention it: it still feels like the relationship you are trying to build can be supported with the OOB capabilities of SharePoint and List...
Aug 2, 2013 at 2:54 PM
Thanks. presaving the form then using the edit form sounds like a good approach, as then I'll only have one form to customise as well. It should be fine as regards to cancelling etc, as the order form has various statuses and won't actually be submited, until they choose to submit it, regardless of save. If they never actually submit it, it'll just sit there as draft and could be cleaned up later.

I'd like to just use the standard list "New" button. Is it possible to override that button, or would I have to update newform, to create the order, then redirect to the edit form from there?

The post processing technique using the source URL is interesting. I'll try the other way 1st I think, but sure that will come in handy at some point.

What part don't you understand about the relationship? It's similar to "add to basket" functionality on websites. I'm always open to suggestions if there's a better way, but not sure how you mean about standard list functionality.

I have an online order from effectively, from which people can order 100's products per order. Instead of having 100's of fields in the order form, products when added are created in another list, with the order id stored and displayed in the order. So the order actually consists of all products ordered with that order ID.
Aug 2, 2013 at 3:48 PM
i tried Redirecting in the new form and it does it pretty quickly. I haven't done the item create yet, but that'll be quick. I was concerned the whole original page would load and show before the edit form was loaded, but it looks fine.

So that looks like it should work well. Thanks.

Feel free to make any suggestions about the relationships etc though.
Aug 2, 2013 at 5:25 PM
Re: Understanding of how you are storing data
What I don't understand is the approach you are taking for storing the relationships of orders to products... or products to Orders.... can you elaborate on that? is it rows in a list? data in a column? If data in a column - where? the Order list? the Product List?
If you can describe your list setup and column of each, I (or several that "listen" to this SPSErvices forum) can help.

Re: New Button intercept
You could overwrite the NEW button on the page with javascript so that when the user clicked on it, it would not redirect to the NEW form... but... that button can appear in a few places. I Think the easiest path is for you to customize the NEW form and
  1. Hide the UI from the User
  2. Using javascript/SPServices - create a new item. This returns to you the new order created.
  3. Use the ID of the new item and redirect the URL to the Edit page.
Customizing the NewForm is a "catch all"... regardless how the user got there (ex. they typed the URL, they clicked the NEW button on View... they clicked the NEW button on a DISP form), it all lands on the NEW form and thus your customization is assured to kick in.

RE: Your statement - "i tried Redirecting in the new form and it does it pretty quickly. I haven't done the item create yet, "
So I'm not sure what you did here... I'm assuming you invoked the NEW form for the Orders with a source= defined and then clicked CANCEL? because if you clicked OK, the new item should have been created (your sentence said you did not yet create the item).
Aug 2, 2013 at 7:08 PM
I'm storing the Order ID in the Products (ordered) list. It's a simple parent-child relationship.

Good point about the various routes to the NewForm. I'll stick to doing it on the form.

I meant I didn't create the new item using SPS (to get the ID). I just put a redirect in .ready on the newform to a random editform. So I click "new" and end up in the edit form as suggested.
Coordinator
Aug 5, 2013 at 11:25 AM
Guys:

Just getting back from vacation, so sorry for the delayed reply. I haven't read all of the above, but have you looked at SPRedirectWithID? From your original post in the thread, I think it does exactly what you are trying to do. It's a tricky little problem.


M.
Aug 5, 2013 at 12:04 PM
Welcome back.

Just had a quick look. Looks good and certainly very useful, but it seems to work on the form save, which would be too late for my needs. I need to add products to the order before they submit/save.

I'm happy with creating an order on the fly in the new form and then instantly redirecting to the edit form, That'll be pretty slick and eliminate the need to for a separate newform at all.

Only downside I can see if that every "New" click would result in a item created, either if they then abandon it, but that's not really a problem to me.

I'm sure other people could use the same functionality or want to eliminate newform custimisation. Could this be a future new feature of SPS, or option in SPRedirect?
Aug 5, 2013 at 12:11 PM
Edited Aug 5, 2013 at 12:27 PM
Just thought of another possible issue. You'd have to be careful with server side form validation. Assuming that's actually enforced via WS.

I use status based, client side validation, so not an issue for me.
Coordinator
Aug 5, 2013 at 1:18 PM
It is what it is, really. Because IDs are assigned on item save, and asynchronously at that, we can't know the ID ahead of time.

If you're customizing your validation, then you could also do a save with UpdateListItems. This will return the ID to you and you are off and running.

M.
Aug 5, 2013 at 10:27 PM
Mark,
Yeah, I though about suggesting the Redirect utility, but his needs was very specific...

Did not know that - "...assigned on item save, and asynchronously at that..."

I'm assuming this is the case for non-webservices updates (ex. those done via the SP Forms)... In my workings with UpdateListItems, the ID seems to always be returned on the response (the workflows, however, I know run async and cant take a little bit to complete).



_________
Paul T


Sep 30, 2013 at 12:52 AM
Great thread, because the use case described was exactly what I wanted to do. For the record this is how I achieved it (using SP2013 online):

1) Created a custom new item form (NewTrainingItemRedirect.aspx)
2) Created a custom edit item form to act as a pseudo new item form (NewTrainingItem.aspx)
3) Added a Script Editor WP to the NewTrainingItemRedirect.aspx page and referenced my .js file, which contained the following:
"use strict";

$(document).ready(function(){
    
    //hide page - hides all page content other than the uppermost menu bar (with Outlook, Calendar, People... on)
    $("#s4-ribbonrow").hide();  //hides the ribbon
    $("#s4-workspace").hide(); //hides main body of page, including, by definition, the default form rendering
    
    //display message - not imperative to do, but this is a small function I use from time to time to display custom HTML-based messages whilst SP does stuff
    var $pageContentTitle = $('div[id="suiteBarDelta"]');
    $pageContentTitle.after("<div id='confmsg'></div>");
    displayMsg("Working on it...");
    
    //create register item - creates a dummy item in my list.  In my case 'Branch' is a lookup field and is the only Required field
     $().SPServices({
            operation: "UpdateListItems",
            async: false,
            batchCmd: "New",
            listName: "Employee Training Register",
            valuepairs: [["Branch",7]],
            completefunc: function(xData, Status) {
              //    alert(Status);
         } //end completefunc
        }); //end UpdateListItems

    //get Traininglog ID - gets the ID of the item I have just created
    var $lastID = $().SPServices.SPGetLastItemId({  
        webURL: "",
        listName: "Employee Training Register",
        userAccount: "",
        CAMLQuery: ""
        });
    
    //console.log("Last ID = " + $lastID);
        
    //redirect to 'edit' page with ID, although this should only be a pseudo edit page as the main edit page has preformatted field
    var $url = $().SPServices.SPGetCurrentSite(); //gets the URL of the current site

    var $newTrainRegItemIDUrl = $url + "/Lists/Employee Training Register/NewTrainingItem.aspx?ID=" + $lastID; //forms a path string to my pseudo edit form.
    window.location.replace($newTrainRegItemIDUrl); //performs the actual page redirection

});//end ready
and after this all down-stream code kicks in as I would like.

Thanks @ixwood for kicking off and contributing to this thread and @ptaveres for bouncing around your ideas. +1 to you both.

Simon
Sep 30, 2013 at 1:10 AM
Awsome. It's already good to hear success stories.
Paul.


--

_________
Paul T

Aug 5, 2015 at 3:50 PM
I'm doing the exact same thing. Actually, I did the exact same thing in SharePoint 2007 and 2010, using Marc's SPRedirectWithID. Unfortunately, I can't get SPRedirectWithID to work in SharePoint 2013 online.

So I'm starting from scratch SharePoint 2013 online. First I created the parent child relationship ixwood describes (and a VERY good resource for this is here). My parent list is called Orders. My Child list is called Line Items. The link explains how to put the code needed into my parent list's DisplayForm and my child list's NewForm. They work like a charm.

If SPRedirectWithID worked, I would use it on the parent list's NewForm, like I did in SharePoint 2007 and 2010.

Instead, I'm going to try using ptavares' Get the New item ID after create method to redirect users, after saving the NewForm list of the parent list, to a page where they will see their order and can click on a link to go to the parent list's display form, where they can then happily add Line Items to their order and save it, change order details, delete it, submit it, etc. I dislike having to use the in-between step, but it seems workable.