Monday, April 6, 2009

AddFieldAsXml bug

Yes, there is a bug on this function allowing that the field created using this function to have after creation as InternalName the DisplayName.

This can cause problems when you ranslate your field name into other languages. In this case when you will try to access your field an error will occure.

This bug can be fixed with a small workaround. For this, into our function that create the field we have to get the InternalName , create the field and after that replace the InternalName of the new created field with the one that we saved before. This solution can be used together with a solution presented into a previous post.

private void SetTheProperGUID(SPList catList, SPField catField, SPList pageLibList) 
{
string fieldXml = catField.SchemaXml;
string strInternalName = catField.InternalName;
string strDisplayName = catField.Title;
Regex regex = new Regex(@"List=\""(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}\""");
if (regex.IsMatch(fieldXml))
{
fieldXml = regex.Replace(fieldXml, "
List=\"" + catList.ID.ToString("B").ToLower() + "\"");
}
// a SharePoint bug force us to make a workaround
// DisplayName must be the same as InternalName at creation
string oldValue = "DisplayName=\"" + strDisplayName + "\"";
string newValue = "DisplayName=\"" + strInternalName + "\"";
fieldXml = fieldXml.Replace(oldValue, newValue);
catField.Delete();
pageLibList.Fields.AddFieldAsXml(fieldXml);
// now the DisplayName must be set with the proper value
SPField fixedField = pageLibList.Fields[strInternalName];
fixedField.Title = strDisplayName;
fixedField.Update();
}

Single check on a TreeView

In the past I showed how to bind a TreeView control to a xml data source. Now the task is to allow selection of none or only one node from this control.

An ideea is to implement this using JQuery. A friend introduced me to this scripting language and now the solution seems simple. I’m sure that it can be improved but is my first contact with JQuery so have mercy.

The only thing that we have to do is to add some new code to the existing TreeView solution.

To display all checkboxes for the tree in order to be able to do the selection we have to set the ShowCheckBoxes property.

TreeView tv = (TreeView)Page.FindControl("ChapterTree");
tv.ShowCheckBoxes = TreeNodeTypes.All;



And this are all modification that we must to into the .cs file. Now we must open the .aspx page and add some lines. Of course  the first that we have to add is the reference to the jquery.js file. You can download this file from the JQuery site and have the latest version.



To be able to access our TreeView checkboxes we have first to take a look into the source code of the page. We will see that our controls have a generated ID. What we can do to access our control is to attach an attribute and search by this attribute. We must notice that our checkboxes are created into some cells of a html table. To access  them we have to create a selector that go from the TreeView control to our checkboxes.




$("div[myAttribute='myValue'] table tr td input[type='checkbox']")



After that we have to bind a function to each of our checkboxes. In this function we unselect all other and select the current node.



Below is all the code that must be added into the head tag:




<script type="text/javascript" src="jquery.js" ></script>
<script type="text/javascript">
function aClick() {
var allNodes = $("div[myAttribute='myValue'] table tr td input[type='checkbox']");
allNodes.bind('click', aClick);
allNodes.attr('checked', false);
$(this).attr('checked', true);
$(this).unbind('click', aClick);
}

$(document).ready(function(){
$("div[myAttribute='myValue'] table tr td input[type='checkbox']").bind('click', aClick);
});
</script>



Now all seems to be simple. From today I start to apreciate JQuery.



Have a nice one !