April 30, 2013

Custom values on Choice column - Part 1

Couple of weeks ago I was playing around with SharePoint columns, and thought it would be nice to have a custom set of choices to show always when we create a choice column in SharePoint 2010.


Out of The Box functionality:
In SharePoint 2010, go to any list/library, and click 'Create Column' button. When you select a choice column then 3 dummy choice items will display initially ('Enter Choice #1', 'Enter Choice #2' and 'Enter Choice #3'). If you delete these and entered your custom list of items instead, you will notice that the default value field shows the first item value automatically.

My objective is to show useful data each time you create a choice column across your SharePoint farm. Examples could be: numbers from 1 to 10, or list of all months, or just a bunch of names..and the custom values can be static, calculated or coming from a SharePoint list!

I find manipulating SP pages an amusing task, and it is helpful to give you an inside view of how everything works. However, keep in mind that customizing OTB pages is not recommended because all your work can be flushed when patches got installed.
If you do things carefully and you are not going to install any update then continue reading!

First let's have a look on how the choices works in the OTB page.
The page we just saw in column creation is: 'FldNew.aspx' and you can find it in _Layouts folder.
Hit F12 key to view the JavaScript code. If you select the arrow icon and click on the box that shows the three dummy values then we can get to the control and its id is 'idChoices' as follows:

<tr>
                <td colspan="2"></td>
                <td class="ms-authoringcontrols">&#160;</td>
                    <td class="ms-authoringcontrols" id="onetidEnterChoice"><label for="idChoices">Type each choice on a separate line</label>:<font size="3">&#160;</font><br />
                        <table border="0" cellspacing="1">
                                <tr>
                                        <td>
<textarea class="ms-input" name="Choices" id="idChoices" rows="4" cols="40" wrap="off"  onchange="clearOutDefaultWithCheck()" >
Enter Choice #1
Enter Choice #2
Enter Choice #3
</textarea>
                                        </td>
                                </tr>
                        </table>
                </td>
</tr>

The default value control has the id:'onetidIODefChoiceValue'. This is how it works:
Initial value is 'Enter Choice #1'. When user edits and put custom choices, the method clearOutDefaultWithCheck() triggers and will call the other method clearOutDefault() when Calculated Value radio button was not selected. Method clearOutDefault() will set the first choice as the value of the text box of the Choice radio button.



Let's switch to Visual Studio and open the 'FldNew.aspx' and search for 'idChoice'. 
Caution: make backup copy for each OTB file before editing.

<tr>
<td colspan="2"></td>
<td class="ms-authoringcontrols">&#160;</td>
<td class="ms-authoringcontrols" id="onetidEnterChoice"><label for="idChoices"> <SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,fldedit_typeeachchoiceonseparate%>" EncodeMethod='HtmlEncode'/></label>:<font size="3">&#160;</font><br />
<table border="0" cellspacing="1">
<tr>
<td>
<textarea class="ms-input" name="Choices" id="idChoices" rows="4" cols="40" wrap="off"  onchange="clearOutDefaultWithCheck()" >
<%
SPHttpUtility.HtmlEncode((string)(this.GetGlobalResourceObject("wss", "fldedit_L_strDefaultChoice_Text")) + "\r\n" + (string)(this.GetGlobalResourceObject("wss", "fldedit_L_strChoice2_Text")) + "\r\n" + 
(string)(this.GetGlobalResourceObject("wss", "fldedit_L_strChoice3_Text")),Response.Output);
%></textarea>
</td>
</tr>
</table>
</td>
</tr>

Yellow portion is the where you need to focus, because this tells us how the control is getting the default values. This is an inline C# code that reads static text strings from a resource file using GetGlobalResourceObject() and encode the combined text string to be displayed within the control.
The method GetGlobalResourceObject() reads the a string value of a resource key stored in Resources file named 'wss'. The actual resource file name is 'wss.en-US.resx'. This is an ASP.NET application level resources file and available in the App_GlobalResources directory for every web application in SharePoint. 
For example: for my web application that resides on default port 80, the file path is:
C:\inetpub\wwwroot\wss\VirtualDirectories\80\App_GlobalResources\wss.en-US.resx

For idChoice control the keys are: "fldedit_L_strDefaultChoice_Text", "fldedit_L_strChoice2_Text" and  "fldedit_L_strChoice3_Text".
And for the the onetidIODefChoiceValue control the key is: "fldedit_L_strDefaultChoice_Text".

You can open this wss.en-US.resx file by notepad or Visual Studio. Search for the keys, and you will find the default choice values!



Now we finished understanding what's going on...the following article (Part 2) is about setting our desired custom choice values!