如何为我的画廊过滤器添加多项选择系统

发布于 2025-01-29 23:30:47 字数 3639 浏览 1 评论 0原文

我正在为我的WebDev编队做一个虚构的项目,我只需要一点帮助即可为我的画廊修复过滤系统。它非常简单,您单击一个类别,图库显示与该类别相对应的图像。一切(最终)效果很好,只有两个不断困扰我的问题是:

- 一旦检查一个类别,我无法取消选中它,而必须检查另一个类别(这会自动取消选中上一个类别);
- 正如我的问题的标题所暗示的那样,我只能一次选择一个类别。

我希望用户能够检查多个类别以显示与所选类别相对应的所有照片,因此意味着I希望用户能够取消选中类别,并且如果未检查类别,则画廊将显示API的所有照片。

感谢您的帮助和研究。

import Head from 'next/head'
import Image from 'next/image'
import { useRouter } from 'next/router'
import { useState } from 'react'
import Nav from '../components/nav'
import styles from '../styles/style.module.css'

export default function Gallery({ res, res2 }) {
  const [targetCategory, setTargetCategory] = useState("");

  return(
    <main className={`${styles.container} ${styles.gallery}`}>
      {/* NAVBAR */}
      <div className={`${styles.menu}`}>
        <Nav />
      </div>

      {/* GALLERY FILTER - MOBILE COLLAPSIBLE */}
      <div className={`${styles.filter}`}>
        <div className="container-fluid">
          <nav className="navbar navbar-expand-lg">
            <button className="navbar-toggler text-white" 
              type="button" 
              data-bs-toggle="collapse" 
              data-bs-target="#filterContent" 
              aria-controls="filterContent" 
              aria-expanded="false" 
              aria-label="Toggle navigation">
              <span className="align-self-center">Filtres</span>
              <i className="bi bi-list fs-1"/>
            </button>
          
            <div className="collapse navbar-collapse" id="filterContent">
              <form id="img-sort" action="">
                <ul className="nav navbar-nav">
                  {res2.data.map((category) => (
                    <>
                    <label key={category.id} className={styles.formControl}>
                      <input 
                      type="checkbox" 
                      name="checkbox"
                      id={category.attributes.name}
                      value={category.attributes.name}
                      checked={targetCategory === category.attributes.name} 
                      onClick={(e) => setTargetCategory(e.target.value)}/>
                      {category.attributes.name}
                    </label>
                    </>
                  ))}
                </ul>
              </form>
            </div>

          </nav>
        </div>
      </div>

      {/* GALLERY CONTENT */}
      <div className={`${styles.pictures_holder}`}>
        <div className={`${styles.pictures}`}>
          {res.data.filter((photo) => photo.attributes.category.data.attributes.name.includes(targetCategory)).map((photo) => (
            <div key={res.id}>
              <img
              src={`http://localhost:1337` + photo.attributes.img.data[0].attributes.formats.small.url} 
              alt={photo.attributes.img.data[0].attributes.formats.small.name}
              />
              <p className="text-white text-center">{photo.attributes.name}</p>
            </div>
          ))}
        </div>
      </div>
    </main>
  )
}


export async function getStaticProps() {
  try {
    const res = await fetch("http://localhost:1337/api/photos?populate=*").then((res) => res.json());
    const res2 = await fetch("http://localhost:1337/api/categories?populate=*").then((res2) => res2.json());
    
    return {
      props: { res, res2 }
    };

  } catch (err) {
    console.error(err);
  }
}

I'm working on a fictive project for my webdev formation, and I would need just a little help in fixing my filter system for my gallery. It's pretty straightforward, you click on a category and the gallery displays the images corresponding to the category. Everything (finally) works pretty nicely, the only two problems that keep bugging me are:

-Once a category is checked, I can't uncheck it and have to check another category instead (which automatically unchecks the previous one);
-And as the title of my question suggests, I can only select one category at a time.

I would like the user to be able to check multiple categories in order to display all photos corresponding to the categories selected, thus meaning I would like the user to be able to uncheck a category, and if no categories are checked, then the gallery would display all photos of the api.

Thank you for your help and your research.

import Head from 'next/head'
import Image from 'next/image'
import { useRouter } from 'next/router'
import { useState } from 'react'
import Nav from '../components/nav'
import styles from '../styles/style.module.css'

export default function Gallery({ res, res2 }) {
  const [targetCategory, setTargetCategory] = useState("");

  return(
    <main className={`${styles.container} ${styles.gallery}`}>
      {/* NAVBAR */}
      <div className={`${styles.menu}`}>
        <Nav />
      </div>

      {/* GALLERY FILTER - MOBILE COLLAPSIBLE */}
      <div className={`${styles.filter}`}>
        <div className="container-fluid">
          <nav className="navbar navbar-expand-lg">
            <button className="navbar-toggler text-white" 
              type="button" 
              data-bs-toggle="collapse" 
              data-bs-target="#filterContent" 
              aria-controls="filterContent" 
              aria-expanded="false" 
              aria-label="Toggle navigation">
              <span className="align-self-center">Filtres</span>
              <i className="bi bi-list fs-1"/>
            </button>
          
            <div className="collapse navbar-collapse" id="filterContent">
              <form id="img-sort" action="">
                <ul className="nav navbar-nav">
                  {res2.data.map((category) => (
                    <>
                    <label key={category.id} className={styles.formControl}>
                      <input 
                      type="checkbox" 
                      name="checkbox"
                      id={category.attributes.name}
                      value={category.attributes.name}
                      checked={targetCategory === category.attributes.name} 
                      onClick={(e) => setTargetCategory(e.target.value)}/>
                      {category.attributes.name}
                    </label>
                    </>
                  ))}
                </ul>
              </form>
            </div>

          </nav>
        </div>
      </div>

      {/* GALLERY CONTENT */}
      <div className={`${styles.pictures_holder}`}>
        <div className={`${styles.pictures}`}>
          {res.data.filter((photo) => photo.attributes.category.data.attributes.name.includes(targetCategory)).map((photo) => (
            <div key={res.id}>
              <img
              src={`http://localhost:1337` + photo.attributes.img.data[0].attributes.formats.small.url} 
              alt={photo.attributes.img.data[0].attributes.formats.small.name}
              />
              <p className="text-white text-center">{photo.attributes.name}</p>
            </div>
          ))}
        </div>
      </div>
    </main>
  )
}


export async function getStaticProps() {
  try {
    const res = await fetch("http://localhost:1337/api/photos?populate=*").then((res) => res.json());
    const res2 = await fetch("http://localhost:1337/api/categories?populate=*").then((res2) => res2.json());
    
    return {
      props: { res, res2 }
    };

  } catch (err) {
    console.error(err);
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文