8

ANSWERED! See bottom of original question for the working answer.

I'm trying to find out how I can run a piece of JavaScript code the moment a list item gets deleted. So it should be some sort of script that runs on the page, and triggers when a user deletes an item from a list.

For example, this dummy code should somewhat tell you what I mean:

function doThisOnDelete() {
  if (action == delete) {
    alert('You just deleted a list item.');
  }
  else {
    do nothing
  }
} 

So on the line with "(action == delete)", it should be something that detect if a list item gets deleted.

Is there a way to check when a method is called (like the one that deletes list items)? And how can I find out what the name of that method would be?

My goal is to return to the previous page when an item gets deleted, or to prevent the page from going to the list and leave the page with the custom list view.

Any help is greatly appreciated!

Alternatively, I'm also open to the idea of using custom JavaScript code to delete a list item (based on the paragraph titled "Delete a file in a document library" from the MSDN site).
If I can manage to use a custom delete script in JavaScript, then I can perhaps prevent the user from automatically being redirected. If this is possible, then any suggestions and/or tips regarding this are welcome as well!

ANSWER

Inspired by Ecanem's answer, I wrote the following code. Against my expectations, it ended up being rather simple and short.

var ref = document.referrer;            // Stores the URL of the previous page.
var url = window.location.pathname;     // Stores the URL of the current page.

// The following code will run if the user edits a list item or properties of a document.
if (url.indexOf('EditForm.aspx') > -1) {
    sessionStorage.setItem("page", ref);
}

if (url.indexOf('AllItems.aspx') > -1 && ref.indexOf('EditForm.aspx') > -1) {
    window.location = sessionStorage.getItem("page");
}

It works like this: first we see if the current URL is "EditForm.aspx". If it is not, do nothing. If it is, then we save the URL of the previous page in the session.
If the URL of the current page is "AllItems.aspx" and the previous page was "EditForm.aspx", then this means that an item or document was deleted from the list or library by the user.

Since we want to prevent users from seeing the "AllItems.aspx" page and let them stay on the page with the list/library view, we will redirect them to the page we stored in the session.

The redirection is smooth and almost unnoticeable; the URL for "AllItems.aspx" may be present in the browser address bar for a short moment, but most users won't focus on the address bar and won't even know they have been redirected back to the original page.

There is, however, a very small issue.
When you log something to the console while using this code, you may get an error saying "Uncaught ReferenceError: Type is not defined" and then you won't be able to redirect back to the proper page (in my case, it ended up redirecting to a completely different page). But as long as you don't include "console.log();" in the code, you'll be just fine!

I also added the answer to my blog, you can find the post here.

8
  • You can take pointers from this Basic operations using JS.
    – Amit
    Nov 19, 2013 at 13:17
  • Best bet would be to replace the functionality entirely, unr-egister the control and readd a custom one which performs the deletion and removal from the item in page without causing a page refresh. In page there are at least 4 methods that call deletion, and 2 methods of registering, the last 2 are _doPostBack commands.
    – Hugh Wood
    Dec 12, 2013 at 11:50
  • Try taking a look at WebSockets. It allows RealTime communication between Client and Server. Hook it up on an event receiver and you should be good to go. I haven't done this myself, but have seen it in action before.
    – user2536
    Dec 12, 2013 at 14:22
  • I don't completely understand the scope of your problem as you haven't given enough details. For example, there are at least 4 different places an item can be deleted from in the browser -- in-place on the list view, in the ribbon on the list view, in the ribbon on the edit view and in the ribbon on the 'view item' view. Are you trying to impact all of these scenarios, or only impact the delete event on your particular custom list view?
    – tyshock
    Dec 12, 2013 at 20:14
  • 1
    Check the DeleteDocLibItem javascript method in OWS.debug.js or CORE.debug.js. It will be hard to override such postback with javascript.
    – ppatalong
    Dec 12, 2013 at 21:46

4 Answers 4

5
+50

So let's go with your first request.

You want a piece of code to run when a list item is deleted from a list but it has to be 100% javascript and there can't be any page postbacks.

Obviously we must assume the page is going to stay open the entire time.

You are left with using web services or CSOM to achieve this. My recommendation would be to use the Lists web service, all three options are going to rely on putting your function within a javascript setInterval of some period. This setInterval will call the web service on this interval you decide to look for changes.

  1. Use the standard getListItems webservice with an array of ID's. On each function run, compare the old array to the new to see if there is an ID missing, that is the item that was deleted.
  2. Use GetListItemChangesSinceToken, on your first and every subsequent call. This will give you the changes that occurred since the token was sent. A bonus of this function is you could store the token as a cookie and thus when the user came back to the page they could see the changes that occurred since they were last on the page.
  3. Use GetListItemChanges. This is similar to the above but you are defining the time in which you want to receive the changes from.

As mentioned, for all of these, you would need to wrap them in a setInterval function and I would likely use SPServices to make the calls.

2
  • I find your answer very useful, I do indeed need code that is 100% JavaScript. I'm just going to try out all three options and see which one suits me best. Thank you!
    – Magali
    Dec 20, 2013 at 8:43
  • Inspired by your second option, I was searching for information about cookies and came across "session storage". Using this, I managed to check if a user had deleted something by seeing if the previous URL was "EditForm.aspx" and if the current URL was "AllItems.aspx". If that condition was true, then it would mean the user deleted something, in which case I could redirect the user to the URL stored in the session.
    – Magali
    Dec 20, 2013 at 11:18
3

If you are using SharePoint 2013 you can use the client api and register event receivers remotely. E.g. SPRemoteItemEventProperties (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.eventreceivers.spremoteitemeventproperties.aspx). You can even use this api with your embedded javascript.

For SharePoint 2010 jQuery may help you to fiddle with changing standard behavior.

2
  • 1
    Looks nice! But this answer could be even better if you provided a code example of how to implement the OnDeletedItem() JavaScript function.
    – Benny Skogberg
    Dec 12, 2013 at 20:56
  • 1
    A code example would indeed be nice.
    – Magali
    Dec 16, 2013 at 15:23
0

within your item deleted event reciver you can call the JS script. or better yet, all you seem todo is show that they have deleted an item? and then redirect back to previous page!

iv done somthing similar! but fully coded, including the creation of the list. once iv created the list i added a webpart that i created... it pure function is to simply redirect back to previous page:

public class httpRedirectHome : WebPart
{
    protected override void CreateChildControls()
    {
    }

    protected override void OnInit(EventArgs e)
    {

        changeRedirection(Page.Session["PreviousPageUrl"].ToString());
        base.OnInit(e);
    }

    private void changeRedirection(string url)
    {
        if (Page.Session["PreviousPageUrl"] != null)
        {
            Page.Response.Redirect(url);
        }
    }
}

I added that webpart to any list that i want to redirect back after any operation!

say for instance I Have a custom page, on the page load i would add the following:

Page.Session["PreviousPageUrl"] = SPContext.Current.Site.Url + "/mysite";

so on the page load the session varible that stores the url is saving the site to redirect when i navigate to the list!

going to the list iv deleted an item it will then redirect me back to the save url!

its basic and very simple but it works like a charm! You can still have a popup box to display on the custome page that an item has been deleted! todo this i would do:

public class httpRedirectHome : WebPart
{
    protected override void CreateChildControls()
    {
    }

    protected override void OnInit(EventArgs e)
    {

        changeRedirection(Page.Session["PreviousPageUrl"].ToString());
        base.OnInit(e);
    }

    private void changeRedirection(string url)
    {
        if (Page.Session["PreviousPageUrl"] != null)
        {
            Page.Response.Redirect(url);
            Page.Session["ItemDeleted"] = "true";
        }
    }
}

NOTE

in your case the code above does not need to be within a webpart, rather it would go within the item deleted event to redirect like so:

   public override void ItemDeleted(SPItemEventProperties properties)
   {
       base.ItemDeleted(properties);
       changeRedirection(Page.Session["PreviousPageUrl"].ToString());
   }

    private void changeRedirection(string url)
    {
        if (Page.Session["PreviousPageUrl"] != null)
        {
            Page.Response.Redirect(url);
            Page.Session["ItemDeleted"] = "true";
        }
    }

now to change the custom page to show the user that an item has been deleted after the redirect:

Page.Session["PreviousPageUrl"] = SPContext.Current.Site.Url + "/mysite";

if(Page.Session["ItemDeleted"] == "true")
{
     ClientScript.RegisterStartupScript(this.GetType(),"", "$(document).ready(function(){alert('You just deleted a list item.')});", true); 
}

there are many other ways of going about it, this is a simple method and works! so what would the user experience?

well when they delete an item it will reload the page sending you to the page that you came from or what ever the url you save and it will display a message indicating that an item was deleted.

3
  • While I fully understand the logic of your answer and your code, I can only program in Javascript. I'll try to see if I can achieve the same using Javascript, based on your code. Will bring news after the weekend.
    – Magali
    Dec 13, 2013 at 14:54
  • how come you can only do it within js?
    – Ali Jafer
    Dec 13, 2013 at 15:11
  • I have little knowledge of MS Visual Studio and C#, hence I wanted to do this in JS first. I do however plan on learning C# and then convert all my existing scripts to C# so that everything will run server-side rather than client-side, but that will be for in a few months. :(
    – Magali
    Dec 16, 2013 at 10:59
0

I have done this kind of "hackery" before. I would recommend doing this only after all other options have failed. Here are the basic steps:

1) Include the JavaScript (which you want to load when the item gets deleted) in a js file. Lets call this FireOnDelete.js

2) Create a Module and using CustomActions and the ScriptLink attribute, include FireOnDelete.js in it. Here is how to do that: http://blog.voyta.net/2010/09/12/referencing-javascript-files-using-customaction-in-sharepoint-2010-sandboxed-solutions/

3) Create a Web level Feature and include the previously created module inside it. Do not activate this feature by default.

4) On your list, put an ItemDeleted event receiver and inside that, programmatically activate the feature which we created in step 3.

5) In FireOnDelete.js itself, you can write JSOM code to deactivate the feature so that the script will load on the page only once.

So the Flow will be:

Item Gets Deleted -> ItemDeleted EventReceiver fired -> Feature is Activated -> JavaScript is loaded on the page -> JS code is executed -> JS code deactivates feature using JSOM -> JS is not loaded on other pages.

1
  • 1
    -1 This would fire a post back which isn't desired
    – Hugh Wood
    Dec 17, 2013 at 2:34

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.