I’m currently building search functionality using an UpdatePanel with updatemode conditional. The trigger for this updatepanel is my searchPhrase TextBox. When the TextChanged fires my panel gets updated and the right searchresults are shown.
I’m however clueless on how to implement paging functionality that will work with my searchresults.
I want paging links to be shown on a partial page update and I want the pager to also update my searchResults (only want to show 3 results on one page).
How do I set this up correctly?
This is my code (ascx)
<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
</asp:ScriptManagerProxy>
<div class="searchBox">
<asp:TextBox ID="searchPhrase" runat="server"
AutoCompleteType="Search"
AutoPostBack="true" />
</div>
<asp:UpdatePanel ID="ProductenUpdate" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="ProductRepeater" runat="server">
<ItemTemplate>
<strong><sc:Text ID="Titel" Field="Titel"
runat="server" /></strong><br />
<sc:Text ID="Auteur" Field="Auteur" runat="server" />
<sc:Text ID="Intro" Field="Intro" runat="server" />
<sc:Image ID="Thumb" Field="Thumbnail" runat="server" /><br/>
</ItemTemplate>
</asp:Repeater>
<div class="filterBox">
<asp:PlaceHolder ID="filterOnePlaceholder"
runat="server">
<sc:Text ID="TitelOne" Field="Filter1" runat="server" />
<asp:CheckBoxList ID="filterOneCbl" runat="server"
AutoPostBack="true"
CssClass="checkboxList">
</asp:CheckBoxList>
</asp:PlaceHolder>
</div>
<div class="filterBox">
<asp:PlaceHolder ID="filterTwoPlaceholder"
runat="server">
<sc:Text ID="TitelTwo" Field="Filter2" runat="server" />
<asp:CheckBoxList ID="filterTwoCbl" runat="server"
AutoPostBack="true"
CssClass="checkboxList"
RepeatColumns="3"
RepeatDirection="Vertical">
</asp:CheckBoxList>
</asp:PlaceHolder>
</div>
<div>
PaginaMarker DIV:
<asp:Label ID="paginaMarker" runat="server" />
</div>
<script type="text/javascript">
function ClientCallbackFunction(args)
{
}
</script>
<asp:Button ID="btnBackwards" Text="Vorige"
OnClick="MyServerCall(this.value)" />
<asp:Button ID="btnForward" Text="Volgende"
OnClick="MyServerCall(this.value)" />
<asp:DropDownList ID="DropDownListChoice" runat="server"
onChange="MyServerCall(this.value)">
<asp:ListItem>Choice 1</asp:ListItem>
<asp:ListItem>Choice 2</asp:ListItem>
<asp:ListItem>Choice 3</asp:ListItem>
<asp:ListItem>Choice 4</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="searchPhrase"
EventName="TextChanged" />
</Triggers> </asp:UpdatePanel>
code behind:
// Needed to store the searchResults
List<Item> validSearchResults = new List<Item>();
private List<string> listOneSelectedItems = new List<string>();
private List<string> listTwoSelectedItems = new List<string>();
private string currentCategoryPath = string.Empty;
private string _callbackArgs;
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.UpdateSelectedItemLists();
this.currentCategoryPath = Sitecore.Context.Item.Paths.FullPath;
this.searchPhrase.TextChanged += new EventHandler(searchPhrase_TextChanged);
this.filterOneCbl.SelectedIndexChanged += new EventHandler(filterOneCbl_SelectedIndexChanged);
this.filterTwoCbl.SelectedIndexChanged += new EventHandler(filterTwoCbl_SelectedIndexChanged);
this.ProductRepeater.ItemDataBound += new RepeaterItemEventHandler(ProductRepeater_ItemDataBound);
}
private void UpdateScreen()
{
// update the list of selectedItems for use with the selection of new Items from the index
this.UpdateSelectedItemLists();
this.GetSearchResults();
ProductRepeater.DataSource = validSearchResults;
ProductRepeater.DataBind();
ProductenUpdate.Update();
}
void btnSearch_Click(object sender, EventArgs e)
{
// update the list of selectedItems for use with the selection of new Items from the index
this.UpdateSelectedItemLists();
this.GetSearchResults();
ProductRepeater.DataSource = validSearchResults;
ProductRepeater.DataBind();
ProductenUpdate.Update();
}
private void ProductRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Item dataItem = (Item)e.Item.DataItem;
// if there is a dataItem
if (dataItem != null)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.Item)
{
Sitecore.Web.UI.WebControls.Text Titel = (Sitecore.Web.UI.WebControls.Text)e.Item.FindControl("Titel");
Sitecore.Web.UI.WebControls.Text Auteur = (Sitecore.Web.UI.WebControls.Text)e.Item.FindControl("Auteur");
Sitecore.Web.UI.WebControls.Text Intro = (Sitecore.Web.UI.WebControls.Text)e.Item.FindControl("Intro");
Sitecore.Web.UI.WebControls.Image Thumb = (Sitecore.Web.UI.WebControls.Image)e.Item.FindControl("Thumb");
if (Thumb != null)
{
Thumb.Item = dataItem;
}
if (Titel != null)
{
Titel.Item = dataItem;
}
if (Auteur != null)
{
Auteur.Item = dataItem;
}
if (Intro != null)
{
Intro.Item = dataItem;
}
}
}
}
/// <summary>
/// Handles the TextChanged event of the searchPhrase control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void searchPhrase_TextChanged(object sender, EventArgs e)
{
this.UpdateScreen();
}
/// <summary>
/// Handles the SelectedIndexChanged event of the filterTwoCbl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void filterTwoCbl_SelectedIndexChanged(object sender, EventArgs e)
{
this.UpdateScreen();
}
/// <summary>
/// Handles the SelectedIndexChanged event of the filterOneCbl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void filterOneCbl_SelectedIndexChanged(object sender, EventArgs e)
{
this.UpdateScreen();
}
/// <summary>
/// Updates the selected item lists.
/// </summary>
private void UpdateSelectedItemLists()
{
foreach (ListItem thisItem in filterOneCbl.Items)
{
if (thisItem.Selected)
{
if (!listOneSelectedItems.Contains(thisItem.Value.ToUpper()))
{
listOneSelectedItems.Add(thisItem.Value.ToUpper());
}
}
}
foreach (ListItem thisItem in filterTwoCbl.Items)
{
if (thisItem.Selected)
{
if (!listTwoSelectedItems.Contains(thisItem.Value.ToUpper()))
{
listTwoSelectedItems.Add(thisItem.Value.ToUpper());
}
}
}
}
/// <summary>
/// Gets the search results.
/// </summary>
private void GetSearchResults()
{
SearchResultRetreiver retriever = new SearchResultRetreiver("productenSearch");
IndexSearcher searcher = null;
Hits mySearchResults = retriever.GetSearchResults(searchPhrase.Text.Trim(), ref searcher);
if (mySearchResults != null)
{
for (int i = 0; i < mySearchResults.Length(); i++)
{
Item newItem = Sitecore.Data.Indexing.Index.GetItem(mySearchResults.Doc(i), Sitecore.Context.Database);
string itemTitel = SitecoreHelper.ShowItemTitel(newItem);
bool addItem = true;
if (itemTitel.StartsWith("$")) addItem = false;
if (itemTitel.StartsWith("_")) addItem = false;
if (addItem)
{
this.validSearchResults.Add(newItem);
}
}
}
}
private void FilterSearchResults()
{
}
/// <summary>
/// Handles the Load event of the Page control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Page_Load(object sender, EventArgs e)
{
Item contextItem = Sitecore.Context.Item;
Item subwebsiteItem = contextItem.Axes.GetAncestors().Where(c => c.Axes.Level == 4).FirstOrDefault<Item>();
Sitecore.Data.Fields.CheckboxField filterOneSelected = subwebsiteItem.Fields["Filter1Actief"];
Sitecore.Data.Fields.CheckboxField filterTwoSelected = subwebsiteItem.Fields["Filter2Actief"];
if (filterOneSelected.Checked)
{
TitelTwo.Item = subwebsiteItem;
}
if (filterTwoSelected.Checked)
{
TitelOne.Item = subwebsiteItem;
}
if (!Page.IsPostBack)
{
string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "args", "ClientCallbackFunction", "");
string callbackScript = "function MyServerCall(args)" +
"{" + callbackRef + "}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyServerCall", callbackScript, true);
filterOnePlaceholder.Visible = false;
filterTwoPlaceholder.Visible = false;
if (subwebsiteItem != null)
{
if (filterOneSelected.Checked)
{
filterOnePlaceholder.Visible = true;
Item filterOneLocation = Sitecore.Context.Database.GetItem(subwebsiteItem.Paths.FullPath + "/Filters/Filter1");
List<Item> filterOneList = new List<Item>();
filterOneList = filterOneLocation.GetChildren().Where(c => c.TemplateName.ToLower() == "filter").ToList<Item>();
foreach (Item filterItem in filterOneList)
{
ListItem thisItem = new ListItem(filterItem["Naam"], filterItem.ID.ToGuid().ToString());
this.filterOneCbl.Items.Add(thisItem);
}
}
if (filterTwoSelected.Checked)
{
filterTwoPlaceholder.Visible = true;
Item filterTwoLocation = Sitecore.Context.Database.GetItem(subwebsiteItem.Paths.FullPath + "/Filters/Filter2");
List<Item> filterTwoList = new List<Item>();
filterTwoList = filterTwoLocation.GetChildren().Where(c => c.TemplateName.ToLower() == "filter").ToList<Item>();
foreach (Item filterItem in filterTwoList)
{
ListItem thisItem = new ListItem(filterItem["Naam"], filterItem.ID.ToGuid().ToString());
this.filterTwoCbl.Items.Add(thisItem);
}
}
}
}
}
#region ICallbackEventHandler Members
/// <summary>
/// Returns the results of a callback event that targets a control.
/// </summary>
/// <returns>The result of the callback.</returns>
public string GetCallbackResult()
{
return this._callbackArgs;
}
/// <summary>
/// Processes a callback event that targets a control.
/// </summary>
/// <param name="eventArgument">A string that represents an event argument to pass to the event handler.</param>
public void RaiseCallbackEvent(string eventArgument)
{
this._callbackArgs = eventArgument;
}
Please have a look and tell me how I can make a pager work for my solution.
I’ve had this fixxed by introducing a GetList() method and an Update() method that got called after eachother. In de GetList() metthod i’d set the total amount of items and in the Update method then I’d call another method that would create the pager.
This solved my question.