Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

180
Vistas
How to make a cumulative filter system in svelte (like amazon sidebar)

I have a svelte page to show a list of post, I need to give the user the ability to filter that list by several conditions, eg: year, tags, category, etc. All those conditions should be concurrent, just like the amazon website sidebar.

Using a derived store I got one filter working fine, but still I can't manage to get 2 or 3 filters applied at the same time.

For the "year" filter I have the following code:

import { readable, writable, derived } from "svelte/store";

export let data;
let posts = readable(data.posts);

const extractColumn = (arr, column) => arr.map((x) => x[column]);
const allYears = extractColumn(data.posts, "year");
const years = readable ([...new Set(allYears)]);
const filter = writable({ year: null });

const filteredPosts = derived([filter, posts], ([$filter, $posts]) => {
        if (!$filter.year) return $posts;
        return $posts.filter((x) => x.year === $filter.year);
    });

So, based in the posts list I can get the years array for the filter and then with a simple select trigger the filtering action, and this work pretty fine.

<select bind:value={$filter.year}>
    {#each $years as year}
        <option value={year}>{year}</option>
    {/each}
</select>

As I said at the beginning, the point is how to add complexity to this scenario to turn a simple filter into a system, with a variable number of dynamic cumulative filters.

Thanks for any idea.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You can loop over the props of an object with Object.entries Combine that with bracket notation to read props obj[prop] Throw in an array reduce to make it a simpler and you get:

return Object.entries($filter)
  .reduce(
    (pre, [key, value]) => pre.filter(x => x[key] == value), 
    $posts
  );

As an extra you could actually stores arrays in your filter instead so you can filter on multiple values:

{
  "year": [2022],
  "colour": ['red', 'green']
}

In that case use pre.filter(x => values.includes(x[key])) instead.

about 4 years ago · Juan Pablo Isaza Denunciar

0

To make this more universal I would start by 'automatically' generating the filter options

    const filterOptions = derived(posts, $posts => {

        // set the columns you'd like to have a filter for
        const columns = ['year', 'language']
        //  const columns = Object.keys($posts[0]) // or change to this to have a filter for every property

        return columns.reduce((filterOptions, column) => {
            filterOptions[column] = extractUniqueColumnValues($posts, column)
            return filterOptions
        }, {})
    })

    function extractUniqueColumnValues (arr, column) {
        return Array.from(new Set(arr.map((x) => x[column])))
    } 

and display them like this

{#each Object.entries($filterOptions) as [column, values]}
{column}
<select bind:value={$filter[column]}>
    <option value={null} ></option>
    {#each values as value}
    <option value={value}>{value}</option>
    {/each}
</select>
{/each}

filter can simply be

const filter = writable({});

(It is initially set to {year: null, language: null} via the select value bindings)

One way to filter the posts could be this (or using reduce like Stephane Vanraes` answer is showing)

const filteredPosts = derived([filter, posts], ([$filter, $posts]) => {
        Object.entries($filter).forEach(([key, value]) => {
            if(value !== null) $posts = $posts.filter(x => x[key] == value)
        })      
        return $posts
    });

Here's a REPL built on this

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda