Question

this one is weird I hope somebody can help me.

I created a custom action for a callout on a document library. I added the javascript code in a code snippet webpart on top of the document library default view.

When I click on the left navigation menu to go to the library, the code throws this exception when I click on the 3 dots.

Uncaught TypeError: Cannot read property 'get_current' of undefined 

If I press Ctrl + F5, the code works fine.

<script type="text/javascript">
    SP.SOD.executeFunc("callout.js", "Callout", function () {
        IsCurrentUserMemberOfGroup("Approvers", function(isSuccess){
            if(isSuccess){
                var itemCtx = {};
                itemCtx.Templates = {};
                itemCtx.BaseViewID = 'Callout';
                // Define the list template type
                itemCtx.ListTemplateType = 101;

                itemCtx.Templates.Footer = function (itemCtx) {             
                  return CalloutRenderFooterTemplate(itemCtx, AddCustomCompleteAction, true);
                };  

                SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
            }               
        });
    });


    function AddCustomCompleteAction (renderCtx, calloutActionMenu) {  
        var Status = renderCtx.CurrentItem.Status;

        if(renderCtx.CurrentItem.ContentType=='Bill Cycle'  && Status=='') {
                calloutActionMenu.addAction (new CalloutAction ({
                text: 'COMPLETE',
                tooltip: 'This action will set status to Complete, this action cant be rolled back. Only click once the action can take a few seconds to complete.',
                onClickCallback: function() {UpdateBillCycleStatusToCompleted(renderCtx.CurrentItem.ID);}
            }));            
        }

        // Show the default document library actions
        CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu);

         // Show the follow action
          calloutActionMenu.addAction(new CalloutAction({
            text: Strings.STS.L_CalloutFollowAction,
            tooltip: Strings.STS.L_CalloutFollowAction_Tooltip,
            onClickCallback: function (calloutActionClickEvent, calloutAction) {
              var callout = GetCalloutFromRenderCtx(renderCtx);
              if (!(typeof(callout) === 'undefined' || callout === null))
                callout.close();
              SP.SOD.executeFunc('followingcommon.js', 'FollowSelectedDocument', function() { FollowSelectedDocument(renderCtx); });
            }
          }));
    }   

    function UpdateBillCycleStatusToCompleted(itemId) {
        var clientContext = new SP.ClientContext.get_current();
        var oList = clientContext.get_web().get_lists().getByTitle('Cycles');
        this.oListItem = oList.getItemById(itemId);
        oListItem.set_item('Status', 'Completed');
        oListItem.update();
        clientContext.executeQueryAsync(Function.createDelegate(this, this.StatusCompletedSucceeded), Function.createDelegate(this, this.StatusCompletedFailed));
    }

    function StatusCompletedSucceeded() {
        alert(' set to completed succeeded');
        window.location.reload(true);
    }

    function StatusCompletedFailed(sender, args) {
        alert(' update failed. ' + args.get_message() + '\n' + args.get_stackTrace());
    }

    function IsCurrentUserMemberOfGroup(groupName, callback) {
        var currentContext = new SP.ClientContext.get_current();
        var currentWeb = currentContext.get_web();

        var currentUser = currentContext.get_web().get_currentUser();
        currentContext.load(currentUser);

        var allGroups = currentWeb.get_siteGroups();
        currentContext.load(allGroups);

        var group = allGroups.getByName(groupName);
        currentContext.load(group);

        var groupUsers = group.get_users();
        currentContext.load(groupUsers);

        currentContext.executeQueryAsync(OnSuccess,OnFailure);

        function OnSuccess(sender, args) {
            var userInGroup = false;
            var groupUserEnumerator = groupUsers.getEnumerator();
            while (groupUserEnumerator.moveNext()) {
                var groupUser = groupUserEnumerator.get_current();
                if (groupUser.get_id() == currentUser.get_id()) {
                    userInGroup = true;
                    break;
                }
            }  
            callback(userInGroup);
        }

        function OnFailure(sender, args) {
            callback(false);
        }        
    }
</script>
Was it helpful?

Solution 2

fixed with this

$(document).ready(function () { ExecuteOrDelayUntilScriptLoaded(CustomAction, "sp.js"); });

    function CustomAction()

    {
           //Your Code
    }

OTHER TIPS

Since you are using SP.ClientContext in CSR, make sure the SharePoint script file 'sp.js' is loaded before your rendering code runs:

SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
 //Your code goes here...
});

This works for me when I am using WorkflowServices. It should work in your case as well:

ExecuteOrDelayUntilScriptLoaded(function () {
    ExecuteOrDelayUntilScriptLoaded(function () {
        SP.SOD.registerSod('SP.ClientContext', SP.Utilities.Utility.getLayoutsPageUrl('sp.js'));
        SP.SOD.registerSod('SP.WorkflowServices.WorkflowServicesManager', SP.Utilities.Utility.getLayoutsPageUrl('SP.WorkflowServices.js'));
        SP.SOD.loadMultiple(['SP.ClientContext', 'SP.WorkflowServices.WorkflowServicesManager'], function () {
            var context = SP.ClientContext.get_current();
            var web = context.get_web();
            var servicesManager = SP.WorkflowServices.WorkflowServicesManager.newObject(context, web);
            var instanceService = servicesManager.getWorkflowInstanceService();
        });
    }, "sp.js");
}, "sp.runtime.js");

Elaborating more on Vadim solution:

function retrieveWebSite() {
       SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function(){
            var clientContext = new SP.ClientContext.get_current();
            this.oWebsite = clientContext.get_web();
            clientContext.load(this.oWebsite);

        clientContext.executeQueryAsync(
           Function.createDelegate(this, this.onQuerySucceeded), 
           Function.createDelegate(this, this.onQueryFailed)
        );
   });
}

 function onQuerySucceeded(sender, args) {
     alert('Title: ' + this.oWebsite.get_title() + 
    ' Description: ' + this.oWebsite.get_description());
 } 

function onQueryFailed(sender, args) {
     alert('Request failed. ' + args.get_message() + 
    '\n' + args.get_stackTrace());
 }

In HTML

 <input type="button" onclick="retrieveWebSite()" value="Click"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top