2

I have a requirement to expose a list item's ID value on the "DispForm.aspx" form and all alert emails for a particular list.

SharePoint is very "protective" of its IDs (or counter fields) and it doesn't allow you to make them visible on the display and edit forms. To circumvent this, I have deployed a feature which does the following:

  • Adds a new number field/column to my list called "Issue ID", and
  • Adds an event receiver to my list which simply traps the ItemAdded event and copies the built-in "ID" value to my new "Issue ID" field each time a new list item is created

    public override void ItemAdded(SPItemEventProperties properties)
    {
        properties.ListItem["Issue ID"] = properties.ListItem["ID"];
        properties.ListItem.SystemUpdate();
    }
    

The idea here is to create a copy of the built-in ID field (which SharePoint forceably hides on the forms and email alerts) and display the new field instead. This all works great except that my "Issue ID" field appears blank in the email that gets generated when an item is first created. This is because the email is generated before my event receiver's ItemAdded event is executed. When an item is edited or deleted, the "Issue ID" is correct.

Does anyone know how I can programmatically set a list item's field value BEFORE the list's alert email is generated?

2 Answers 2

1

Maybe instead of using the ItemAdded event, you could try using the ItemAdding event?
Example

What you also could do is create a workflow on the listitem that activates when the item changed. First check if the "Issue ID" is not empty. If so, than send an email to a group. To let users subscribe to an "alert", I would create a webcontrol where users are added to the group mentioned above when they click the subscribe button.

0

Sadly, I didn't find an actual solution to this problem (and I didn't want to replace the OOTB email alerting system with a custom workflow that sends an email etc) so we resigned to the fact that the "Issue ID" would not be dislayed in the initial alert email that gets sent whern an item is first added to the list.

For those playing at home, here was my final code solution do displaying the ID value of each item in the list's display and edit forms:

Base Setup:

NB: These steps were all performed programmatically in my feature receiver

  • I added a new field to my list called "Issue ID" with the following properties:

    DisplayName="Issue ID"
    Type="Number"
    Decimals="0"
    ShowInDisplayForm="TRUE"
    ShowInEditForm="FALSE"
    ShowInNewForm="FALSE"
    ShowInViewForms="TRUE"
    ShowInFileDlg="FALSE"
    ShowInListSettings="TRUE"
    
  • I pre-set all the "Issue ID" of all my existing list items

  • I added my new "Issue ID" column to all my list views

Display Form Fix:

  • I attached an event receiver to my list
  • I trapped the ItemAdded event and used it to copy the built-in "ID" value to my custom "Issue ID" field

    public override void ItemAdded(SPItemEventProperties properties)
    {
        base.DisableEventFiring();
        properties.ListItem["Issue ID"] = properties.ListItem["ID"];
        properties.ListItem.SystemUpdate(false);
        base.EnableEventFiring();
    }
    

Edit Form Fix:

NB: This step was performed programmatically in my feature receiver

  • I added a Content Editor Web Part to the edit form with the following JavaScript:

    SPFile file = web.GetFile(list.Forms[PAGETYPE.PAGE_EDITFORM].Url);
    
    using (SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared))
    {
        ContentEditorWebPart contentEditorWebPart = webPartManager.WebParts.Cast<WebPart>().FirstOrDefault(webPart => Equals(webPart.Title, "Issue ID JavaScript")) as ContentEditorWebPart;
    
        if (contentEditorWebPart == null)
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlElement xmlElement = xmlDocument.CreateElement("Root");
            xmlElement.InnerText = @"
                <script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js' charset='utf-8'></script> 
    
                <script type='text/javascript'>
                    $(function() {
                        var id = GetQueryString()['ID'];
                        var table = $('table.ms-formtable');
    
                        table.prepend('<tr><td class=""ms-formlabel""><h3 class=""ms-standardheader"">RFC ID</h3></td>' + '<td class=""ms-formbody"">' + id + '&nbsp;</td></tr>');
                    })
    
                    function GetQueryString() {
                        var assoc = new Array();
                        var queryString = unescape(location.search.substring(1));
                        var keyValues = queryString.split('&');
    
                        for (var i in keyValues) {
                            var key = keyValues[i].split('=');
                            assoc[key[0]] = key[1];
                        }
    
                        return assoc;
                    }
                </script>";
    
            contentEditorWebPart = new ContentEditorWebPart();
            contentEditorWebPart.Content = xmlElement;
            contentEditorWebPart.Hidden = true;
            contentEditorWebPart.Title = "Issue ID JavaScript";
            contentEditorWebPart.ZoneID = "Main";
    
            webPartManager.AddWebPart(contentEditorWebPart, contentEditorWebPart.ZoneID, 0);
            web.Update();
        }
    }
    

It's failry self-explanatory, however the display form will happily display your custom field for you (provided you set the ShowInDisplayForm="TRUE" in your field definition).

The edit form needs a hack. I placed a CEWP on the edit form and used some JavaScript to retrieve the ID from the querystring and inject it into the HTML.

1
  • Did you ever try Ruben's suggestion to use ItemAdding instead of ItemAdded? I'm interested to find out where in that whole process the alerts are sent out.
    – Nacht
    Commented Aug 7, 2014 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.