shadcn:如何按应用名称过滤?

问题描述 投票:0回答:1

我正在构建一个简单的预算跟踪器,我想让用户按应用程序名称进行过滤。

下面是我的代码。

[
  {
    "status": "on",
    "id": "NZMwD83Nxg",
    "name": "GTA_UA_UAC_Android_01_DAU",
    "dailyBudget": 800,
    "apps": [
      {
        "name": "app 1",
        "icon": "https://marketing-0-7-0-85-220.png/230x0w.webp"
      },
      {
        "name": "app 2",
        "icon": "https://marketing-0-7-0-99-220.png/230x0w.webp"
      }
    ],
    "currency": "USD",
  },
  {
    "status": "on",
    "id": "aXly0x0vX6",
    "name": "GTA_UA_UAC_Android_02_DAU",
    "dailyBudget": 65,
    "apps": [
      {
        "name": "app 3",
        "icon": "https://marketing-0-7-0-85-220.png/230x0w.webp"
      }
    ],
    "currency": "USD",
  }
]

这是我的专栏类型。

type AppsType = {
  name: string;
  icon: string;
};

export type MainCampaign = {
  id: string;
  name: string;
  status: string;
  apps: AppsType[];
  dailyBudget: number;
  currency: string;
};

export const columns: ColumnDef<MainCampaign>[] = [
  {
    accessorKey: "icon",
    header: ({ column }) => (
      <Button
        variant="ghost"
        onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
      >
        Apps
        <ArrowUpDown className="ml-2 h-4 w-4" />
      </Button>
    ),
    cell: ({ row }) => {
      const apps: AppsType[] = row.getValue("apps");

      return (
        <div style={{ display: "flex", gap: "10px" }}>
          {apps.map((app, index) => (
            <Avatar key={index}>
              <AvatarImage src={app.icon} alt={app.name} />
              <AvatarFallback>{app.name}</AvatarFallback>
            </Avatar>
          ))}
        </div>
      );
    },
  },
  {
    accessorKey: "apps",
    header: ({ column }) => (
      <Button
        variant="ghost"
        onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
      >
        App Names
        <ArrowUpDown className="ml-2 h-4 w-4" />
      </Button>
    ),
    cell: ({ row }) => {
      const apps: AppsType[] = row.getValue("apps");
      return apps.map((app, index) => <div key={index}>{app.name}</div>);
    },
  },
{
    accessorKey: "name",
    header: ({ column }) => {
      return (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
        >
          Campaign Name
          <ArrowUpDown className="ml-2 h-4 w-4" />
        </Button>
      );
    },
  },
  ...
]

这是我现在在数据表中的输入,使用

apps
时有效,输入后没有结果。

<div className="flex items-center py-4">
  <Input
     id="filter-app"
     placeholder="Filter App..."
     value={table.getColumn("apps")?.getFilterValue()?.toString() ?? ""}
     onChange={(event) =>
     table.getColumn("apps")?.setFilterValue(event.target.value)
      }
     className="max-w-sm"
  />
</div>

我已经记录了应用程序名称,结果如下所示:[“app1”,“app2”],[“app3”]。我最初的想法是检查它们是否包含过滤器值,然后返回字符串,但是在实现该功能时我遇到了困难。

非常感谢您的指导。

reactjs shadcnui tanstack-table
1个回答
0
投票

我已经解决了这个问题,下面是我的实现。

 {
    accessorKey: "apps",
    header: ({ column }) => (
      <Button
        variant="ghost"
        onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
      >
        App Names
        <ArrowUpDown className="ml-2 h-4 w-4" />
      </Button>
    ),
    cell: ({ row }) => {
      const apps: AppsType[] = row.getValue("apps");
      return apps.map((app, index) => <div key={index}>{app.name}</div>);
    },
    filterFn: (
      row: Row<MainCampaign>,
      _cloumnId: string,
      filterValue: string
    ) => {
      const apps: AppsType[] = row.getValue("apps");
      return apps.some((app) =>
        app.name.toLowerCase().includes(filterValue.toLowerCase())
      );
    },
  },

这是我的数据表

 const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    onColumnFiltersChange: setColumnFilters,
    getFilteredRowModel: getFilteredRowModel(),
    onPaginationChange: setPagination,
    filterFns: {
      apps: (row, _columnId, value) => {
        const apps: AppsType[] = row.getValue("apps");
        const appsNameArr: string[] = apps.map((app) => app.name.toLowerCase());
        return appsNameArr.some((name) => name.toLowerCase().includes(value));
      },
    },
    state: {
      sorting,
      columnFilters,
      pagination,
    },
  });

我做了一些清理工作,在 util.ts 中提取了我的过滤器函数

所以会是这样的。

  {
    accessorKey: "apps",
    header: ({ column }) => (
      ...
    ),
    cell: ({ row }) => {
     ...
    },
    filterFn: customFilterFn,
  },
// data-table.tsx

const table = useReactTable({
    data,
    ...
    filterFns: {
      apps: customFilterFn,
    },
    state: {
      ...
    },
  });
© www.soinside.com 2019 - 2024. All rights reserved.