zaterdag 9 oktober 2010

Get value from Checkboxlist clientside using Javascript

My latest (SharePoint) assignment was to modify the OOB “Send to –> Other location” functionality. The customer wanted to select the target lists using a checkboxlist control instead of having to type URL’s manually. To make this work I made a copy of the application page Copy.aspx and modified it slightly. It turned out that SharePoint was doing some clientside checks, for which it needed the value of the selected items in my checkboxlist control.

Quite some searching and Googling taught me that it is not possible to retrieve the value clientside using the standard checkboxlist control, but I did find a way to retrieve the value from a checkboxcontrol. To make this possible I needed to make my very own control.

This custom control should be made in the following way:

namespace Your.NameSpace
{
    public class CustomCheckBoxListControl : CheckBoxList, IRepeatInfoUser
    {
        void IRepeatInfoUser.RenderItem(ListItemType itemType, int repeatIndex, RepeatInfo repeatInfo, HtmlTextWriter writer)
        {
            writer.WriteBeginTag("input");
            writer.WriteAttribute("type", "checkbox");
            writer.WriteAttribute("name", UniqueID + "$" + repeatIndex);
            writer.WriteAttribute("id", ClientID + "_" + repeatIndex.ToString(NumberFormatInfo.InvariantInfo));
            writer.WriteAttribute("value", Items[repeatIndex].Value);
            System.Web.UI.AttributeCollection attrs = Items[repeatIndex].Attributes;
            foreach (string key in attrs.Keys)
            {
                writer.WriteAttribute(key, attrs[key]);
            }

            writer.Write(">");
            writer.Write(Items[repeatIndex].Text);
        }
    }
}

As you can see, the value from the listitem is rendered along with the rest of the standard HTML. This means that we can now access the value clientside. Just to be complete, the javascript to retrieve the value of the first checked item could look like this:

var checkedItemValue;

for (i = 0; i < 100; i++)
{
    var checkbox = document.getElementById("<%SPHttpUtility.NoEncode(myCheckBoxList.ClientID,Response.Output);%>_" + i );

    if (checkbox == null)
    {
        break;
    }

    if (checkbox.checked)
    {
        checkedItemValue = checkbox.value;
        break;
    }
}

zaterdag 2 oktober 2010

SharePoint custom field type which shows an image

 

One of my present assignments is to make a custom field type. This field should be showing images in the listview webpart depending on the text value it holds. Now this should be easy to do right? Wrong… for some reason I could not get this to work.

What I want is a completely standard textfield that renders an image for certain texts. There are many blogs describing on how to do this. What I missed though is the fact that you must set <CAMLRendering> to TRUE if you want your HTML to show in the listview webpart.

This is described in MSDN: http://msdn.microsoft.com/en-us/library/aa544201.aspx. They state that:

Optional Boolean. The default is FALSE. Specifies whether the field is rendered on list views using the CAML markup in a RenderPattern element elsewhere within the parent FieldType element. The default FALSE means that the field is rendered on list views by an XSL transform in a fldtypes*.xsl file, which is the standard system for field rendering on list views. (However, this element has no effect on field rendering on Display, New, and Edit forms. A RenderPattern would still be the standard way of rendering the field on a Display form.)

My fieldref_.xml looked like this:

<?xml version="1.0" encoding="utf-8" ?>
<FieldTypes>
  <FieldType>
    <Field Name="TypeName">YourTypeName</Field>
    <Field Name="ParentType">Text</Field>
    <Field Name="TypeDisplayName">xxx</Field>
    <Field Name="TypeShortDescription">xxx.</Field>
    <Field Name="UserCreatable">TRUE</Field>
    <Field Name="Sortable">FALSE</Field>
    <Field Name="AllowBaseTypeRendering">TRUE</Field>
    <Field Name="Filterable">FALSE</Field>
    <Field Name="CAMLRendering">TRUE</Field>
    <Field Name="FieldTypeClass">Some.Namespace.AndClass, Some.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=87iu1765432ade40</Field>
    <RenderPattern Name="DisplayPattern">
      <Switch>
        <Expr>
          <Column/>
        </Expr>
        <Case Value="Text1">
          <HTML><![CDATA[<img src="/_layouts/IMAGES/myImage.png" />]]></HTML>
        </Case>
        <Case Value="Text2">
          <HTML><![CDATA[<img src="/_layouts/IMAGES/OtherImage.png" />]]></HTML>
        </Case>
        <Default>
          <HTML><![CDATA[<span>No Value</span>]]></HTML>
        </Default>
      </Switch>
    </RenderPattern>
  </FieldType>
</FieldTypes