Sitecore Inline Item List with Select All / De-Select All option

Most of the topics in the Sitecore Slack channel are about project issues someone is facing day-to-day, so any topic you pick from there is useful for development or blogging. 

Recently, I came across this topic about Inline Item List - a customized Sitecore multilist. This module was written quite long ago, it has the option to add list items without traversing to the data source location in the Sitecore Content tree. I felt that this is useful till-date . Luckily, the source code was still downloadable for this module. I wanted to see how this retro-fits on a Sitecore 10.2 project. 


I added a few changes to accommodate:

1. Select All Option

2. and, Deselect All Option

So, here are the steps I followed to use it in a Sitecore 10.2 project. 

Markup for Select All and Deselect All part of OnLoad event:


//spacer

sb.AppendFormat("<td>{0}</td>", Images.GetSpacer(16, 1));


//SelectAll button

string clientEventSelectAll = Sitecore.Context.ClientPage.GetClientEvent(ID + ".SelectAll");

sb.AppendFormat("<td><a href='#' class='scContentButton' onclick=\"{0}\">Select all</a></td>", clientEventSelectAll);

ImageBuilder imageSelectAll = new ImageBuilder { Src = "Applications/16x16/checkbox.png", ID = ID + "_selectall", OnClick = clientEventSelectAll };

sb.AppendFormat("<td>{0}</td>", imageSelectAll);


//spacer

sb.AppendFormat("<td>{0}</td>", Images.GetSpacer(16, 1));


//UnSelectAll button

string clientEventDeselectAll = Sitecore.Context.ClientPage.GetClientEvent(ID + ".DeselectAll");

sb.AppendFormat("<td><a href='#' class='scContentButton' onclick=\"{0}\">Deselect all</a></td>", clientEventDeselectAll);

ImageBuilder imageDeselectAll = new ImageBuilder { Src = "Applications/16x16/selection.png", ID = ID + "_deselectall", OnClick = clientEventDeselectAll };

sb.AppendFormat("<td>{0}</td>", imageDeselectAll);


The above code invokes these methods in turn:

/// <summary>

/// This event responds to the client 'SelectAll' button 

/// </summary>

protected void SelectAll()

{

if (Disabled)

return;


string fieldId = GetViewStateString("ID");

Listbox listbox1 = FindControl(fieldId + SourceListboxIDSuffix) as Listbox;

Listbox listbox2 = FindControl(fieldId + SelectedListboxIDSuffix) as Listbox;


Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox2);


foreach (ListItem item in listbox1.Items)

{

listbox2.Controls.Add(item);

}


Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox1);

Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox2);

}


protected void DeSelectAll()

{

if (Disabled)

return;


string fieldId = GetViewStateString("ID");

Listbox listbox1 = FindControl(fieldId + SourceListboxIDSuffix) as Listbox;

Listbox listbox2 = FindControl(fieldId + SelectedListboxIDSuffix) as Listbox;


Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox1);


foreach (ListItem item in listbox2.Items)

{

listbox1.Controls.Add(item);

}


Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox1);

Sitecore.Context.ClientPage.ClientResponse.Refresh(listbox2);

}

Patch file related to add a custom control:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<controlSources>

<source mode="on" namespace="Foundation.ContentEditor.Controls" assembly="Foundation.ContentEditor.Controls" prefix="content" />

</controlSources>

</sitecore>

</configuration>

Here is the project structure:



As part of an item template:


In the content editor:


There is a package that needs to be run that is part of the data folder. This package installs an item to core DB and the concerned item is used to configure the inlinelistitem control as part of the list while building the item template. 

I would push this Core db config thru Unicorn so that the package doesn't need to be run in each environment. There are many blogs about Unicorn configuration over the web but my earlier blog covers a practical scenario similar to this one.

Apart from the modified code, added the original documentation for reference in my github repo.

For clarity, the Inline list is a variation of Sitecore multilist. Here is a screen shot of both in same content:


Comments