Filtering data dynamically is a common requirement in web applications. Instead of writing multiple queries for each filter, you can design a single CASE‑based SQL query and then use frontend toggles to switch between views. In this article, we’ll walk through how to implement a three‑toggle filter (All, Pending, Replaced) in ASP.NET WebForms.
The Concept
Default View: Show all rows.
Toggle Pending: Show only rows marked as Pending.
Toggle Replaced: Show only rows marked as Replaced.
Backend: Use a single SQL query with CASE to compute a Status column.
Frontend: Bind the result to a Repeater and filter rows based on button clicks.
Backend (SQL + C#)
SQL Query (Generic Example)
SELECT
CASE
WHEN t.UpdateFlag IS NOT NULL THEN 'Replaced'
WHEN t.UpdateFlag IS NULL THEN 'Pending'
ELSE ''
END AS Status,
ISNULL(m.Series, 'EQ') AS Series,
t.ItemName,
t.ItemCode,
'WEB' AS Source
FROM ItemMaster t
LEFT JOIN ItemMeta m ON t.ItemCode = m.Code;
ItemMaster → your main table (replaces ScripMaster).
ItemMeta → metadata table (replaces ScripTokenMaster).
CASE → computes a Status column (Pending or Replaced).
C# Code‑Behind
private DataTable dtItems
{
get { return ViewState["dtItems"] as DataTable; }
set { ViewState["dtItems"] = value; }
}
public void LoadItems()
{
string sql = @"SELECT CASE
WHEN t.UpdateFlag IS NOT NULL THEN 'Replaced'
WHEN t.UpdateFlag IS NULL THEN 'Pending'
ELSE '' END AS Status,
ISNULL(m.Series, 'EQ') AS Series,
t.ItemName, t.ItemCode, 'WEB' AS Source
FROM ItemMaster t
LEFT JOIN ItemMeta m ON t.ItemCode = m.Code;";
DataSet ds = SqlHelper.ExecuteDataset(
ConfigurationManager.ConnectionStrings["MyConnection"].ToString(),
CommandType.Text, sql);
if (ds != null && ds.Tables.Count > 0)
{
dtItems = ds.Tables[0];
repItems.DataSource = dtItems;
repItems.DataBind();
}
}
// Toggle Buttons
protected void btnShowAll_Click(object sender, EventArgs e)
{
LoadItems();
repItems.DataSource = dtItems;
repItems.DataBind();
}
protected void btnShowPending_Click(object sender, EventArgs e)
{
LoadItems();
DataView dv = dtItems.DefaultView;
dv.RowFilter = "Status = 'Pending'";
repItems.DataSource = dv;
repItems.DataBind();
}
protected void btnShowReplaced_Click(object sender, EventArgs e)
{
LoadItems();
DataView dv = dtItems.DefaultView;
dv.RowFilter = "Status = 'Replaced'";
repItems.DataSource = dv;
repItems.DataBind();
}
Frontend (ASPX)
<div class="d-flex justify-content-between align-items-center mb-3">
<h5 class="review mb-0">Item Status</h5>
<div class="btn-group">
<asp:Button ID="btnShowAll" runat="server" Text="Show All"
OnClick="btnShowAll_Click" CssClass="btn custom-btn" />
<asp:Button ID="btnShowPending" runat="server" Text="Show Pending"
OnClick="btnShowPending_Click" CssClass="btn custom-btn" />
<asp:Button ID="btnShowReplaced" runat="server" Text="Show Replaced"
OnClick="btnShowReplaced_Click" CssClass="btn custom-btn" />
</div>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Item Name</th>
<th>Series</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<asp:Repeater ID="repItems" runat="server">
<ItemTemplate>
<tr>
<td><%# Eval("ItemName") %></td>
<td><%# Eval("Series") %></td>
<td><%# Eval("Status") %></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
</div>
Styling the Buttons
.custom-btn {
color: #ffffff !important;
background-color: #003f88 !important;
padding: 15px 20px;
border: none;
margin-left: 5px;
border-radius: 4px;
}
.custom-btn:hover {
background-color: #002f66 !important;
}
Key Takeaways
Use CASE in SQL to compute a Status column instead of writing multiple queries.
Store the result in ViewState so it persists across postbacks.
Use ASP.NET Repeater for flexible binding.
Add three toggle buttons to filter rows dynamically.