This blog post introduces a neat functionality to filter as you type all documents in your Sitefinity libraries on the front-end.

Dowload the full code in GitHub repository here

Video demo

Click on the image below to watch a video demonstration:

Filter as you type

Solution plan

We would need to create new custom widget that inherits Sitefinity's DownloadList widget. The new one will extend the MasterListView template of the DownloadList widget to be able to add search textbox and functionality to filter documents. To achieve filtering without post-back, we are taking advantage of the ASP.NET UpdatePanel.

Solution

1.Create new custom class that inherits DownloadListView and override the MasterListView property as follows:

public class CustomDownloadListView : DownloadListView
{
    public override string MasterViewName
    {
        get
        {
            return "CustomMasterListView";
        }
        set
        {
            base.MasterViewName = value;
        }
    }
}

This step prepares our custom widget to search for a new fully custom master view for documents.

2.Register CustomMasterListView in Sitefinity settings.

  • Navigate to Administration -> Settings -> Advanced -> ContentView -> Controls -> FrontendDocuments -> Views and click to Create new View
  • Select DownloadListViewMasterElement as a type and add the following values to the fields:

ThumbnailType = BigIcons Allow aging = True
Allow URL Queries = True
Disable sorting = False
Filter expression = Visible = true AND Status = Live
Items per page = 20
Allow users to set number of items per page = True
Sort expression = PublicationDate DESC
Template evaluation mode = None
Parent ID = 00000000-0000-0000-0000-000000000000
Render links in Master View = True
Enable social sharing = False
DisplayMode = Read
ResourceClassId = DocumentsResources
ViewName = CustomMasterListView
ViewType = SitefinityWebApp.CustomWidgets.DownloadList.CustomMasterListView, SitefinityWebApp

  • Save changes

3.Create the markup of the MasterListView

For the demo purpose, bootstrap and several fonts and styles were used to make the widget look as you see it in the video. All of the files are located in the assets folder. You are free to use your own styles and create your own presence for the documents list.

We are aiming to filter all documents by title as soon as a key is pressed by the search textbox. To be able to achieve that, we should invoke a postback so that server logic is executed. This is done by a simple trick in the onkeyup event handler:

<asp:TextBox ID="search" ClientIDMode="Static" CssClass="search" placeholder="Search" runat="server"
    onkeyup="RefreshUpdatePanel();" OnTextChanged="search_TextChanged"
    AutoPostBack="true" />

<script type="text/javascript">
function RefreshUpdatePanel() {
    __doPostBack('<%= search.ClientID %>', '');
};
</script>

Wrap all of the documents list markup by UpdatePanel to prevent flickering of the screen.

4.Add code-behind logic

Here is the place to put logic to filter all documents by search characters. This is achieved by subscribing to the TextChanged server event.

protected void search_TextChanged(object sender, EventArgs e)
    {
        LibrariesManager libMan = LibrariesManager.GetManager();
        var dataSource = libMan.GetDocuments().Where(a => a.Status == ContentLifecycleStatus.Live);
        if (!this.search.Text.IsNullOrEmpty())
            dataSource = dataSource
                .Where(itm => (itm.Title.ToString()
                    .Contains(this.search.Text) && itm.Status == ContentLifecycleStatus.Live));

        this.documentsRepeater.DataSource = dataSource.ToList();
        this.documentsRepeater.ItemDataBound += documentsRepeater_ItemDataBound;
        this.documentsRepeater.DataBind();
    }

In the TextChanged event handler, we are also subscribing to the documents repeater ItemDataBound event to be able to display the Library title above each document and bind all properties as File size, Title, File extension, etc.

5.Add CustomMasterListView class

Finally, we need to tell the widget to use our custom markup instead of the default one. For this purpose, we are overriding the MasterListView class and LayoutTemplatePath property:

 public class CustomMasterListView : MasterListView
  {
    #region Properties

    /// <inheritdoc />
    public override string LayoutTemplatePath
    {
        get
        {
            return CustomMasterListView.layoutTemplatePath;
        }
    }

    static CustomMasterListView()
    {
        CustomMasterListView.layoutTemplatePath = "~/CustomWidgets/DownloadList/CustomMasterListView.ascx";
    }


    #endregion 
  } 

When the search textbox text is cleared, we would like to display all documents. For that purpose, we need to override the DataBindDocumentList method and call base each time the Text is null or empty:

    protected virtual TextBox SearchTextBox
    {
        get
        {
            return this.Container.GetControl<TextBox>("search", true);
        }
    }

    public override void DataBindDocumentList()
    {
        if (String.IsNullOrEmpty(this.SearchTextBox.Text))
        {
            base.DataBindDocumentList();
        }
    }

With this last step, we are now ready to upload documents and filter them easily as we type on the front-end.

Veronica Milcheva

About Veronica Milcheva

I am a passionate Sitefinity blogger, developer and consultant. In my spare time I enjoy running and listening to music. My personal quote: There's no tough problem, just not enough coffee :)

View Comments

comments powered by Disqus