R – Cascading list boxes, with multi-select

sharepoint

I wound up modifying the source from a publically posted POC: http://datacogs.com/datablogs/archive/2007/08/26/641.aspx, which is a custom field definition for cascading drop downs. The modifications were to allow parent-child list boxes where a user can multiselect for filtering and selecting the values to be written back to a SharePoint list. I got the parent-child cascading behavior working, but the save operation only takes the first value that is selected from the list box. I changed the base type for the custom field control from "SPFieldText" to "SPMultiLineText", along with changing the FLD_TYPES field definition values from:
Text to Note and this did not work. So, I changed the field control base type to "SPFieldMultiChoice" and the FLD_TYPES to "MultiChoice" and still get the same result, which is only the first value that's selected, writing to the SharePoint list.

Does anyone have any idea how to get a custom field with multiple selections to write those multiple selections to a SharePoint list?

Thanks for taking the time to read through my post.

Cheers,
~Peter

Best Answer

I was able to accomplish this by inheriting from SPFieldLookup and overriding its internal handling of AllowMultipleValues:

  1. In your FLDTYPES_*.xml set <ParentType>LookupMulti</ParentType>

  2. In your extension of SPFieldLookup, be sure to override AllowMultipleValues (always true), FieldValueType (probably typeof(SPFieldLookupValueCollection)) and FieldRenderingControl. I also set base.LookupField = "LinkTitleNoMenu", though in retrospect I'm not sure why. :)

  3. In your field editor control's OnSaveChange(), set the field's Mult value to true.

To set Mult, you can either string manipulation on field.SchemaXml:

string s = field.SchemaXml;
if (s.IndexOf(" Mult=", StringComparison.OrdinalIgnoreCase) < 0)
    field.SchemaXml = s.Insert(s.IndexOf("/>", StringComparison.Ordinal), " Mult=\"TRUE\" ");

Or use reflection:

    var type = field.GetType();
    var mi = type.GetMethod("SetFieldBoolValue", BindingFlags.Instance | BindingFlags.NonPublic);
    mi.Invoke(field, new object[] { "Mult", true });

It's been a while, so I might be forgetting something, but that should be most of it.

Related Topic