Unlocking the elusive TelephonePattern... almost

I spent a few hours this morning chasing down a new SharePoint unicorn. Unfortunately I haven't found the solution but it's close. Real close. My rule is that if I can't crack the secret in a few hours I'll post or email someone and see if someone can complete the work. 10,000 monkeys must be smarter than 1.

Have you ever built a custom list and had a telephone field that looked like this:

That's the normal way you have to define a telephone field. With a plain ordinary text field (or you could use a number field if you want). But there's no way to format this stuff for end users. Wouldn't it be great if you could have THIS!

Well, you can. Or at least Microsoft was *thinking* about letting you have it. The above image isn't a custom web part. It's just a regular list but with a *secret* option. I just haven't figured out how to get it to completely work.

Deep in the heart of a file called FLDTYPES.XML (one of those dont-touch-this-or-you-will-be-unsupported files) lies the heart of something just waiting to get out. FLDTYPES.XML defines all of those columns you can add to a list (Text, DateTime, Number, Calculated, Lookup, etc.) and it also determines the way the fields are rendered for the various forms (New, Edit, Display, etc.) through something called RenderPattern. If you dissect the Text field's RenderPattern you'll find a switch on a property called Format. The default value is to just write out some JavaScript to create a new TextField:

<Default>
       <HTML><![CDATA[<SCRIPT>fld = new TextField(frm,]]></HTML>
       <ScriptQuote>
        <Property Select="Name"/>
       </ScriptQuote>
       <HTML>,</HTML>
       <ScriptQuote>
        <Property Select="DisplayName"/>
       </ScriptQuote>
</Default>

This will result in writing out the following JavaScript fld = new TextField(frm, "Name", "DisplayName"); into the browser and through a method in OWS.JS it will create a text field like in Image 1 above. However if a property called Format is set to Telephone you get this instead:

<Case Value="Telephone">
       <HTML><![CDATA[<SCRIPT>fld = new TelephonePattern(frm,]]></HTML>
       <ScriptQuote>
        <Property Select="Name"/>
       </ScriptQuote>
       <HTML>,</HTML>
       <ScriptQuote>
        <Property Select="DisplayName"/>
       </ScriptQuote>
</Case>

This will result in writing out the following JavasScript fld = new TelephonePattern(frm, "Name", "DisplayName"); to the browser which will create the 2nd image above. Cool. However it doesn't work. So first we create our Text field in a custom list using the SCHEMA.XML and add our Format="Telephone" value:

<Fields>
   <Field Name="Title" DisplayName="Title" Required="TRUE"/>
   <Field Name="ContactTelephone" Type="Text" DisplayName="Telephone" Format="Telephone" />
</Fields>

This gets us our form and the data entry looks good. There's even separate validators created for each part of the field so if you make the ContactTelephone field required, it will require the area code and phone number (doesn't need a country code). Saving the item will result in a nasty message from SharePoint:

Error

No such field name

No field was found with that name. Check the name, and try again.

 

So now what? If you take a look at OWS.JS you'll see that when it actually makes the call to create the TelephonePattern, it actually creates a bunch of TextFields. One for each part of the phone number (country code, area code, number). So I figured if SharePoint couldn't save it, it was because there were these new fields that didn't know how to map to the record in the list (after all I only had one field, ContactTelephone). The code in OWS.JS seems to create new fields and gives them the naming pattern of "TelephonePattern#countryCode:" + the internal name of the field for the phone. So I modified my list definition to create some hidden fields to hold those values like so:

 

<Fields>
   <Field Name="Title" DisplayName="Title" Required="TRUE"/>
   <Field Name="ContactTelephone" Type="Text" DisplayName="Telephone" Format="Telephone" />
   <Field Name="TelephonePattern#countryCode:ContactTelephone" Type="Text" DisplayName="Telephone" Hidden="TRUE" />
   <Field Name="TelephonePattern#nationalCode:ContactTelephone" Type="Text" DisplayName="Telephone" Hidden="TRUE" />
   <Field Name="TelephonePattern#number:ContactTelephone" Type="Text" DisplayName="Telephone" Hidden="TRUE" />
</Fields>

Here I thought we're all set. I deployed the list and entered a new item. Field displayed correctly, validation happened and it saved! Nice. However when you look at the list (through something like SharePoint Explorer) you'll see the fields but they're all set to null.

 

So that leaves us puzzled and moving onto other things. You can get the Telephone to display correctly and save correctly with those fields in there. Just no values. As the Telephone format is not documented in SDK, it's one of those things that is left up to the reader. If I use it will it be supported? It's there in FLDTYPES.XML which is a core file of SharePoint however since it's not documented, you might think it will be removed in a future release.

 

Tommorow I'll blog about another undocumented property which does work and I *think* should be there in fhe future. If anyone completes this investigation and gets the Telephone format working please drop me a note through the comments of this entry!

No Comments