People Picker customization in SharePoint 2010

If you are still stuck in 2010 land, this might help you. In one of my recent projects I had to customize the out of box people picker (multi user) in a custom visual web part  and the old faithful jQuery helped me out.

The requirement was to change the people picker from this :

To this:

The list of changes is really simple :

  1. Hide the image  .
  2. Move the browse image  above the text box.
  3. Add help text before the browse image  .

To start with, here is the  high level html structure which is rendered by the SharePoint for a multi user people picker :

<SPAN ....>
 <TABLE class=ms-usereditor ....>
 <TBODY>
 <TR>//TextBox</TR>
 <TR>//Row to display errors</TR>
 <TR>//Row with buttons </TR>
 </TBODY>
 </TABLE>
</SPAN>

I have removed all the metadata to highlight the structure. You can also access the complete structure here.

Also, if you have not looked at the complete structure, here is the highlight from the row with buttons to look at how the images are being rendered.

Once you have gone through the structure, you will realize that  hiding the check names image is easy as it can be selected by the img title tag and then hidden by jQuery.

 <1> $("img[title='Check Names']").hide();

Remember to limit the selector’s range by providing the div/table id which will contain the people picker to be changed as the script above will hide all images with title of ‘Check Names’ on the page.

For our second requirement, adding the text is also straight forward as SharePoint adds an empty cell before the check names and browse buttons, with a span. We can update the text in the span with our required help text and apply the CSS we want.

<1> var row = $("img[title='Check Names']").
closest('tr');
<2> row.find('td:first').find('span').
text('<Custom Text>');
<3> row.find('td:first').find('span').
addClass('<Custom CSS Class>');

For our third requirement, we need to move the last row containing buttons to the top of the text box i.e. move the last row to the top.

What we have currently have from the above script is a row object which is in a nested table in the last row. So the first task of action is to get the parent row object to work on, which can be done via:

 <1> var topRow = $(row).parentsUntil('tr');
 <2> topRow = topRow[topRow.length - 1];
 <3> topRow = $(topRow);
 <4> topRow = $(topRow.parent());

In the above script, the first line gets all the objects till the top level row (which will be TD since parentsUntil  only gets the objects till the parent without including the parent), line 2 gets the top object of this collection and then in line 3 we cast the object as a jQuery object. In line 4 we get the parent of the cell which is the row we need to push to top of the parent table.

Now we move this row to the top using :

topRow.prev().prev().before(topRow);

This will select the two previous objects (Row 2 and then Row 1) and move the row before the first row in the table.

The final structure changes to this:

<SPAN ....>
 <TABLE class=ms-usereditor ....>
 <TBODY>
 <TR>//Row with buttons</TR>
 <TR>//TextBox</TR>
 <TR>//Error Row</TR>
 </TBODY>
 </TABLE>
</SPAN>

You can download the complete script here : peoplepicker2010.js

Set Development Databases to Simple Recovery

If you develop SharePoint Solutions and have SharePoint installed in your development environment then this script will come in real handy to you.

This script uses a cursor and sets all non system databases to simple recovery. This will help you in terms of performance as it reduces the number of disk writes by SQL along with that you will not face the problem of SQL logs filling your hard drive.

USE MASTER
declare
@cmd varchar(2000),
@dbname varchar(64),
@logfile varchar(128)

declare c1 cursor for 
	SELECT  d.name, mf.name as logfile
	FROM sys.master_files mf
		inner join sys.databases d
		on mf.database_id = d.database_id
	where recovery_model_desc <> 'SIMPLE'
		and d.name not in ('master','model','msdb','tempdb') 
		and mf.type_desc = 'LOG'	
		
open c1
	fetch next from c1 into @dbname, @logfile
		While @@fetch_status <> -1
		begin
			select @cmd = 'ALTER DATABASE [' + @dbname + '] SET RECOVERY SIMPLE'
			exec(@cmd)
			select @cmd='USE [' + @dbname + '] checkpoint'
			exec(@cmd)
			select @cmd='USE [' + @dbname + '] DBCC SHRINKFILE ([' + @logfile + '], 1)'
			exec(@cmd)
			fetch next from c1 into @dbname, @logfile
		end
close c1
deallocate c1

You can also download the script here: SETDBSIMPLE