2

,I need to build something (using a sandboxed solution?) to demonstrate that SharePoint has the ability for users to copy a document (with its attributes) from a doc library in one site to a doc library in another site (same site collection, if it matters) without an external application. This will be so that users across multiple sites can go to my library, choose a word template and then copy any number of those to their own library.

I understand this may become complicated with people picker and lookup fields, but even the most basic of functionality is appropriate now. We were originally thinking that there was an OOTB feature which may be able to do that, but that doesn't seem to be of much help so I'm willing to learn anything at this point.

I'm just looking for a recommendation of the best way to go about doing this before possibly overthinking the solution.

edit: Explorer and Designer have been ruled out as options for our end users. The closest example of what I'm looking for is the "Send to other location" option that allows you to copy files with their metadata over to another library. But I would like users to be able to do this in bulk (e.g., make 20 copies of a certain template in one instance). Can I modify this tool at all or would I need to create my own? Thanks!

3 Answers 3

5


I no in your post you said "without an external application" but does that include js libraries?
Below is a simple solution that will copy a document from one SP library to any other SP library. I have not verified its cross-site scripting capabilities but it theoretically should work across farms, domains, and different SP versions. (It 100% works across webs in same site collection)
Simply copy this code into an .html file, replace the path/to/jquery* with the path to your jquery and spservices files, and add a Content Editor Web Part to what ever page you want to host the interface and set its content link to the location of the .html file you created.

Since you want to allow sending to multiple destinations I recomend using a textarea instead for the destination url(s) and then parse them by line ie: $("textarea").val().split("\n").each(myfunc);

You could also extend this to utilize the currently selected document as the source or even use a list item dropdown with url tokens to send a query string paramater to another page whose value(s) would give you the information necessary to retreive the source document information.

Note: This example uses Jquery and SPServices
References: Using JS in CEWP

<label>Copy From:</label><input type="text" value="" id="copyFrom" maxlength="255">
<label>Copy To:</label><input type="text" value="" id="copyTo" maxlength="255">
<input type="button" onclick="copyItem();" value="Copy">
<script type="text/javascript" src="/path/to/jquery.ver"></script>
<script type="text/javascript" src="/path/to/jquery.SPServices.ver"></script>
<script type="text/javascript">
    function copyItem(){
        var itemurl = $("#copyFrom").val();
        var dst = $("#copyTo").val();
        $().SPServices({
            operation: "GetItem",
            Url: itemurl,
            async: false,
            completefunc: function (xData, Status) {
                itemstream = $(xData.responseXML).find("Stream").text();
                       console.log(itemstream);
                itemfields = "";
                $(xData.responseXML).find("FieldInformation").each(function(){
                    itemfields+=$(this).get(0).xml;
                });

            }
        });
        $().SPServices({
            operation: "CopyIntoItems",
            SourceUrl: itemurl,
            async: false,
            DestinationUrls: [dst],
            Stream: itemstream,
            Fields:itemfields,
            completefunc: function (xData, Status) {
                var error = $(xData.responseXML).find("CopyResult").first().attr("ErrorCode");
                       console.log(error);
            }
        });
    }
    //to run in console uncomment line below
    //copyItem();
</script>

UPDATE

Instead of parsing the destination URL's one at a time you can actually store them in an array and pass it to the DestinationUrls parameter which accepts an array of destination urls.

Also, I have tested this function successfully in console on a page containing the spservices and jquery library using hardcoded absolute urls for the dst and itemurl variables.

UPDATE 2

I forgot to mention that I had issues copying the fields over. What I ended up doing was retrieving the source List fields and removing any read only ones using the function below.
I neglected to mention this because my particular implementation gives me easy access to the source listguid via a querystring. If you need to find yours check out the $().SPServices.SPListNameFromUrl function which I have had mixed success with.

var fieldstocopy = '';
    var itemfieldsxml = $.parseXML(itemfields);
    $().SPServices({
      operation: "GetList",
      listName: ListGUID,
      async: false,
      completefunc: function(xData, Status) {
        $(xData.responseXML).find("Fields > Field").not("[ReadOnly='TRUE']").each(function() {
          var $node = $(this);
          fieldstocopy+=$(itemfieldsxml).find("FieldInformation[InternalName='"+$node.attr("Name")+"']").first().get(0).xml;
        });
      }
    });
7
  • Hi Realistic, I think I would like to go with this option, but I can't seem to get it to work properly on my display form. For the "copy from" ID, I'm entering the document url (e.g, mysite/subsite/Library/Template.docx) and for the "copy to" I'm entering the library url (e.g., mysite/subsite/Library). -- Is this not correct for the parameters you've specified? edit: I will try it with the new .docx file added. Feb 24, 2014 at 17:49
  • 1
    The copyto url needs to be the full url including the new filename.
    – Realistic
    Feb 24, 2014 at 17:52
  • I'm noticing that even if I enter the values directly into the function (e.g., setting itemurl = to "mysite.com/sites/Library/blank.docx"), the copy function doesn't seem to work. Could you give an example in which this executes efficiently? The console (in developer mode) tells me: "The value of the property 'copyItem' is null or undefined, not a Function object" Feb 24, 2014 at 20:45
  • I updated the code a bit and fixed a small error. I have tested the script verbatim in console (using hardcoded absolute urls) and it worked. Also, did you by chance give the input button element the same name of the function? Doing so has given me that error before.
    – Realistic
    Feb 27, 2014 at 17:59
  • Thanks! For now, this is only copying the documents with the name property (seems to have trouble mapping the other fields), but this is much easier to work with. Feb 27, 2014 at 20:31
0

I can think of 2 very simple options:

1) users can copy items with lists/libraries opened in Windows Explorer

2) users can copy documents with "Content and structure":

http://yoursite/_Layouts/sitemanager.aspx?Source={WebUrl}_layouts/settings.aspx

Option one will not bring all of the document's metadata across to the new location (e.g. Created, Modified, etc.).

1
  • Unfortunately, our users wouldn't be able to access this feature. I have edited my original post. Sorry for the vagueness! Feb 24, 2014 at 14:09
0

I may be missing something, but why not just set up the original documents as Site Content Types? By setting them as a Content Type, you can include the metadata fields and assign a default template (your original document) to the type. Once the Content Type has been set up, you can include it in the users' document library so there doesn't have to be any copying back and forth.

Also, if you happen to change the original document, you can just update the content type and the template will change for everywhere it has been included, instead of you having to re-copy the document to each separate destination.

1
  • Thank you for this suggestion. However, we will have several content types set up with a few documents and pre-defined attributes already. That isn't an issue. My users want to be able to have a separate library where they have many "templates" that any number (200?) users will want to add to libraries within their own sites. I won't be maintaining the site after it is set up, so I can't add them as content types each time. Feb 24, 2014 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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