Sitecore 5.3: Dynamically add headers to SheerUI listviews

Creating shell applications in Sitecore’s SheerUI is rather complex. But once you get the hang of it (= have modified enough existing sample code to get a working application) you can do amazing stuff.
Yesterday I had to dynamically alter the columns of my SheerUI listview, and here is what I did.

In the XML file I created my listview:

<Listview ID="IndexList" MultiSelect="false" View="Details" Width="100%" Background="white">
	<listviewheader id="IndexHeader">
  </listviewheader>
</listview>

The header is defined but empty, as I will create them myself.

In the .CS file I added both the InexList and the IndexHeader as private variables:

private Listview IndexList = null;
private ListviewHeader IndexHeader = null;

Then in the code where I fill the listview I started with creating my header sections by calling this function:

private void CreateHeader(string name)
{
  ListviewHeaderItem headerItem = new ListviewHeaderItem();
  Context.ClientPage.AddControl(IndexHeader, headerItem);
  headerItem.ID = Control.GetUniqueID("HI");
  headerItem.Value = name;
  headerItem.Name = name;
  headerItem.Header = name;
}

The function will create a new header item, add it to the header and set the header properties to the value contained in the “name” parameter.
When filling in values in the IndexList I have to refer to the header by the header property:

ListviewItem listItem = new ListviewItem();
Context.ClientPage.AddControl(IndexList, listItem);
listItem.ID = Control.GetUniqueID("I");
listItem.ColumnValues["somecolumnname"] = somevalue;

Sitecore: Adding your own buttons to the RichText editor

It’s surprisingly easy to add your own functionality to the Sitecore Rich Text editor. First you need to register your button in Sitecore:

/system/settings/Html Editor Profiles/Rich Text Default/Toolbar 1

Duplicate an existing button and you will have added a new button to the first toolbar in the default Rich Text Editor.
Change the “Click” field of your new button to a unique text. I have changed mine to “MyNewButton”.

Then you must change the Rich Text javascript file. You’ll find the file at:

/sitecore/shell/Controls/Rich Text Editor/RichText Commands.js

This file contains the commands for the Rich Text editor. Here you can add your own “RadEditorCommandList” for the “MyNewButton”: 

RadEditorCommandList["MyNewButton"] = function(commandName, editor, tool)
{
};

Inside this function you can add code to add text to the editor:

var str = "This is my new text. This will be inserted at the cursor position";
editor.PasteHtml(str);

Here is another example where I call a webservice and inserts the response:

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","/service.asmx/MyFunction",false);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send("param=" + escape("my parameter"));
if (xmlhttp.status==200)
{
  var str = xmlhttp.responseText;
  str = str.replace(/</g, "");
  editor.PasteHtml(str);
}
else
{
  alert("Error calling webservice: " + xmlhttp.statusCode + " - " + xmlhttp.statusText);
}

Sitecore 5.3 HandleMessage and ShowModalDialog

Creating your own Sitecore Fields can be tricky. The best way to start is to download one of Sitecores examples (the composite control is a good example).
In this example I’ll use the HandleMessage function in my control to open a modal window, do some stuff and return the values to my control.

The HandleMessage function reacts on events from the Sitecore Client. Each message contains the ID of the current control, which I will use to react to messages that belongs to me:

public override void HandleMessage(Sitecore.Web.UI.Sheer.Message message)
{
  if (message["id"] == this.ID)
  {
    if ( message.Name == "MyControl:message" )
    {
      System.Web.HttpContext.Current.Session["MyControl.ID"] = this.ID;
      ClientCommand command = Sitecore.Context.ClientPage.ClientResponse.ShowModalDialog("MyPage.aspx", "300px", "630px", "my:Message", false);
    }
  }
}

The trick is now that when the modal dialog closes, a message called “my:Message” will be thrown. Unfortunately there is no control ID attached to the message. In order to identify which control opened the modal window, I store the control’s ID in a session variable, and use this ID when handling the my:Message message:

if ( message.Name == "my:Message" )
{
  string id = System.Web.HttpContext.Current.Session["MyControl.ID"] as string;
  if (id == this.ID)
  {
    // do my work, and remember to clear the session
  }
}