Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

If you use SP.UI.ModalDialog.showModalDialog to show a Lists standard EditForm.aspx the callback (dialogReturnCallback) is hit for cancels and edits but not deletes which are instead redirected to the list view (AllItems.apx) via a 302.

How can I stop deletes via EditForm.aspx getting 302 redirected?

Example javascript (itemId is ID of record you're editing)

var options = {};
options.url = "/YOUR_SITE/Lists/YOUR_LIST/EditForm.aspx";
// If we don't append ?ID=X onto end of url then won't have context of edited record
// so won't enabled ribbon Edit button and a save will throw 500 server error    
options.url = options.url + "?ID=" + itemId;

options.dialogReturnValueCallback =
           function (dialogResult, returnValue) {
                  // Cancels and Saves will get here, Deletes will not,
                  // page redirected to standard list view (AllItems.aspx)
                  // via a 302 redirect.
                  console.log("dialogResult=" + dialogResult +
                              " returnValue=" + returnValue);
              }
SP.UI.ModalDialog.showModalDialog(options);
share|improve this question

2 Answers 2

up vote 2 down vote accepted

I'm afraid it is a standard behavior and there is no setting out there to change this.

But I can propose a workaround...

When the ribbon Delete button is pressed on a list form, SharePoint requests user confirmation, and then performs postback. Thus, redirection happens server-side and nothing could be changed here.

However, nothing prevents you from deleting the item client-side (using client object model), and then you can just close the dialog using either SP.UI.ModalDialog.commandModalDialogClose method or window.frameElement.commitPopup shortcut.

The code will look something like this:

if (!confirm("Are you sure want to delete this item?")) return;
var context = new SP.ClientContext.get_current();
var list = context.get_web().get_lists().getByTitle(listTitle);
var item = list.getItemById(parseInt(GetUrlKeyValue("ID")));
item.recycle();
if (GetUrlKeyValue("IsDlg") != "1")
  context.load(list);
context.executeQueryAsync(
    function()
    {
        if (GetUrlKeyValue("IsDlg") == "1")
        {
            window.frameElement.commitPopup("item deleted");
        }
        else
        {
            document.location.href=list.get_defaultViewUrl();
        }
    },
    function(sender,args) {alert('Error! ' + args.get_message());});

To make this code work, of course you will need to replace standard Delete button with your own custom one, which will look alike, but will act differently.

You will need to perform this operation for all list forms. Initial button definitions can be grabbed from the 14\TEMPLATE\GLOBAL\XML\CMDUI.XML file.

For example, standard definition of Delete button on Display form is presented below:

<Button
   Id="Ribbon.ListForm.Display.Manage.DeleteItem"
   Sequence="50"
   Command="Ribbon.ListForm.Display.Manage.DeleteItem"
   Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-112" Image16by16Left="-224"
   Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="-128" Image32by32Left="-128"
   LabelText="$Resources:core,cui_ButDeleteItem;"
   ToolTipTitle="$Resources:core,cui_ButDeleteItem;"
   ToolTipDescription="$Resources:core,cui_STT_ButListFormDeleteItem;"
   TemplateAlias="o2"/>

Obviously, you need to change Id and Command attributes here, providing your own identifiers.

Then, wrap this code into CommandUIDefinition element, setting Location attribute to original ID value:

<CommandUIDefinition Location="Ribbon.ListForm.Display.Manage.DeleteItem">
    <Button
       Id="Ribbon.Ryan.DeleteItem"
       Sequence="50"
       Command="Ribbon.Ryan.DeleteItem"
       ...
    />
</CommandUIDefinition>

Repeat the trick for Edit form, and then wrap these CommandUIDefinition elements into proper CustomAction code, and of course do not forget to provide command handler for the "Ribbon.Ryan.DeleteItem" command and put the code presented above there :)

For details of how ribbon customizations are performed, and for examples of custom action code, you can examine the following MSDN how-to:

(Location attribute of the CustomAction element should be set to "CommandUI.Ribbon", to apply the customization to all list forms).

share|improve this answer
    
Outstanding again, cheers. Unfortunately isn't going to work for this project (sprello.codeplex.com) as can't be modifying existing lists for the sake of my web part. –  Ryan Feb 6 '12 at 8:35
    
you can deploy this customization for all lists, and then pass a parameter and by existance of this parameter you can determine if you need to use custom code or just call the original postback. –  Andrey Markeev Feb 6 '12 at 8:38

If you need to modify OOTB JS behavior without actually editting the SHarePoint JS files the jquery.aop plugin. It allows for adding before and after (and a few more) "aspects" (function calls) to another function, without actually having to rewrite that other function.

share|improve this answer
    
very interesting plugin, thank you. –  Kai Feb 6 '12 at 15:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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