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;
});
}
});