Monday, August 10, 2009

Programmatically working with SharePoint list choice fields

SharePoint Fields, Columns and ListItems can get confusing at first glance, adding a choice field to the mix doesn't help things at all.

First, a quick note on nomenclature. Generally, when someone refers to a SharePoint "field", they're referring to the value of a field in a ListItem.
For example, when I say that I am checking the value of the Id field of a ListItem, I am referring to the value of the field which is an integer unique to that ListItem in that list.

When someone refers to a "column" they're referring to the definition of the field, i.e. the object that you can use to define the type of the column, the name of the column, the ID of the column, among many other values. Site columns are columns that are defined at the site or site collection level that can be used in any list. The values of the fields the columns they represent can be different, but the basic definition of the columns are the same.
So if I want to get the value of the Id of a choice site column, I'm referring to the Unique identifier that identifies the column, not a value of the field in a ListItem.

Adding to the confusion is that the class that you use to get and set column specific properties are all named "Fields" (like SPFieldChoice). More on this later.

What if you want to have a choice site column that is the same in all respects except for different choice values? In your code you will want to get the site column and cast it as an SPFieldChoice object. Once you have an instance of that column you can manipulate the choices in the "Choices" collection, which is basically a generic string array. For example:
//Using will close the web object automatically when I'm done with it.
Using (SPWeb myWeb = SPContext.Current.Web)
{
SPList myList = myWeb.Lists["MyList"]; //Gets a list named "MyList"

//Gets the field named "ChoiceField". Since ChoiceField is an SPFieldChoice I can cast it as
// such. SPFieldChoice also inherits SPField.
SPFieldChoice dropDown = (SPFieldChoice)myList.Fields["ChoiceField"];

dropDown.Choices.Clear(); //Clears out the list of options

//Add some values
dropDown.Choices.Add("a");
dropDown.Choices.Add("b");

dropDown.Update(); //Need to update the column for the changes to take affect
}
So that's how we edit the column. Now how do we get and edit the value of the field that is already stored in a ListItem?

Accessing the value of the field using the traditional ListItem[Field] method will yeild an int32 object whose value is the zero-based index of the selected Choice. To get the value that is selected you will have to use the SPFieldChoice method GetFieldValueAsText(string). You can do this in the following manner:

//Taking the list from the example above,
//lets assume the ListItem has the choice of "b" selected...
int SelectedIndex = myList.Items[0]["ChoiceField"] //will return a value of 1
SPFieldChoice dropDown = (SPFieldChoice) myList.Items[0].Fields["ChoiceField"];

string SelectedValue = dropDown.GetFieldValueAsText(myList["ChoiceField"]);
//SelectedValue will now be equal to "b"
Finally, to set a the value of a Choice field you use the same method as you normally would, bearing in mind that the field type is an integer. If you aren't sure what the field type should be, you could use the GetFieldValue(string) method and send it the text value that you would like the field to be and it will return the Field value that SharePoint Object Model is expecting.

myListItem["ChoiceField"] = 0;

Or

myListItem["ChoiceField"] = myList.Fields["ChoiceField"].GetFieldValue("a");

Both will have the same effect. Don't forget that when you modify the value of a field, call the Update() method of the ListItem or your changes will be lost.

myListItem.Update()...

Snowburnt.Update()

4 comments:

  1. What if I need to update choice field in Issue list, eg. Status field (Choices: started, ..., completed, closed) programatically?
    Let me explain closer: I have the timer job that runs every morning, goes throught all ListItems and checks the value of one field that I use as a flag. If that field has specific value I want to change Status field from completed to closed. How to achieve this?

    ReplyDelete
  2. Maja, for this you'd change the value of the choice field. Like in my last example.

    (make sure you're using the proper constants or enums)
    myListItem["StatusFlagField"] = myList.Fields["StatusFlagField"].GetFieldValue("Closed");
    myListItem.Update();

    ReplyDelete
  3. My current project requires ability to display choice column value via color or image associated with a choice

    But Sharepoint standard packaged misses that control

    I am looking for available solutions on market

    I came across

    http://sharepointfields.com

    Does anybody has experiece using it?

    ReplyDelete
  4. Best way add choice field data to the dropdownlist with required validation
    http://sharepointquicksolutions.blogspot.in/2012/11/spfieldchoice-to-dropdown-list.html

    ReplyDelete