Showing posts with label ContentType. Show all posts
Showing posts with label ContentType. Show all posts

Friday, January 15, 2010

Aggregate the values from an InfoPath repeating section for data administration

A common requirement for setting up (web)forms is to enter multiple rows of similar information. For example, entering the name(s) of your child(ren) for an holiday booking. The InfoPath Repeating Section enables an intuitive usage model for this. Initial the form displays only 1 section for data entrance. Via a link or button the user can on-the-fly expand the form with more occurrences of that same section.
Question is how best to administer the entered data from the repeating section in a SharePoint library. Is this a Master/Slave relationship? Or should it be considered simple as embedded in the form data self? The former requires a relation data model employed within the SharePoint information architecture. Although possible, this is not the typical SharePoint model which is namely to administrate the entity data in a single List or Library. However, for the second alternative it is still required to potentially administrate multiple values per field in the repeating section.
SharePoint supports this via the concept of AggregateFunction at Field level. To collect the data from a repeating section, specify aggregate="merge" for the field within the InfoPath form template
When explicitly self-provision the SiteColumns and ContentType (Administrate data from InfoPath form in a self-provisioned ContentType), you ran into a problem here. The FieldSpecification CAML currently does not allow the Aggregate attribute as in:

<FieldRef
  ID="{5e046132-9284-4322-b1c7-9a742d60270e}"
  Name="FirstNameChild"
  ReadOnly="TRUE"
  Node="/my:myFields/my:group/my:Children/my:FirstNameChild" />

SharePoint will fail the activation of your Feature with the error message: The 'Aggregation' attribute is not allowed.
The remedie is to skip the 'Aggregate' attribute from the CAML specification, and afterwards add it via an EventReceiver to the provisioned SPField in the RootWeb:

  SPField aggregateField = site.RootWeb.Fields[new Guid("{5e046132-9284-4322-b1c7-9a742d60270e}")];
  aggregateField.AggregationFunction = "merge";
  aggregateField.Update();

Wednesday, January 13, 2010

Administrate data from InfoPath form in a self-provisioned ContentType

When registrating via XSNFeatureReceiver an InfoPath Form Template in a SharePoint sitecollection, automatically a ContentType and the associated SiteColumns are provisioned. This ContentType enables promotion of the data entered via the form to a SharePoint library. However, I prefer to apply explicit self-provisioned ContentType and SiteColumns for the data administration. The rationale is to have full control over the created information architecture entities. In the automatic created ContentType, the ID is arbitrary and thus differerent accross (re)deployments and environments. This hampers the content deployment process between environments. And at rolling out an upgrade of the InfoPath form template in the same site collection, a new version of the ContentType is provisioned with potential another ID. The automatic provisioned SiteColumns do not expose this particular problem. Their IDs are namely contained in the InfoPath form template, and therefore remain identical accross (re)deployments. But the SiteColumns have their own issues. Most noticable is a SiteColumn with type (Multi)Lookup. This cannot be correctly provisioned via a CAML FieldSpecification only, but requires a fix afterwards (Creating Lookup columns as a feature). Another problem that both the automatic provisioned SiteColumns and ContentType suffer of, is when there are changes in the definiton while the entity is already in use. To propagate the changes at the sitecollection-defined entities to their usage at List/Library level requires some afterwards fix via custom code.
Because of these issues I prefer to explicit self-provision both the SiteColumns and the ContentType for administrating the forms data. You then control the ID of the ContentType, you can fix the Lookup-relationships for SiteColumns, and you can propagate changes within the ContentType to all List/Libraries which already use the type. It costs some extra development time, but it surely pays off upon repeated full-automic deployments, and accross environments.