3

My customer has a requirement that they be able to "edit" existing items by creating new ones with those values. I was considering making a rest call based on the ID in the query string and populating the controls. It would work, but it'd require a lot of messy clean up involved this way due to the difference in how the values are displayed in a JSON request versus how I would need to transform them in order to set the new fields using JavaScript/jQuery.

In order to avoid this, I created a custom New Form and changed a few of the controls to "Edit" mode. This looked like it worked (those controls were pre-populated with values from the original item) until I saved an item and noticed that it was simply updating the original item instead of creating a new one even if the PageType was still set to NewForm.

Is there any way I could set default values on the New Form based on the ID in the query string or to leverage the edit controls that are automatically being populated from the referring item? Even with the "submit" button having its control mode set to "New", it functions the same way.

My first thought is to use a workflow and copy the list item.. but the customer doesn't want to have to wait for a workflow to create the item or for his people to have to search for the newly created form before editing it.

1

Then you don't need some fancy javascript to load in values etc.

You may bash on JavaScript all you want; it is the preferred solution here from an End-User point of view because he/she triggers the cloning in the Browser.

You have to let go of the old-school SharePoint back-end approach and poplulating controls.
All you have to do is

  • create a new item
  • copy field values from the original item
  • Open the EditForm of that new item

The user may want to clone an Item either in a Display Form or a View.

If you are happy with only activating from a View

You can paste this Formula in a Calculated Column and set the Datatype to Number

="<img style=cursor:pointer src=/_layouts/images/icongo01.GIF onclick=""{"
&"event.stopPropagation();"
&"function cloneItem(id){var c=new SP.ClientContext.get_current(),"
&"l=c.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList()),"
&"i=l.getItemById(id),f=l.get_fields(),n,e,d,m,v,"
&"url=_spPageContextInfo.serverRequestPath;c.load(i);c.load(f);"
&"c.executeQueryAsync(function(){"
&"n=l.addItem(new SP.ListItemCreationInformation());e=f.getEnumerator();"
&"while(e.moveNext()){d=e.get_current();m=d.get_internalName();"
&"if(!(d.get_readOnlyField()||d.get_hidden()||['Attachments','ContentType'].indexOf(m)>-1)){"
&"v=i.get_item(m);if(v)n.set_item(m, v);}}n.update();c.load(n);"
&"c.executeQueryAsync(function(){"
&"document.location=url.substr(0,url.lastIndexOf('/'))+'/EditForm.aspx?ID='+n.get_id();})})}"
&"this.style.display='none';var TR=this;while(TR.tagName!='TR'){TR=TR.parentNode}"
&"TR.style.cursor='wait';cloneItem(TR.id.split(',')[1]);"
&"}"">"

Full explanation at http://www.viewmaster365.com/#/How (including Pros & Cons)

It adds a Clone button to the View, onclick it

  • Creates a new Item in the current List
  • copies all Fields from the current Item to the New Item (exlcuding Attachments/ContentTypes)
  • redirects the browser to the EditForm of the New Item

It only works in Views.. but does work in SP2010

In SP2013 you can offload the logic to a CSR file; and use it anywhere you want. But you need some more boilerplate code to trigger the uncompressed code:

function cloneItem(id) {
    var c = new SP.ClientContext.get_current(),
        l = c.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList()),
        i = l.getItemById(id),
        f = l.get_fields(),
        n, e, d, m, v,
        url = _spPageContextInfo.serverRequestPath;
    c.load(i);
    c.load(f);
    c.executeQueryAsync(
        function () {
            n = l.addItem(new SP.ListItemCreationInformation());
            e = f.getEnumerator();
            while (e.moveNext()) {
                d = e.get_current();
                m = d.get_internalName();
                if (!(d.get_readOnlyField() 
                       || d.get_hidden() 
                       || ['Attachments', 'ContentType'].indexOf(m) > -1)
                   ) {
                    v = i.get_item(m);
                    if (v) n.set_item(m, v);
                }
            }
            n.update();
            c.load(n);
            c.executeQueryAsync(function () {
                document.location = url.substr(0, url.lastIndexOf('/')) 
                                     + '/EditForm.aspx?ID=' + n.get_id();
            })
        })
}

ICC

  • This seems like a very good approach. I'd probably implement it in a custom action on the ribbon. I'm going to research this to see if I can leverage this model to add attachments as well. Thanks – Dinerdo Aug 30 '15 at 22:59
  • I didn't use this method, but I did use the idea behind it. I copied the list item to a new item with all of the properties aside from the ContentType and ID fields.. then I iterated through the attachments on the original item and added them to the new item before directing the user to my custom edit form. It was a learning process.. but I'm happy with the result. Thanks! – Dinerdo Aug 31 '15 at 5:52
  • It seems like there's not a good way to actually GET the binary info for attachments in order to reattach them as new attachments. This is imperative for my product to be rolled out. Do you have any insight on possible solutions for creating a copy of a list item with its attachments outside of a workflow? I need to be able to create a new item based on an existing item with the exception of a few fields. That works great, but for the attachments to be excluded is unacceptable :( – Dinerdo Sep 11 '15 at 14:43
  • m getting this Column Validation Failed. error after adding the above stated code inside formula field,this error comes after trying to uploading document to document library – Madhav Jun 13 '16 at 6:38
  • This type of Formulas are a pain to edit; strip code to eliminate good lines until you come to the problem line. – Danny '365CSI' Engelman Jun 13 '16 at 9:47
1

What you need to do is create a new Edit form, not create a new New form.

You can reuse all the Edit form markup from the original Edit form from the list, but you will have to add some custom codebehind to override the Save mechanism.

I've found that these 2 blog posts describe quite well how to do this; given they describe it for a custom Display form, the principles are the same.

Then you don't need some fancy javascript to load in values etc.

  • I don't believe I'm able to modify any of the code-behind code in mmy environment. Thank you though. This would be the best approach for sure.. – Dinerdo Aug 30 '15 at 22:59

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.