“Hack attack” jQuery in a list view

9 July 2012 Leave a comment

Useful jQuery snippet to add a “View Properties” icon, so the user doesn’t have to use context menu or ribbon (apparently they prefer this)


$(".ms-listviewtable > tbody > tr:first").append("<TH class='ms-vh2 ms-vh2-icon' noWrap>View</TH>");
  
  $(".ms-listviewtable > tbody > tr").each(function() {
  
    if ($('td:first', $(this)).hasClass("ms-vb-title"))
    {
     var id = $("td.ms-vb-title > div.ms-vb", $(this)).attr("id");
     var viewLink = $("<td class='ms-vb-icon'><IMG style='CURSOR:hand; BORDER-RIGHT-WIDTH: 0px; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px' title='View Properties' alt=Search src='/_layouts/images/gosearch15.png' /></td>");      
     $(this).append(viewLink);
  
     viewLink.click(function(event){
         
      var options = {
       url: "/MyLibrary/Forms/DispForm.aspx?ID=" + id,
       title: "Document Properties",
       allowMaximize: true,
       showClose: true,
       dialogReturnValueCallback: function(dialogResult, returnValue) { }
      };
      
      SP.UI.ModalDialog.showModalDialog(options);
     });
    }
  });

This just adds an extra column to the end with an icon that opens the ‘View Properties’ dialog.

You can either use a Content Editor web part to make it view specific or add it to a global script for all views.
It’s a little hacky, but does the job.

It relies on the title column being available to extract the id of the item.

Advertisements
Categories: Code Tags: ,

RunAs method for running code in specific user SPServiceContext

25 October 2011 Leave a comment

You may have the need to run some code in a SPServiceContext of a specific user. e.g. when dealing with user profiles or activities.

This can be achieved by using a combination of the SPUser, WindowsIdentity, GenericPrincipal and the GetContext method of SPServiceContext.

From these we can set the HttpContext.Current.User property to the specified user.

Don’t forget to set the context back after the code has executed!

Below is a helper method that makes this very easy.

I haven’t done any solid testing on performance etc. so the usual caveats apply.


// Example calling code

RunAs("http://asharepointsite", "THEDOMAIN\THEUSER", c =>
{
    // The code to execute. e.g. get a the UserProfileManager as the passed in user
    var upm = new UserProfileManager(c, true);

    // Do some stuff to the UPM as the passed in user
});

// Helper method

private static void RunAs(string siteUrl, string userName, Action<SPServiceContext> contextToUse)
{
    try
    {
        var currentSetting = false;
        var currentHttpContext = HttpContext.Current;
        SPUser currentUser = null;

        if (SPContext.Current != null)
        {
            if (SPContext.Current.Web != null)
            {
                currentUser = SPContext.Current.Web.CurrentUser;
            }
        }

        SPSecurity.RunWithElevatedPrivileges(delegate
        {
            using (var site = new SPSite(siteUrl))
            {
                using (var web = site.OpenWeb())
                {
                    try
                    {
                        var user = web.EnsureUser(userName);

                        currentSetting = web.AllowUnsafeUpdates;
                        web.AllowUnsafeUpdates = true;

                        var request = new HttpRequest("", web.Url, "");

                        HttpContext.Current = new HttpContext(request,
                                                                new HttpResponse(
                                                                    new StringWriter(CultureInfo.CurrentCulture)));

                        HttpContext.Current.Items["HttpHandlerSPWeb"] = web;

                        var wi = WindowsIdentity.GetCurrent();

                        var newfield = typeof (WindowsIdentity).GetField("m_name",
                                                                            BindingFlags.NonPublic |
                                                                            BindingFlags.Instance);

                        if (newfield != null) newfield.SetValue(wi, user.LoginName);

                        if (wi != null) HttpContext.Current.User = new GenericPrincipal(wi, new string[0]);

                        var elevatedContext = SPServiceContext.GetContext(HttpContext.Current);

                        contextToUse(elevatedContext);

                        //Set the HTTPContext back to "normal"
                        HttpContext.Current = currentHttpContext;

                        if (currentUser != null)
                        {
                            var winId = WindowsIdentity.GetCurrent();

                            var oldField = typeof (WindowsIdentity).GetField("m_name",
                                                                                BindingFlags.NonPublic |
                                                                                BindingFlags.Instance);

                            if (oldField != null) oldField.SetValue(winId, currentUser.LoginName);

                            if (winId != null)
                                HttpContext.Current.User = new GenericPrincipal(winId, new string[0]);
                        }
                    }
                    catch (Exception ex)
                    {
                        // Log or whatever
                    }
                    finally
                    {
                        web.AllowUnsafeUpdates = currentSetting;
                    }
                }
            }
        });

    }
    catch (Exception exO)
    {
        // Log or whatever
    }
}

Fun and games with the ActivityEvent

14 March 2011 2 comments

I haven’t seen a massive amount of documentation on MSDN or other posts about this, so I thought I would write a small note.

This details a way of extracting the info you see in the news feed on your ‘My Site’

First of all you need to get the the format used by the ActivityEvent, this done using ActivityType and ActivityTemplate.


ActivityType type = activityMan.ActivityTypes[activity.ActivityEventId];
ActivityTemplate template = type.ActivityTemplates[ActivityTemplatesCollection.CreateKey(false)];
string format = GetResourceString(template.TitleFormatLocStringResourceFile, template.TitleFormatLocStringName, (uint)CultureInfo.CurrentUICulture.LCID);

The format variable will now contain something along the lines of “{Pubisher} has posted a note {Link} on {PublishDate}”

Now you could at this point take the corresponding Properties in the ActivityEvent, but there is a whole load of formatting that needs to be done. The Publisher Tag needs to be turned into a link to the users profile page and display their name, etc, etc.

There is an easier way, you can use the static methods of the ActivityTemplateVariable.


ActivityTemplateVariable.DateOnlyToString(tag, variable, ContentType.Html, CultureInfo.CurrentCulture);

The problem here is that you have to pass in an ActivityTemplateVariable as one of the parameter and there is no obvious way of doing this.

There are no properties or methods in the ActivityEvent that give you an ActivityTemplateVariable or is there?

After further investigation of the TemplateVariable string property, you can see that this actually returns an XML string. This XML string is a de-serialised ActivityTemplateVariable object.


var variable = (ActivityTemplateVariable)FromXml(item.TemplateVariable, typeof(ActivityTemplateVariable));

You can now use this object to pass to the static method of ActivityTemplateVariable to return the full HTML representation of the tag.

If you then combine that with SimpleTemplateFormat you can then loop round all the tags and replace them.


var items = SimpleTemplateFormat.SimpleParse(formatToUse);

I’ll try and upload a code sample soon.

Add you support for a SharePoint Overflow Q&A site

1 March 2011 Leave a comment

Please follow this link and show your commitment to a new SharePoint Overflow Q&A site.

http://area51.stackexchange.com/proposals/28921/sharepoint-overflow?referrer=1TGRHFSrtrcnXLaDPCj7kA2

 

Categories: Uncategorized

Finding the SMTP server address through code in SharePoint 2010

13 February 2011 Leave a comment

If anyone knows a better way then let me know.

string smtp = string.Empty;

SPFarm.Local.Servers.ForEach(s => s.ServiceInstances.ForEach(i =>
{
if (i is SPOutboundMailServiceInstance)
{
smtp = s.Address;
}
}));

return smtp;

I use a ForEach extension which I’ve included below

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)

{

foreach (T item in enumerable)

{

action(item);

}

}

Dilbert on SharePoint (via SharePoint Tech Blog)

17 November 2010 Leave a comment

Very true

Dilbert on SharePoint

via SharePoint Tech Blog

Categories: Uncategorized Tags:

The hidden User Information List and the Email field

4 November 2010 Leave a comment

More of a reminder to myself.

The internal name for Email in the hidden User Information list is EMail and not Email.

I came across this when doing a SiteDataQuery on this list and using rather than

The email was never returned in the DataTable.

Categories: Uncategorized Tags: