| I am very happy to announce that I have signed on as an instructor for Critical Path Training. (I have no doubt that this is the direct result of discussing 1980’s computing technology with Ted at a SharePint in Las Vegas.) I am excited to have the opportunity to work with friends and colleagues. Like most instructors at CPT, I will still be an independent consultant. This allows me to bring real-world experience into the classroom. I’ll be teaching The Great SharePoint Adventure 2013 course in Calgary in July (register here), and will have more opportunities for my adoring public to see me coming up soon! |
| During a recent client visit, I came across an interesting application of technology that I had not seen in quite a while. On the intranet home page was displayed a box notifying employees that a critical system was experiencing service degradation. The message included a link to a page with more information. This notification solution reminded me of the “etc/motd” file that exists on Unix systems. The “Message of the Day” is automatically displayed on a user’s console after login. I can still remember a young college student working in the computer lab who updated the motd file each day with the hockey standings in the old Norris division! I was inspired to replicate this functionality in SharePoint. Read the full article… |
| This morning, the Dutch Information Worker User Group (DIWUG) published their ninth e-Magazine, which includes an article of mine. Marianne and Mirjam have done a wonderful job, and I encourage you to download this latest issue. |
| I blogged last week about an article on Impersonation/RWEP. Next week, I’ll be presenting on that topic. Come see the demo and ask question! Chicago SharePoint Developers User Group Thursday, October 18, 2012 from 6:00 PM to 8:00 PM (CDT) http://www.eventbrite.com/event/4588257602 |
| This is mostly a note to myself, but did you know that the ULS logs contains the CAML generated by the CQWP? Product: Web Content Management Category: Publishing Level: Medium |
| I’ve published an article on the People Picker functionality in web applications using a Trusted Identity Provider. (What a mouthful.) BTW, it really should be called the Claims Expression Editor.TM SharePoint People Picker |
| For the first time today, I had to include a boolean field on a publishing page while in edit mode. (Doesn’t that seem a bit weird? After all this time, there was never a need for content authors to update a boolean field.)
My field (site column) is nothing out of the ordinary. A Yes/No column with a name and a description. When the field is rendered on the list New/Edit/Display form, the title is on the left and the checkbox is on the right. The description is below the box, providing some context to the author. The display is accomplished via the InputFormSection control and the rendering templates in CONTROLTEMPLATES\DefaultTemplates.ascx.

In my publishing scenario, the value of the field is used to do some conditional rendering. It is not rendered in display mode, so on the page layout it is wrapped in an EditModePanel. And, as you would expect, I used a Microsoft.SharePoint.WebControls.BooleanField control. The result was pretty lame:

The BooleanField control also uses the RenderingTemplate from CONTROLTEMPLATES\DefaultTemplates.ascx. But it does not use the InputFormSection. The template for BooleanField is quite spartan:

The CheckBox does not have the Text attribute specified, so there is nothing next to the box as is the custom in ASP.NET pages.
Fixing the issue
My fix for the issue is a custom FieldControl to adjust the rendering. (This is *not* a custom FieldType. I don’t need to change the storage of the field value, so a FieldType is not required.) In this custom control, I get a reference to the checkbox and set its Text attribute.
Enhanced Boolean control
- using System;
- using System.Web.UI.WebControls;
-
- namespace Schaeflein.Community.WebControls
- {
- public class FieldBooleanEnhancedControl: BooleanField
- {
- protected CheckBox cbx;
-
- protected override void CreateChildControls()
- {
- base.CreateChildControls();
-
- string fieldDescription = this.Field.Description;
-
- if (!String.IsNullOrEmpty(fieldDescription))
- {
- cbx = (CheckBox)this.TemplateContainer.FindControl("BooleanField");
- if (cbx != null && String.IsNullOrEmpty(cbx.Text))
- {
- cbx.Text = fieldDescription;
- }
- }
- }
- }
- }
Since the checkbox control now has its Text attribute, the edit-mode experience is less lame, and authors are happy. 

|
| I am writing a lot of javascript lately, and I ran into a quirk in the ASP.Net framework that caused a bit of frustration. Let’s say we have a user interface requirement that calls for a checkbox to indicate using a default value. If the checkbox is not selected, then additional controls must be displayed to capture the non-default value. This is quite straight-forward with jQuery’s hide/show functions. This paradigm is repeated for numerous items on the page. Since I don’t want to copy/paste javascript all over the place, I re-factored the script to have an onclick function for every checkbox: Initial javascript - DefaultSelector = {
- containerId: null,
-
- useDefaultClick: function (e) {
- if (e.checked) {
- $(e.id + "[related_control_id]").hide();
- } else {
- $(e.id + "[related_control_id]").show();
- }
- },
- initialize: function (containerId) {
- this.containerId = containerId;
- // attach an on-click event to the "use default" checkboxes
- $("#" + containerId + " input:checkbox").click(function () {
- DefaultSelector.useDefaultClick(this);
- });
- }
- };
As you can see in the snippet, I need the id of the control to hide/show. In the server control code, I can use the ClientId property to get that value, but how do I get that value into the useDefaultClick function? The easiest approach is to put the id into the html as a property. (This is called expando properties.) So, I used the Attributes property of the CheckBox class to add the related control id: Server Control - private CheckBox CreateUseDefaultControl(string id, string relatedControlId)
- {
- CheckBox result = new CheckBox { ID = id };
- result.Text = "Use Default";
- result.TextAlign = TextAlign.Right;
- result.InputAttributes.Add("relatedcontrol", relatedControlId);
- return result;
- }
Now, I just need to grab that property from the element that is clicked: Updated click handler - useDefaultClick: function (e) {
- if (e.checked) {
- $(e.relatedControl).hide();
- } else {
- $(e.relatedControl).show();
- }
- },
However, it does not work! Digging into the html, I found this nice bit of malformed XHTML: Code Snippet - <SPAN relatedControl="ctl00_TextBox1">
- <INPUT id=ctl00_useDefault name=ctl00$useDefault value="" type=checkbox>
- <LABEL for=ctl00_useDefault>Use Default</LABEL>
- </SPAN>
How nice of the CheckBox class to put the attribute in a containing element. Grrrrr!! The solution: the CheckBox class has to additional attribute collections – InputAttributes and LabelAttributes. |
Compliance Details javascript:commonShowModalDialog('{SiteUrl}/_layouts/itemexpiration.aspx?ID={ItemId}&List={ListId}', 'center:1;dialogHeight:500px;dialogWidth:500px;resizable:yes;status:no;location:no;menubar:no;help:no', function GotoPageAfterClose(pageid){if(pageid == 'hold') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/hold.aspx?ID={ItemId}&List={ListId}'); return false;} if(pageid == 'audit') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/Reporting.aspx?Category=Auditing&backtype=item&ID={ItemId}&List={ListId}'); return false;} if(pageid == 'config') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/expirationconfig.aspx?ID={ItemId}&List={ListId}'); return false;}}, null); return false; 0x0 0x1 ContentType 0x01 898 |
|
|
 |
|
I am a long-time SharePoint developer currently working as a consultant.
I like hockey, margaritas and SharePints.
|
|
|
|
|
Compliance Details javascript:commonShowModalDialog('{SiteUrl}/_layouts/itemexpiration.aspx?ID={ItemId}&List={ListId}', 'center:1;dialogHeight:500px;dialogWidth:500px;resizable:yes;status:no;location:no;menubar:no;help:no', function GotoPageAfterClose(pageid){if(pageid == 'hold') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/hold.aspx?ID={ItemId}&List={ListId}'); return false;} if(pageid == 'audit') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/Reporting.aspx?Category=Auditing&backtype=item&ID={ItemId}&List={ListId}'); return false;} if(pageid == 'config') {STSNavigate(unescape(decodeURI('{SiteUrl}'))+'/_layouts/expirationconfig.aspx?ID={ItemId}&List={ListId}'); return false;}}, null); return false; 0x0 0x1 ContentType 0x01 898 |
|
|
|
|
|