How to Create Filter Combinations Like Bodyweight Chest Exercises in the Exercises Dataset

You can create bodyweight chest filter combinations by intersecting independent Equipment, Category, and Target Muscle criteria in the interactive browser or by programmatically filtering the JSON dataset.

The hasaneyldrm/exercises-dataset repository ships with a vanilla-JavaScript exercise browser that supports multi-dimensional filtering out of the box. When you need to create filter combinations like bodyweight chest exercises, the browser's applyFilters() function in index.html intersects active selections from three independent groups against the full catalog stored in data/exercises.json. This guide breaks down the engine and shows how to replicate the logic in your own projects.

How the Filter Logic Works in index.html

The browser constructs three independent filter groups—Category, Equipment, and Target Muscle—from distinct values discovered in data/exercises.json. Each group is rendered as a set of clickable chips that manipulate a shared state.filters object. When any filter or search term changes, the applyFilters() function recomputes the visible list by requiring every active criterion to match, producing a strict logical AND across all dimensions.

Rendering Filter Chips with renderChips

The renderChips() function in index.html generates a clickable button for every distinct value inside a filter dimension. It also appends a show more toggle when the number of values exceeds the visible limit, keeping the sidebar uncluttered while still exposing every possible filter value.

Toggling Filter State with toggleFilter

Each chip click triggers toggleFilter(), which adds or removes the selected value from the appropriate Set stored in state.filters. Because the state uses native JavaScript Set objects, duplicate entries are impossible and membership tests remain constant-time.

Applying Combined Filters with applyFilters

The core intersection logic lives in applyFilters() within index.html. It iterates over the full exercise array and retains only records whose pre-computed search index (_idx) matches the current query and whose category, equipment, and target properties are all present in the corresponding active filter sets. If no filters are active for a given dimension, that dimension is skipped, allowing combinations of any granularity—from a single equipment type to a fully qualified bodyweight-chest-target triad.

Step-by-Step Example: Bodyweight Chest Exercises

Using the Interactive UI

To obtain bodyweight chest exercises without writing any code, follow these steps in the browser:

  1. Open index.html in any modern web browser.
  2. Click the Equipment chip labeled body weight.
  3. Click the Category chip labeled chest (or the Target Muscle chip for pectoralis work).
  4. Review the filtered grid and the removable active badges at the top of the results pane.

Programmatic Filtering in JavaScript

You can reproduce the browser's applyFilters() behavior in your own scripts by loading data/exercises.json and chaining equality checks. The pattern below mirrors the checks found inside the filter logic in index.html:

// Load the dataset (already available as EXERCISES in index.html)
const exercises = EXERCISES;

// Helper to filter by equipment and category
function filterBodyweightChest(data) {
  return data.filter(
    ex => ex.equipment === 'body weight' && ex.category === 'chest'
  );
}

// Example usage
const bodyweightChest = filterBodyweightChest(exercises);
console.log('Body-weight chest exercises:', bodyweightChest.length);
console.table(bodyweightChest.map(e => ({ id: e.id, name: e.name })));

Passing exercises through this function yields only records that satisfy both constraints, identical to the UI's logical AND behavior.

Building a Custom Filter Interface

If you want to embed this logic into a bespoke layout, reuse the existing createCard() renderer while supplying your own controls. The snippet below wires two <select> elements to the dataset:

// Assume you have two <select> elements: #equipmentSelect and #categorySelect
document.getElementById('applyBtn').addEventListener('click', () => {
  const eq = document.getElementById('equipmentSelect').value;
  const cat = document.getElementById('categorySelect').value;

  const filtered = EXERCISES.filter(
    ex => (eq === '' || ex.equipment === eq) &&
          (cat === '' || ex.category === cat)
  );

  // Render the result grid (reuse the createCard function from index.html)
  const grid = document.getElementById('exercise-grid');
  grid.innerHTML = '';
  filtered.forEach(ex => grid.appendChild(createCard(ex)));
});

This preserves the repository's card styling and event bindings while letting you define arbitrary filter combinations programmatically.

Summary

  • The exercise browser in index.html groups filters into Category, Equipment, and Target Muscle chips via renderChips().
  • Clicks update state.filters through toggleFilter(), which tracks active values in memory-efficient Set objects.
  • applyFilters() intersects all active criteria with a logical AND against data/exercises.json, enabling precise combinations like bodyweight chest exercises.
  • You can replicate or extend this behavior in custom JavaScript by filtering the EXERCISES array on equipment, category, and target fields.

Frequently Asked Questions

How does the exercise browser combine multiple filter selections?

The browser collects active values into state.filters and evaluates them inside applyFilters() in index.html. Each exercise must satisfy every active dimension simultaneously, so selecting body weight under Equipment and chest under Category returns only exercises that match both properties. This strict logical AND is what makes precise combinations possible.

Which data fields support filter combinations?

The underlying data/exercises.json supplies category, equipment, and target fields for every record. The UI surfaces these three columns as independent chip groups, and you can use the same fields in custom scripts to build comparable queries. No other schema transformations are required.

Can I filter exercises without using the provided web interface?

Yes. Because the dataset is a flat JSON array, you can load data/exercises.json directly and call Array.prototype.filter() on properties such as equipment and category. This approach bypasses index.html entirely while producing identical bodyweight chest subsets.

Where is the active filter state stored?

Filter state is maintained in a global state object inside index.html, specifically within state.filters, which contains a Set for each dimension. toggleFilter() mutates these sets, and applyFilters() reads them on every user interaction to refresh the results grid. The active badges rendered by updateActiveBadges reflect the same underlying state.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →