Web Development  

Creating Dynamic Data-Style Cards Using ASP.NET

Introduction

In this article, we will walk through the process of creating dynamically loading cards that pull content from your database and display it in a neat two-column layout. This is an efficient way to present feature-based content while maintaining a clean and SEO-friendly user interface.

Objective

Our goal is to display articles in dynamically generated cards that are styled in a way that offers a great user experience, improves SEO, and is easy to maintain. Each article will contain a title, description, icon, and an SEO-friendly URL.

Key Features

  • SEO-friendly URLs: Each article will have a clean, readable URL.

  • Dynamic Loading: Articles are loaded from the database in real-time.

  • Left and Right Column Layout: Articles will be grouped into pairs, displayed in two columns.

  • Alternating Background Colors: Grey backgrounds will alternate for visual appeal.

  • Handling Odd Number of Articles: If there is an odd number of articles, the last row will only contain a left card.

Components Used

  • ASP.NET Repeater Control: Used to display the articles dynamically.

  • Database Query: A SQL query is used to fetch active articles from the database.

  • CSS Styling: Custom styles are applied to alternate the background colors for left and right cards.

Step-by-Step Implementation

1. ASP.NET Repeater Control

The Repeater control is responsible for displaying each article. We create a dynamic structure using ItemTemplate, which allows us to render each article's content into styled cards.

<asp:Repeater ID="rptFeatures" runat="server">
    <ItemTemplate>
        <div class="col-sm-12 col-xs-12 nopad">

            <!-- LEFT CARD -->
            <div class='col-sm-6 col-xs-12 nopad <%# GetLeftStyle(Container.ItemIndex) %>'>
                <div class="abc">
                    <div class="col-sm-2 col-xs-3 nopad top_pd">
                        <div class='product-icon <%# Eval("Left.Icon") %>'></div>
                    </div>
                    <div class="col-sm-10 col-xs-8 nopad">
                        <div class="heads_h2 heads_h2_resp"><%# Eval("Left.Heading") %></div>
                        <p class="paras paras_resp"><%# Eval("Left.Summary") %></p>
                        <div class="button read_more">
                            <a href='<%# Eval("Left.Link") %>'>Read APIs <span class="font_aws">&#xf061;</span></a>
                        </div>
                        <div class="blnk_sp">&nbsp;</div>
                    </div>
                </div>
            </div>

            <!-- RIGHT CARD -->
            <asp:Panel runat="server" Visible='<%# Eval("Right") != null %>'>
                <div class='col-sm-6 col-xs-12 nopad <%# GetRightStyle(Container.ItemIndex) %>'>
                    <div class="abc">
                        <div class="col-sm-2 col-xs-3 nopad top_pd">
                            <div class='product-icon <%# Eval("Right.Icon") %>'></div>
                        </div>
                        <div class="col-sm-10 col-xs-8 nopad">
                            <div class="heads_h2 heads_h2_resp"><%# Eval("Right.Heading") %></div>
                            <p class="paras paras_resp"><%# Eval("Right.Summary") %></p>
                            <div class="button read_more">
                                <a href='<%# Eval("Right.Link") %>'>Read APIs <span class="font_aws">&#xf061;</span></a>
                            </div>
                            <div class="blnk_sp">&nbsp;</div>
                        </div>
                    </div>
                </div>
            </asp:Panel>

        </div>
    </ItemTemplate>
</asp:Repeater>

2. Database Query and Feature Retrieval

The code retrieves active articles from the database. These articles include a title, description, and icon.

string SQL = ConfigurationManager.ConnectionStrings["MainPortal"].ToString();

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        LoadFeatures();
    }
}

protected void LoadFeatures()
{
    var features = new List<FeatureVM>();

    string query = @"
        SELECT DisplayOrder, FeatureName, FeatureText, FeatureIcon
        FROM FeatureCatalog
        WHERE IsEnabled = 1
        ORDER BY DisplayOrder
    ";

    DataSet ds = SqlHelper.ExecuteDataset(SQL, CommandType.Text, query);

    foreach (DataRow row in ds.Tables[0].Rows)
    {
        string name = row["FeatureName"].ToString().Trim();

        features.Add(new FeatureVM
        {
            Heading = name,
            Summary = row["FeatureText"].ToString(),
            Icon = row["FeatureIcon"].ToString(),
            Link = "services/" + MakeSlug(name)
        });
    }

    var pairedRows = new List<FeatureRowVM>();

    for (int i = 0; i < features.Count; i += 2)
    {
        pairedRows.Add(new FeatureRowVM
        {
            Left = features[i],
            Right = (i + 1 < features.Count) ? features[i + 1] : null
        });
    }

    rptFeatures.DataSource = pairedRows;
    rptFeatures.DataBind();
}

3. View Models

We use FeatureVM for individual feature data and FeatureRowVM to group features in pairs.

public class FeatureRowVM
{
    public FeatureVM Left { get; set; }
    public FeatureVM Right { get; set; }
}

public class FeatureVM
{
    public string Heading { get; set; }
    public string Summary { get; set; }
    public string Link { get; set; }
    public string Icon { get; set; }
}

4. Styling Logic

We alternate background colors for visual rhythm using the GetLeftStyle and GetRightStyle methods.

public string GetLeftStyle(int rowIndex)
{
    int pos = rowIndex * 2 + 1;
    return IsGreyBox(pos) ? "greybg" : "grey_box";
}

public string GetRightStyle(int rowIndex)
{
    int pos = rowIndex * 2 + 2;
    return IsGreyBox(pos) ? "greybg white_box" : "";
}

private bool IsGreyBox(int pos)
{
    int mod = (pos - 1) % 4;
    return mod == 0 || mod == 3;
}

5. SEO-Friendly URL Generator

We ensure SEO-friendly URLs by generating slugs from article names. The MakeSlug function converts feature names into lowercase, removes special characters, and replaces spaces with hyphens.

public static string MakeSlug(string text)
{
    if (string.IsNullOrEmpty(text))
        return "";

    text = text.ToLowerInvariant();
    text = Regex.Replace(text, @"&", "and");
    text = Regex.Replace(text, @"[^a-z0-9\s-]", "");
    text = Regex.Replace(text, @"\s+", "-");
    text = Regex.Replace(text, @"-+", "-");
    return text.Trim('-');
}

Conclusion

By following the steps outlined above, we have successfully created dynamic article-style cards that load from the database and display in a clean two-column format. This solution provides:

  • SEO-friendly URLs: Articles are accessible via readable URLs.

  • Consistent UI: Alternating background colors enhance readability.

  • Fast Loading: The use of the Repeater control ensures smooth performance.

  • Easy CMS Control: The system allows for easy article management directly from the database.

This setup is ideal for CMS-based websites or feature-focused web applications where content is frequently updated.

Summary

This implementation demonstrates how to build dynamic two-column feature cards in ASP.NET using a Repeater control, database-driven content, paired view models, alternating styling logic, and SEO-friendly slug generation. The approach ensures maintainability, performance, and a clean user interface suitable for content-driven applications.