Posted by Scott on May 11, 2010
Updated: Click here for an example of how to achieve the same functionality without any code.
The following solution will require a Full Trust form with code, but will allow for a Contact Selector to be placed on a browser-based InfoPath form which will consistently validate, requiring the selection of a user as well as allowing for only one selection.
The code:
public void supervisorEmployeeID_Changed(object sender, XmlEventArgs e)
{
try
{
int supervisorCount = e.Site.SelectChildren(XPathNodeType.Element).Count;
if (this.Errors.GetErrors("_supervisorCountError").Length > 0)
this.Errors.Delete("_supervisorCountError");
if (supervisorCount > 1)
this.Errors.Add(e.Site, "_supervisorCountError", "You can only select one Manager");
else if (supervisorCount < 1)
this.Errors.Add(e.Site, "_supervisorCountError", "You must select a Manager");
}
catch { }
}
The above is meant to serve as a reference and should be self-explanatory.
Posted by Scott on March 17, 2009
I’ve found that working with InfoPath is becoming more and more of a chore. A form I’ve been working on has had its promoted columns changed a number of times (Side note: I would just love to have a defined specification).
Today when I attempted to completely retract my form (inlcuding manually deleting the content type associated with the form), I was presented with the always helpful error “The content type is in use“. This is by far one of the more helpful errors you will ever see from SharePoint. Unfortunately it isn’t clear how to discover where the content type is actually in use. A quick trip to the content database for the site collection you are working in can show us:
DECLARE @ContentTypeName nvarchar(128)
SET @ContentTypeName='Content Type Name Here'
SELECT w.Title AS [Web Site], w.FullUrl AS [Web Url], al.tp_Title AS [List Title],
ct2.*
FROM ContentTypes ct1
JOIN ContentTypes ct2 ON LEFT(ct2.ContentTypeId, Len(ct1.ContentTypeId))=ct1.ContentTypeId
LEFT OUTER JOIN dbo.ContentTypeUsage ctu ON LEFT(ctu.ContentTypeId, Len(ct2.ContentTypeId)) = ct2.ContentTypeId
LEFT OUTER JOIN dbo.AllLists al ON ctu.ListId = al.tp_Id AND ctu.WebId=al.tp_WebId
LEFT OUTER JOIN dbo.Webs w ON al.tp_WebId = w.Id WHERE ct1.ResourceDir=@ContentTypeName
[Credit to Curtis Ruppe]
Once we know where the content type is in use, deleting it through the GUI is a trivial matter.
Posted by Scott on March 9, 2009
When developing custom InfoPath initiation forms for my workflows, I sometimes forget a crucial step when publishing the forms. If you enter an alternate location when publishing your form, the form state will become stuck on “Installing”.
The moral of the story? When publishing a custom initiation form, be sure to leave the “Alternate” publishing location empty.