1

I'm using a primereact datatable, and i have a column which is tags, every row of the table has an array of tags.

So i wanted to create a filter, where you have a multiselect form, displaying all the possible tags (the user shouldn't be able to write anything, just use the options the system gives).

I achieved this with a custom filterElement, but when i apply the filter, no matters which tag i select, it will give no results, i think is not filtering well.

I'm using this matchMode

tags: {
    operator: FilterOperator.AND,
    constraints: [{ value: null, matchMode: FilterMatchMode.IN }]
}

This is my column

<Column
    header="Tags"
    field="tags"
    style={{ minWidth: '16rem' }}
    filter
    filterElement={(options) => <TagsRowFilterTemplate options={options} />}
    sortable
    body={(contact) => <TagBodyTemplate contact={contact} tags={tags} />}
/>

And this is my TagsRowFilterTemplate component

export const TagsRowFilterTemplate = ({ options }: TagsFilterProps) => {
    const { tags } = useTags()

    return (
        <MultiSelect
            value={options.value ? tagsAsOptionFormat(options.value) : []}
            options={tags}
            onChange={(e: MultiSelectChangeEvent) => options.filterApplyCallback(e.value, options.index)}
            itemTemplate={itemTemplate}
            placeholder="Select One or More"
            optionLabel="name"
            className="p-column-filter"
            showClear
            style={{ minWidth: '12rem' }}
            maxSelectedLabels={3}
            filter
        />
    )
}

I tried using filterMatchMode, filterFunction, i tried user the matchmode: CONTAINS.

What i expect: To give an example, if i have 2 users:

John Doe with tags: ['foo', 'bar']

Jane Doe with tags: ['foo']

When i filter by foo i want to get jane and joe, but when i filter for bar i want to see only John

1 Answer 1

1

I finally solved using custom filtering in a bizarre way.
I guided myself with [this issue] (https://github.com/primefaces/primereact/issues/3325).
And with this codesandbox.
So i registered a new FilterService this way

FilterService.register(ArrayContainsMatchMode, tagRowFilterFunction)

const tagRowFilterFunction = (contactTagIds: string[], filterValue: Tag[]) => {
    if (!filterValue || !contactTagIds) return true
    if (filterValue.length === 0) return true
    else if (filterValue.length !== 0 && contactTagIds.length === 0) return false
    const selectedTags = filterValue.map((tag: Tag) => tag.tid)
    return selectedTags.every((tid) => contactTagIds.includes(tid))
}
Sign up to request clarification or add additional context in comments.

1 Comment

This helped me big time as I was attempting a very similar task with Primevue. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.