Sharepoint - Custom ECB-Menu Item which copies the Link of the document into the Clipboard

I had a similar requirement sometime ago.

Due to browser compatibility issues, I ended up using window.prompt, shifting the control of the copy/paste functionality over to the user:

window.prompt ("Copy to clipboard: Ctrl+C, Enter", text);

BTW, the text will already be selected, so the user simply has to press CTRL+C.

At the time I believe this is where I got the idea from:

https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript

EDIT

The (very rough) code below will do as asked:

Create a custom action, when clicked, display the link to the document.

Alternatively, you can use some additional tweaking to actually save the link into the clipboard. Some apis are referenced in the Stack Overflow link above, though they may not support all the browsers.

console.log("hello world");

//https://msdn.microsoft.com/en-us/library/office/hh185004%28v=office.14%29.aspx#sectionSection0

var webUrl = "/sites/a/b/c";
var actionTitle = "My First User Custom Action";
var listTitle = "Procedures";//consider using context.ListTitle if available

//potentially use these to grab the current url automatically
function getWebUrl()
{
    return _spPageContextInfo.webServerRelativeUrl;
}
function getSiteUrl() {
    return _spPageContextInfo.siteServerRelativeUrl;
}

function createUserCustomActionList() {

    var clientContext = new SP.ClientContext(webUrl);

    //var listTitle = clientContext.ListTitle;

    var oWebsite = clientContext.get_web();
    this.oList = oWebsite.get_lists().getByTitle(listTitle);
    var collUserCustomAction = oList.get_userCustomActions();

    var oUserCustomAction = collUserCustomAction.add();
    oUserCustomAction.set_sequence(100);
    oUserCustomAction.set_title(actionTitle);

    oUserCustomAction.set_location('EditControlBlock');

    //oUserCustomAction.set_url(webUrl + '/_layouts/MyPage.aspx?id={ItemUrl}');

    //use ItemUrl property to grab the url of the selected item (also available, ItemID).
    //using function instead of redirect
    //consider using other apis to automatically store in the clipboard: https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript
    oUserCustomAction.set_url("javascript:var link = '{ItemUrl}'; window.prompt('here you go', link);");

    /*
    failed attempts :)
    oUserCustomAction.set_location('ScriptLink');
    //oUserCustomAction.set_scriptSrc(webUrl + '/js/click.js');
    oUserCustomAction.set_scriptBlock = "\
    \
        function JSFX_StartEffects()\
        {\
            JSFX.Fire(200, 100, 100);\
        }\
        var windowOnload=window.onload||function(){};window.onload=function(){JSFX_StartEffects();};\
    \
    ";
    */

    oUserCustomAction.update();

    clientContext.load(oList, 'Title' ,'UserCustomActions');

    clientContext.executeQueryAsync(Function.createDelegate(this, function(){
        //success
        console.log("success");
    }

    ),

         Function.createDelegate(this, function(a, b){
            //error
            console.log("error:" + b.get_message());
         }

         ));

}

function deleteUserCustomAction() {

    this.clientContext = new SP.ClientContext(webUrl);
    var oWebsite = clientContext.get_web();
    this.oList = oWebsite.get_lists().getByTitle(listTitle);
    this.collUserCustomAction = oList.get_userCustomActions();

    clientContext.load(oList,'UserCustomActions','Title');

    clientContext.executeQueryAsync(Function.createDelegate(this, function()
    {
        //success
        console.log("custom actions loaded");       

        var customActionEnumerator = collUserCustomAction.getEnumerator();

        while (customActionEnumerator.moveNext()) 
        {
            var oUserCustomAction = customActionEnumerator.get_current();

            if (oUserCustomAction.get_title() == actionTitle) 
            {

                //will throw "collection updated" exception after, but will delete the action
                oUserCustomAction.deleteObject();

                clientContext.load(oUserCustomAction);

                clientContext.executeQueryAsync(Function.createDelegate(this, function(){
                    //success
                    console.log("custom action deleted");
                }

                ),

                 Function.createDelegate(this, function(){
                    //error
                    console.log("error deleting custom action");
                 }

                 ))

            }
        }

    }

    ),

     Function.createDelegate(this, function(){
        //error
        console.log("error loading custom actions");
     }

     ));

}


//ExecuteOrDelayUntilScriptLoaded(createUserCustomActionList, 'sp.js'); 

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){

    //delete custom action - in case code is executed more than once, delete the action, then recreate it
    deleteUserCustomAction();

    //create custom action
    createUserCustomActionList();
});

Screenshot:

enter image description here


Add this below given code in a CEWP (Content Editor Web Part).

<script language="javascript">
function Custom_AddDocLibMenuItems(m, ctx)
{
var strDisplayText = Redirect to form here;
var strImagePath = ;
var strAction = 'window.navigate(/.../editform.aspx?Source= document.URL.substring(0, document.URL.indexOf(/Forms, 0)) ?RootFolder= GetUrlKeyValue(RootFolder)) DocUrl= GetDocURL(ctx)';
// Add our new menu item
CAMOpt(m, strDisplayText, strAction, strImagePath);
// add a separator to the menu
CAMSep(m);
// false means that the standard menu items should also be rendered
return false;
}
function string GetDocURL(ctx)
{
var URL = ;
var index = itemTable.innerHTML.indexOf(href=);
if (index 0)
{
var str = itemTable.innerHTML.substr(index 6);
index = str.indexOf('');
if (index 0)
{
URL = str.substr(0, index);
}
}
return URL;
}
</script>