zaterdag, november 25, 2006

Using CAML to filter a infopath published boolean field (from a sharepoint list)

In a infopath form we have a boolean field called Draft, we publish the form to a sharepoint list, and we want to filter that list using Caml queries:
Which value should the BOOLEANVALUE have to succeed the query?
False/True ? Yes/No ? 0/1 ?
What I noticed is, when I published the infopath form the boolean type in intopath will be a Yes/No Type in the sharepoint list.....

So the Caml query will not work with BOOLEANVALUE = False/True Or Yes/No , you have to use 0 or 1...

Implement the CAML query into code:

StringBuilder camlBuilder = new StringBuilder();

string queryText = camlBuilder.ToString();

SPWeb site = SPContext.Current.Web;
SPList list = site.Lists["Mail"];
SPQuery query = new SPQuery();
string queryText =""
query.Query = queryText;

results = list.GetItems(query);
foreach (SPListItem item in results)
{..............}

If you put the query Tag as root tag into the query text, you will receive all items, zo don't put it there, some stupid guy I know very good did that ;-)

Also check this out:
U2U CAML Query Builder and Execution Tool (+download)

SPListItem looses Property data type when publishing Infopath form to a sharepoint list (MOSS 2007 beta2TR)

When you publish a Infopath Form to a sharepoint list, the Infopath form contains some fields (text and date(time) data types). These fields are copied to a sharepoint list when you publish the form to it.




You should think sharepoint keeps the data types like in the infopath form, but this isn't, I noticed that the date(time) data type is just a string/text field in the sharepoint list!

The strange thing is that when you add a column in the published list manualy (for example a datetime field), it will keep the data type and not change it to a string.

I noticed it when a wanted to perform an update an a field called ApprovalDate (Date Datatype) in a Web Part:



SPSite site = new SPSite("http://......");
SPListItemCollection results = site.Lists["InfopathPublishedList"].Items;
foreach (SPListItem item in results)
{
item.Properties["ApprovalDate"] = DateTime.Today;//DateTime.Today.ToString();
item.Update();
}

This code failed when I did this on the datetime field published by infopath:

Error:Specified data type does not match the current data type of the property. at Microsoft.SharePoint.Utilities.SPUtility.UpdateArrayFromHashtable(Object& o, Hashtable ht) at Microsoft.SharePoint.SPListItem.PrepareItemForUpdate(Guid newGuidOnAdd, Boolean bMigration, Boolean& bAdd, Boolean& bPublish, Object&
objAttachmentNames, Object& objAttachmentContents, Int32& parentFolderId) at Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration,
Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents) at Microsoft.SharePoint.SPListItem.Update()



This doesn't happen if the ApprovalDate is added by create column in the list.







So watch out, and as you notice in the picture below: It ain't what it look like........


dinsdag, november 21, 2006

System.Web.UI.WebControls.WebControl doesn't fire all events

During the development of a ServerControl for a masterpage in a Sharepoint site, I added some eventhandlers in the CreateChildControls(): DayRender, VisibleMonthChanged and SelectionChanged.

After debugging, I noticed that only the DayRender event worked. I googled sites and newsgroups to find a solution, but I didn't find an answer....
After sending this problem to a colleague(thanks to: Sam), he answered this:

If you inherit controls from the WebControl class, you will get problems with events and state. So if you need dynamic controls, let them inherit from the CompositeControl class, this class is special made for controls that contains other controls.

At the CompositeControl MSDN page I found this:
The CompositeControl class is an abstract class that provides naming container and control designer functionality for custom controls that encompass child controls in their entirety or use the functionality (STATE AND EVENT HANDLING?!!?) of other controls.

Below some code of a custom Calendar that inherit from CompositeControl :

public class MailCalendar : System.Web.UI.WebControls.CompositeControl

{
private System.Web.UI.WebControls.Calendar ctlCalendar;

protected override void Render(HtmlTextWriter writer)
{
this.EnsureChildControls();
this.ctlCalendar.RenderControl(writer);
}

protected override void CreateChildControls()
{
this.Controls.Clear();
this.ctlCalendar = new System.Web.UI.WebControls.Calendar();
ctlCalendar.VisibleDate = DateTime.Today; this.ctlCalendar.DayRender _
+= new DayRenderEventHandler(ctlCalendar_DayRender);

this.ctlCalendar.VisibleMonthChanged _
+= new MonthChangedEventHandler(ctlCalendar_VisibleMonthChanged);

this.ctlCalendar.SelectionChanged _
+= new EventHandler(ctlCalendar_SelectionChanged); this.Controls.Add(ctlCalendar);
}

void ctlCalendar_SelectionChanged(object sender, EventArgs e)
{
this.Context.Response.Redirect(.......);
}

void ctlCalendar_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
{
ctlCalendar.VisibleDate = e.NewDate;
}

void ctlCalendar_DayRender(object sender, DayRenderEventArgs e)
{
// Set date to bold if its today
Style boldStyle = new Style();
boldStyle.Font.Bold = true;

if (e.Day.Date == DateTime.Today)
{ e.Cell.ApplyStyle(boldStyle); }
}
}


More info: Webblog ScottGu