DBindly Docs
Attributes Reference

Lists & Repetition

List attributes allow you to render arrays of data by repeating HTML elements. Combined with filtering and sorting, you can create powerful dynamic lists.

dbind_repeat

Purpose: Repeat an element for each item in an array. This is essential for rendering lists, grids, and tables from your data.

Syntax:

<element dbind_repeat="arrayField">
  <!-- This entire element is repeated for each item -->
</element>

How It Works

  1. DBindly finds the element with dbind_repeat
  2. The element becomes a template
  3. For each item in the array, a copy of the template is created
  4. Inside each copy, data bindings refer to the current item

Basic Usage

<!-- Simple list -->
<ul>
  <li dbind_repeat="items" dbind_data="name"></li>
</ul>

Data:

{
  "items": [
    { "name": "Apple" },
    { "name": "Banana" },
    { "name": "Cherry" }
  ]
}

Result:

<ul>
  <li>Apple</li>
  <li>Banana</li>
  <li>Cherry</li>
</ul>

Accessing Item Properties

Inside a repeated element, use field names directly (no array notation):

<div dbind_repeat="products">
  <h3 dbind_data="name"></h3>
  <p dbind_data="description"></p>
  <span dbind_data="price" dbind_format="currency:USD"></span>
  <img dbind_src="image" dbind_alt="name">
</div>

Data:

{
  "products": [
    {
      "name": "Headphones",
      "description": "Premium wireless audio",
      "price": 149.99,
      "image": "/images/headphones.jpg"
    },
    {
      "name": "Keyboard",
      "description": "Mechanical RGB keyboard",
      "price": 89.99,
      "image": "/images/keyboard.jpg"
    }
  ]
}

Nested Properties

Access nested data within each item:

<div dbind_repeat="users">
  <h3 dbind_data="name"></h3>
  <span dbind_data="address.city"></span>
  <span dbind_data="address.country"></span>
  <img dbind_src="profile.avatar" dbind_alt="name">
</div>

Data:

{
  "users": [
    {
      "name": "John Doe",
      "address": {
        "city": "New York",
        "country": "USA"
      },
      "profile": {
        "avatar": "/avatars/john.jpg"
      }
    }
  ]
}

Special Loop Variables

Inside dbind_repeat, you can access special variables:

VariableDescriptionExample
_indexZero-based index (0, 1, 2, ...){{_index}}
_numberOne-based number (1, 2, 3, ...){{_number}}
_firstBoolean, true for first itemdbind_show="_first"
_lastBoolean, true for last itemdbind_show="_last"
_evenBoolean, true for even indexesdbind_class="evenClass"
_oddBoolean, true for odd indexesdbind_class="oddClass"
<div dbind_repeat="items">
  <span class="number">{{_number}}.</span>
  <span dbind_data="name"></span>
  <span dbind_show="_first" class="badge">First!</span>
  <span dbind_show="_last" class="badge">Last!</span>
</div>

Result:

<div>
  <span class="number">1.</span>
  <span>Apple</span>
  <span class="badge">First!</span>
</div>
<div>
  <span class="number">2.</span>
  <span>Banana</span>
</div>
<div>
  <span class="number">3.</span>
  <span>Cherry</span>
  <span class="badge">Last!</span>
</div>

Use Cases

1. Product Grid

<div class="product-grid" dbind_repeat="products">
  <article class="product-card">
    <img dbind_src="image" dbind_alt="name" loading="lazy">
    <h3 dbind_data="name"></h3>
    <p dbind_data="description"></p>
    <div class="price-rating">
      <span dbind_data="price" dbind_format="currency:USD"></span>
      <span dbind_data="rating">★</span>
    </div>
    <a dbind_href="url" class="btn-view">View Details</a>
  </article>
</div>

2. Navigation Menu

<nav class="main-nav">
  <a dbind_repeat="menuItems" dbind_href="url" dbind_data="label" class="nav-link"></a>
</nav>

3. Feature List

<ul class="feature-list">
  <li dbind_repeat="features">
    <span class="icon" dbind_data="icon"></span>
    <strong dbind_data="title"></strong>
    <p dbind_data="description"></p>
  </li>
</ul>

4. Team Members

<div class="team-grid">
  <div dbind_repeat="team" class="team-member">
    <img dbind_src="photo" dbind_alt="name" class="avatar">
    <h4 dbind_data="name"></h4>
    <span class="title" dbind_data="jobTitle"></span>
    <div class="social-links">
      <a dbind_href="twitter" dbind_show="twitter">Twitter</a>
      <a dbind_href="linkedin" dbind_show="linkedin">LinkedIn</a>
    </div>
  </div>
</div>

5. Blog Post List

<div class="blog-posts">
  <article dbind_repeat="posts" class="post-card">
    <img dbind_src="featuredImage" dbind_alt="title" class="post-image">
    <div class="post-meta">
      <span class="category" dbind_data="category"></span>
      <time dbind_data="publishedAt" dbind_format="date:medium"></time>
    </div>
    <h2 dbind_data="title"></h2>
    <p dbind_data="excerpt"></p>
    <div class="post-footer">
      <span class="author" dbind_data="author.name"></span>
      <a dbind_href="url">Read More →</a>
    </div>
  </article>
</div>

6. Data Table

<table class="data-table">
  <thead>
    <tr>
      <th>#</th>
      <th>Name</th>
      <th>Email</th>
      <th>Status</th>
    </tr>
  </thead>
  <tbody>
    <tr dbind_repeat="users">
      <td>{{_number}}</td>
      <td dbind_data="name"></td>
      <td dbind_data="email"></td>
      <td>
        <span class="status-badge" dbind_class="statusClass" dbind_data="status"></span>
      </td>
    </tr>
  </tbody>
</table>

7. Alternating Row Colors

<div dbind_repeat="items" class="row" dbind_class="rowClass">
  <span dbind_data="name"></span>
</div>

Data:

{
  "items": [
    { "name": "Row 1", "rowClass": "row-odd" },
    { "name": "Row 2", "rowClass": "row-even" },
    { "name": "Row 3", "rowClass": "row-odd" }
  ]
}

Or use _even / _odd:

<div dbind_repeat="items" class="row">
  <span dbind_show="_odd" class="odd-indicator">●</span>
  <span dbind_data="name"></span>
</div>

dbind_repeat-empty

Purpose: Provide fallback content when the repeated array is empty. This is an alias for dbind_empty that's more semantically clear when used with lists.

Syntax:

<element dbind_repeat-empty="arrayField">
  <!-- Shown when arrayField is empty or missing -->
</element>

Basic Usage

<!-- Product list -->
<div class="products">
  <div dbind_repeat="products" class="product-card">
    <h3 dbind_data="name"></h3>
  </div>
</div>

<!-- Empty state -->
<div class="empty-state" dbind_repeat-empty="products">
  <img src="/images/no-products.svg" alt="No products">
  <h3>No products found</h3>
  <p>Try adjusting your search or filters.</p>
</div>

Use Cases

1. Search Results Empty State

<div class="search-container">
  <input type="text" dbind_search="results" placeholder="Search...">

  <div class="results-list">
    <div dbind_repeat="results" class="result-item">
      <h4 dbind_data="title"></h4>
      <p dbind_data="snippet"></p>
    </div>
  </div>

  <div class="no-results" dbind_repeat-empty="results">
    <img src="/images/no-results.svg" alt="">
    <h3>No results found</h3>
    <p>We couldn't find anything matching your search.</p>
    <button onclick="clearSearch()">Clear Search</button>
  </div>
</div>

2. Empty Shopping Cart

<div class="cart-items">
  <div dbind_repeat="cartItems" class="cart-item">
    <img dbind_src="image" dbind_alt="name">
    <span dbind_data="name"></span>
    <span dbind_data="price" dbind_format="currency:USD"></span>
  </div>
</div>

<div class="empty-cart" dbind_repeat-empty="cartItems">
  <span class="cart-icon">🛒</span>
  <h2>Your cart is empty</h2>
  <p>Looks like you haven't added anything yet.</p>
  <a href="/products" class="btn-primary">Start Shopping</a>
</div>

3. Empty Dashboard

<div class="dashboard-grid">
  <div dbind_repeat="projects" class="project-card">
    <h3 dbind_data="name"></h3>
    <p dbind_data="description"></p>
  </div>
</div>

<div class="getting-started" dbind_repeat-empty="projects">
  <h2>Welcome! Let's create your first project.</h2>
  <div class="steps">
    <div class="step">
      <span class="step-number">1</span>
      <p>Click "New Project" to get started</p>
    </div>
    <div class="step">
      <span class="step-number">2</span>
      <p>Give your project a name and description</p>
    </div>
    <div class="step">
      <span class="step-number">3</span>
      <p>Invite your team members</p>
    </div>
  </div>
  <button class="btn-primary">+ Create Project</button>
</div>

dbind_filter

Purpose: Filter the repeated items to show only those matching a condition.

Syntax:

<!-- Filter by exact field value -->
<element dbind_repeat="items" dbind_filter="field:value"></element>

<!-- Filter by multiple values -->
<element dbind_repeat="items" dbind_filter="field:value1,value2"></element>

Basic Usage

<!-- Show only active products -->
<div dbind_repeat="products" dbind_filter="status:active">
  <h3 dbind_data="name"></h3>
</div>

<!-- Show only electronics category -->
<div dbind_repeat="products" dbind_filter="category:electronics">
  <h3 dbind_data="name"></h3>
</div>

Data:

{
  "products": [
    { "name": "Laptop", "category": "electronics", "status": "active" },
    { "name": "Shirt", "category": "clothing", "status": "active" },
    { "name": "Phone", "category": "electronics", "status": "inactive" }
  ]
}

Result (electronics filter):

<div><h3>Laptop</h3></div>
<div><h3>Phone</h3></div>

Multiple Value Matching

<!-- Show electronics OR clothing -->
<div dbind_repeat="products" dbind_filter="category:electronics,clothing">
  <h3 dbind_data="name"></h3>
</div>

Use Cases

1. Category Tabs

<div class="category-tabs">
  <button data-category="all">All</button>
  <button data-category="electronics">Electronics</button>
  <button data-category="clothing">Clothing</button>
</div>

<!-- Show all products (no filter) -->
<div id="all-products" dbind_repeat="products">
  <div class="product" dbind_data="name"></div>
</div>

<!-- Show only electronics -->
<div id="electronics" dbind_repeat="products" dbind_filter="category:electronics" style="display:none;">
  <div class="product" dbind_data="name"></div>
</div>

<!-- Show only clothing -->
<div id="clothing" dbind_repeat="products" dbind_filter="category:clothing" style="display:none;">
  <div class="product" dbind_data="name"></div>
</div>

2. Status Sections

<!-- Active tasks -->
<section class="active-tasks">
  <h2>Active Tasks</h2>
  <div dbind_repeat="tasks" dbind_filter="status:active">
    <div class="task" dbind_data="title"></div>
  </div>
</section>

<!-- Completed tasks -->
<section class="completed-tasks">
  <h2>Completed</h2>
  <div dbind_repeat="tasks" dbind_filter="status:completed">
    <div class="task completed" dbind_data="title"></div>
  </div>
</section>
<!-- Featured products section -->
<section class="featured">
  <h2>Featured Products</h2>
  <div dbind_repeat="products" dbind_filter="featured:true">
    <div class="product-card featured">
      <h3 dbind_data="name"></h3>
    </div>
  </div>
</section>

<!-- Regular products -->
<section class="all-products">
  <h2>All Products</h2>
  <div dbind_repeat="products">
    <div class="product-card">
      <h3 dbind_data="name"></h3>
    </div>
  </div>
</section>

dbind_sort

Purpose: Sort the repeated items by a field value.

Syntax:

<!-- Sort ascending (default) -->
<element dbind_repeat="items" dbind_sort="field"></element>

<!-- Sort descending -->
<element dbind_repeat="items" dbind_sort="field:desc"></element>

<!-- Sort ascending explicitly -->
<element dbind_repeat="items" dbind_sort="field:asc"></element>

Basic Usage

<!-- Sort by name alphabetically -->
<div dbind_repeat="products" dbind_sort="name">
  <h3 dbind_data="name"></h3>
</div>

<!-- Sort by price (highest first) -->
<div dbind_repeat="products" dbind_sort="price:desc">
  <h3 dbind_data="name"></h3>
  <span dbind_data="price" dbind_format="currency:USD"></span>
</div>

<!-- Sort by date (newest first) -->
<div dbind_repeat="posts" dbind_sort="publishedAt:desc">
  <h2 dbind_data="title"></h2>
  <time dbind_data="publishedAt" dbind_format="date:medium"></time>
</div>

Use Cases

1. Leaderboard

<div class="leaderboard">
  <h2>Top Players</h2>
  <div dbind_repeat="players" dbind_sort="score:desc">
    <div class="player-row">
      <span class="rank">{{_number}}</span>
      <span class="name" dbind_data="name"></span>
      <span class="score" dbind_data="score"></span>
    </div>
  </div>
</div>

2. Product List with Sort Options

<select id="sort-select" onchange="updateSort()">
  <option value="name:asc">Name (A-Z)</option>
  <option value="name:desc">Name (Z-A)</option>
  <option value="price:asc">Price (Low to High)</option>
  <option value="price:desc">Price (High to Low)</option>
  <option value="rating:desc">Best Rated</option>
</select>

<!-- Default: Sort by name -->
<div id="products-by-name" dbind_repeat="products" dbind_sort="name">
  <div class="product" dbind_data="name"></div>
</div>

3. Blog Posts by Date

<div class="blog-posts" dbind_repeat="posts" dbind_sort="createdAt:desc">
  <article class="post">
    <time dbind_data="createdAt" dbind_format="date:long"></time>
    <h2 dbind_data="title"></h2>
  </article>
</div>

Combining Sort with Filter

<!-- Featured products, sorted by price -->
<div dbind_repeat="products" dbind_filter="featured:true" dbind_sort="price:asc">
  <div class="product-card">
    <h3 dbind_data="name"></h3>
    <span dbind_data="price" dbind_format="currency:USD"></span>
  </div>
</div>

dbind_limit

Purpose: Limit the number of items displayed from the repeated array.

Syntax:

<element dbind_repeat="items" dbind_limit="number"></element>

Basic Usage

<!-- Show only first 3 products -->
<div dbind_repeat="products" dbind_limit="3">
  <div class="product" dbind_data="name"></div>
</div>

Use Cases

<section class="featured-products">
  <h2>Top 4 Products</h2>
  <div class="product-grid" dbind_repeat="products" dbind_sort="sales:desc" dbind_limit="4">
    <div class="product-card">
      <h3 dbind_data="name"></h3>
    </div>
  </div>
  <a href="/products">View All Products →</a>
</section>

2. Recent Posts Widget

<aside class="recent-posts">
  <h3>Recent Posts</h3>
  <ul dbind_repeat="posts" dbind_sort="publishedAt:desc" dbind_limit="5">
    <li>
      <a dbind_href="url" dbind_data="title"></a>
      <time dbind_data="publishedAt" dbind_format="date:relative"></time>
    </li>
  </ul>
</aside>

3. Preview with "Show More"

<div class="comments-section">
  <!-- Initial 3 comments -->
  <div id="comments-preview" dbind_repeat="comments" dbind_limit="3">
    <div class="comment">
      <strong dbind_data="author"></strong>
      <p dbind_data="text"></p>
    </div>
  </div>

  <button id="show-all-comments" onclick="showAllComments()">
    Show all <span dbind_data="comments.length"></span> comments
  </button>
</div>

4. Top Contributors

<div class="top-contributors">
  <h3>Top 5 Contributors</h3>
  <div dbind_repeat="contributors" dbind_sort="contributions:desc" dbind_limit="5">
    <div class="contributor">
      <img dbind_src="avatar" dbind_alt="name" class="avatar">
      <span dbind_data="name"></span>
      <span class="contributions" dbind_data="contributions"></span>
    </div>
  </div>
</div>

Combining Limit with Filter and Sort

<!-- Top 3 active products by rating -->
<div dbind_repeat="products" dbind_filter="status:active" dbind_sort="rating:desc" dbind_limit="3">
  <div class="product">
    <h3 dbind_data="name"></h3>
    <span class="rating" dbind_data="rating">⭐</span>
  </div>
</div>

Nested Lists

You can nest dbind_repeat to render hierarchical data:

Basic Nested Example

<div dbind_repeat="categories">
  <h2 dbind_data="name"></h2>
  <div class="products" dbind_repeat="products">
    <div class="product" dbind_data="name"></div>
  </div>
</div>

Data:

{
  "categories": [
    {
      "name": "Electronics",
      "products": [
        { "name": "Laptop" },
        { "name": "Phone" }
      ]
    },
    {
      "name": "Clothing",
      "products": [
        { "name": "T-Shirt" },
        { "name": "Jeans" }
      ]
    }
  ]
}

Use Cases for Nested Lists

1. Accordion Menu

<div class="accordion-menu">
  <div dbind_repeat="sections" class="accordion-section">
    <h3 class="section-header" dbind_data="title"></h3>
    <ul class="section-content">
      <li dbind_repeat="items">
        <a dbind_href="url" dbind_data="label"></a>
      </li>
    </ul>
  </div>
</div>

2. Order with Line Items

<div dbind_repeat="orders" class="order-card">
  <div class="order-header">
    <span>Order #<span dbind_data="orderNumber"></span></span>
    <span dbind_data="date" dbind_format="date:medium"></span>
  </div>
  <div class="order-items">
    <div dbind_repeat="items" class="order-item">
      <span dbind_data="name"></span>
      <span>x<span dbind_data="quantity"></span></span>
      <span dbind_data="price" dbind_format="currency:USD"></span>
    </div>
  </div>
  <div class="order-total">
    Total: <span dbind_data="total" dbind_format="currency:USD"></span>
  </div>
</div>

3. Comments with Replies

<div class="comments">
  <div dbind_repeat="comments" class="comment">
    <div class="comment-header">
      <img dbind_src="author.avatar" dbind_alt="author.name">
      <span dbind_data="author.name"></span>
    </div>
    <p dbind_data="text"></p>

    <!-- Nested replies -->
    <div class="replies" dbind_show="replies">
      <div dbind_repeat="replies" class="reply">
        <span dbind_data="author.name"></span>
        <p dbind_data="text"></p>
      </div>
    </div>
  </div>
</div>

Complete Example: Filterable Product Grid

<div class="product-page">
  <!-- Filter Controls -->
  <aside class="filters">
    <h3>Category</h3>
    <select id="category-filter">
      <option value="">All Categories</option>
      <option value="electronics">Electronics</option>
      <option value="clothing">Clothing</option>
      <option value="home">Home & Garden</option>
    </select>

    <h3>Sort By</h3>
    <select id="sort-by">
      <option value="name:asc">Name (A-Z)</option>
      <option value="price:asc">Price: Low to High</option>
      <option value="price:desc">Price: High to Low</option>
      <option value="rating:desc">Top Rated</option>
    </select>
  </aside>

  <!-- Products Grid -->
  <main class="products-container">
    <!-- All products (default view) -->
    <div id="all-products" class="product-grid">
      <div dbind_repeat="products" dbind_sort="name:asc" class="product-card">
        <img dbind_src="image" dbind_alt="name" loading="lazy">
        <div class="product-info">
          <span class="category-badge" dbind_data="category"></span>
          <h3 dbind_data="name"></h3>
          <div class="rating">
            <span dbind_data="rating"></span>⭐
            <span>(<span dbind_data="reviewCount"></span> reviews)</span>
          </div>
          <p class="price" dbind_data="price" dbind_format="currency:USD"></p>
          <span class="stock" dbind_if="stock<=5">Only <span dbind_data="stock"></span> left!</span>
        </div>
        <button class="btn-add-cart" dbind_unless="stock==0">Add to Cart</button>
        <button class="btn-notify" dbind_if="stock==0">Notify Me</button>
      </div>
    </div>

    <!-- Empty state -->
    <div class="no-products" dbind_repeat-empty="products">
      <img src="/images/no-products.svg" alt="">
      <h2>No products found</h2>
      <p>Try adjusting your filters or search terms.</p>
      <button onclick="clearFilters()">Clear All Filters</button>
    </div>
  </main>
</div>

<!-- Pagination -->
<nav class="pagination">
  <a href="#" class="prev" dbind_show="hasPrevPage">← Previous</a>
  <span class="page-info">
    Page <span dbind_data="currentPage"></span> of <span dbind_data="totalPages"></span>
  </span>
  <a href="#" class="next" dbind_show="hasNextPage">Next →</a>
</nav>

Data:

{
  "products": [
    {
      "name": "Wireless Headphones",
      "category": "electronics",
      "price": 149.99,
      "rating": 4.5,
      "reviewCount": 234,
      "stock": 15,
      "image": "/images/headphones.jpg"
    },
    {
      "name": "Cotton T-Shirt",
      "category": "clothing",
      "price": 29.99,
      "rating": 4.2,
      "reviewCount": 89,
      "stock": 3,
      "image": "/images/tshirt.jpg"
    },
    {
      "name": "Smart Watch",
      "category": "electronics",
      "price": 299.99,
      "rating": 4.8,
      "reviewCount": 567,
      "stock": 0,
      "image": "/images/watch.jpg"
    }
  ],
  "currentPage": 1,
  "totalPages": 5,
  "hasPrevPage": false,
  "hasNextPage": true
}

Performance Considerations

Large Lists

For lists with many items:

  1. Use Pagination: Break large lists into pages
  2. Use Limits: Show initial subset with "Load More"
  3. Virtual Scrolling: For very long lists, consider client-side virtual scrolling
<!-- Initial load with limit -->
<div id="items-container" dbind_repeat="items" dbind_limit="20">
  <div class="item" dbind_data="name"></div>
</div>

<button id="load-more" onclick="loadMoreItems()">
  Load More
</button>

Lazy Loading Images

Always add loading="lazy" to images in lists:

<div dbind_repeat="products">
  <img dbind_src="image" dbind_alt="name" loading="lazy">
</div>

Next Steps