You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 22ed03f
Browse filesBrowse the repository at this point in the historyBrowse files
| multiple | boolean | false |`false`| The input renders multiple values itself (e.g. a multi-select) instead of being repeated as an array of inputs. |
383
-
| trim | boolean | false |`false`| Trim string values before they reach the model. |
384
-
| emptyToUndefined | boolean | false |`false`| Replace an empty string with `undefined` (applied after `trim`). |
385
-
| debounce | number | false | - | Debounce the value write to the model, in ms. A number (including `0`) defers the write; omitted = synchronous. |
| multiple | boolean | false |`false`| The input renders multiple values itself (e.g. a multi-select) instead of being repeated as an array of inputs. |
383
+
| trim | boolean | false |`false`| Trim string values before they reach the model. |
384
+
| emptyToUndefined | boolean | false |`false`| Replace an empty string with `undefined` (applied after `trim`). |
385
+
| debounce | number | false | - | Debounce the value write to the model, in ms. A number (including `0`) defers the write; omitted = synchronous. |
386
+
| inline | false or Component | false | - | Behavior in the collection's [filter row](Usage#column-filters) (only effective there). Omitted: the registered component is used inline. A component: a compact variant rendered inline instead. `false`: the input is never rendered inline, the column is edited through its popover only. |
386
387
387
388
By default, when a filter is used with `in` or `not_in` operators, the input component is repeated once per value. With `multiple: true`, your component is rendered only once and is responsible for managing the array of values itself.
388
389
390
+
The `inline` setting follows the same resolution as the component itself (`propertyInputs` > `typeInputs` > built-in inputs). All built-in inputs stay inline-capable by default.
Copy file name to clipboardExpand all lines: docs/Query-filter-format.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,6 +123,27 @@ A filter is removable by default but you can make it not removable by the user.
123
123
}
124
124
```
125
125
126
+
## Column marker
127
+
When [column filters](Usage#column-filters) are enabled on the collection, each filtered column owns one dedicated node at the root of the root group, marked with `column: <fieldId>`:
128
+
129
+
- a plain column is a `group` holding its conditions;
130
+
- a dotted column (e.g. `company.brand_name`) is a chain of `entity_condition` (`operator: 'has'`, plus `count_operator: '>=', count: 1` for relationship segments) with the marker on the outermost node and the group of conditions at the deepest point.
131
+
132
+
```js
133
+
{
134
+
type:'group',
135
+
operator:'and',
136
+
column:'first_name', // managed by the first_name column editor
The marker is internal bookkeeping: it survives the query builder round-trip but is stripped before the filter is sent to the server (like `key`, `editable` and `removable`). A tagged `entity_condition` whose group holds nothing effective is dropped entirely — a bare `has` is never sent because of a column filter.
144
+
145
+
If the marker is duplicated, the first node at the root wins. Children of a tagged group that the column editor did not create (scopes, sub-groups or conditions on other properties added through the query builder) are preserved and sent to the server, but the column editor neither displays nor counts them.
Copy file name to clipboardExpand all lines: docs/Types.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -52,7 +52,7 @@ Types used to type component props and models. See [Usage](Usage).
52
52
-`ItemClickHandler`, `FieldClickHandler`, `PostRequestHandler`, `RequestErrorHandler`, `ExportHandler` — the callback signatures for the handler props (`onItemClick`, `onFieldClick`, `postRequest`, `onRequestError`, `onExport`).
53
53
-`SortItemField`, `SortItemProperty` — a sort entry (`{ field, order }`), as used in `v-model:sort` and in request params.
54
54
-`CollectionType` — `'infinite' | 'pagination'`.
55
-
-`FieldsEditingLocation`, `SortEditingLocation`, `FilterEditingLocation`, `CollectionSortEditingLocation`— where each editor is mounted.
55
+
-`FieldsEditingLocation`, `SortEditingLocation`, `FilterEditingLocation`, `CollectionSortEditingLocation`, `CollectionFilterEditingLocation`— where each editor is mounted. `CollectionFilterEditingLocation` (`'collection-column' | 'collection-row' | 'none'`) is the collection-side subset for [column filters](Usage#column-filters).
Copy file name to clipboardExpand all lines: docs/Usage.md
+25-5Lines changed: 25 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -139,8 +139,11 @@ Props marked with 🔗 support two-way binding via `v-model:<key>`.
139
139
| sort | 🔗 | array | false | - | Sort order. Array of field ids (strings) or objects `{ field: string, order: 'asc'\|'desc' }`. |
140
140
| page | 🔗 | number | false |`1`| Current page number. |
141
141
| customFields || object | false | - | Permit to customize collection headers and cells rendering. More information [here](Usage#custom-fields). |
142
-
| filter || object | false | - | The raw filter. The collection runs `computeFilter` on it before requesting the server. |
143
-
| manual || boolean | false |`false`| If true, prop changes to `filter`/`fields` do not auto-request; call the exposed `submit()` method to trigger the request. Direct interactions in the collection UI (header sort, fields editor, pagination) always request immediately. |
142
+
| filter | 🔗 | object | false |`null`| The raw filter. The collection runs `computeFilter` on it before requesting the server. Two-way binding is only needed for [column filters](Usage#column-filters) (a one-way `:filter` binding keeps working: edits then live in the collection only). |
143
+
| filterEditingLocation || string | false |`'none'`| Where [column filters](Usage#column-filters) are edited: `'collection-column'` (funnel button + popover in each filterable header), `'collection-row'` (a filter row under the headers), or `'none'`. Prop-only: the global `filterEditingLocation` config applies to `QkitSearch` only. |
144
+
| allowedOperators || object | false | - | Restrict the operators offered by the column filter editors. Same format as the query builder prop ([here](Usage#allowed-operators)). |
145
+
| aliasInsensitiveLabels || boolean | false |`false`| Display case-insensitive operators with their case-sensitive label in the column filter editors. |
146
+
| manual || boolean | false |`false`| If true, prop changes to `filter`/`fields` do not auto-request; call the exposed `submit()` method to trigger the request. Direct interactions in the collection UI (header sort, fields editor, pagination) always request immediately. Column filter edits update the model but wait for the validate button of their popover. |
144
147
| debounce || number | false |`1000`| Time in ms to wait after a `filter`/`fields` change before requesting the server. `0` requests immediately. |
145
148
| directQuery || boolean | false |`true`| Request server and display results when component is mounted. |
146
149
| limit || number | false |`undefined`| The count limit of fetched items per page. |
@@ -210,6 +213,23 @@ const customFields = {
210
213
};
211
214
```
212
215
216
+
### Column filters
217
+
With `filterEditingLocation` set to `'collection-column'` or `'collection-row'`, users filter directly from the columns. The conditions live in the main filter (`v-model:filter`), each column owning one dedicated node marked `column: <fieldId>` at the root of the filter — see [the column marker](Query-filter-format#column-marker). The filter is then edited in the columns **or** in the query builder, never both.
218
+
219
+
A column is filterable when the request schema allows it, mirroring column sortability: every segment of the field's path must be filtrable in its entity, and the leaf property must not be a `relationship`/`object`/`morph_to` and must have at least one operator. Open custom fields are never filterable. Non-filterable columns show no filter control.
220
+
221
+
For a dotted column (e.g. `company.brand_name`), the conditions are edited with the leaf entity's schema and sent as a `has` relationship condition chain.
222
+
223
+
The editor is a compact condition list: per condition, an operator select (same operators as the query builder for the property type) and the value input, plus a **+** button that adds a condition on the column's property only. The and/or selector of the group appears from two conditions on. Removing the last condition removes the column's node from the filter.
224
+
225
+
**`'collection-column'` mode** — each filterable header shows a funnel button with a counter of the column's effective conditions (a defined value, or `null`/`not_null`). Clicking it opens a popover anchored under the header (native Popover API + CSS anchor positioning): one popover open at a time, Esc and light-dismiss supported, focus moves to the first field on open and back to the button on close.
226
+
227
+
**`'collection-row'` mode** — a row of cells under the headers. A column is edited directly in its cell when three conditions hold: at most one condition, no array operator (`in`/`not_in`, `contains`/`not_contains`) on an input without `multiple` (a multi-capable input such as an enum select stays inline), and an input allowed inline (see the [`inline` input setting](Plugin-initialization#input-settings)). Otherwise the cell shows the funnel + counter and editing happens in the popover — opened automatically when the fold is caused by a gesture made in the row (adding a second condition, switching to an array operator).
228
+
229
+
**Requests** — in auto mode edits reload live (debounced); a condition without a value does not trigger anything since the computed filter does not change. In `manual` mode edits only update the model (counter included) and a validate button appears in the popover (Enter is equivalent), wired to the exposed `submit()`. Header-click sorting stays immediate even in manual mode.
230
+
231
+
**Reflow** — when the table reflows to cards the headers are hidden, so both modes fall back to a funnel button in the collection's actions bar (visible in reflow only) opening a modal that lists each displayed filterable column with its editor. Edits happen on a working copy: confirming writes the model **and** requests (even in `manual` mode — confirming counts as validation); closing without confirming discards everything.
232
+
213
233
# Search component
214
234
The search component wires the query builder and the collection together into a ready-to-use search interface: what the user builds in the query builder drives what the collection queries and displays, with no glue code on your side.
215
235
@@ -245,11 +265,11 @@ Props marked with 🔗 support two-way binding via `v-model:<key>`.
| allowedProperties || object | false | - | Restrict allowed properties. More information [here](Usage#allowed-properties). |
247
267
| allowedScopes || object | false | - | Restrict allowed scopes. More information [here](Usage#allowed-scopes). |
248
-
| allowedOperators || object | false | - | Restrict allowed operators. More information [here](Usage#allowed-operators).|
268
+
| allowedOperators || object | false | - | Restrict allowed operators, in the query builder and in the column filter editors. More information [here](Usage#allowed-operators). |
249
269
| displayOperator || boolean or object | false |`true`| Display operators. More information [here](Usage#display-operator). |
250
270
| userTimezone || string | false |`'UTC'`| Display time in given timezone. |
251
271
| requestTimezone || string | false |`'UTC'`| Timezone to use when requesting server. |
252
-
| manual || boolean | false |`false`| If true, filter changes request the server only when the user clicks the validate button. Direct interactions in the collection UI (header sort, fields editor, pagination) always request immediately. |
272
+
| manual || boolean | false |`false`| If true, filter changes request the server only when the user clicks a validate button (in the query builder, or in a column filter popover). Direct interactions in the collection UI (header sort, fields editor, pagination) always request immediately. |
253
273
| directQuery || boolean | false |`true`| Request server and display results when component is mounted. |
254
274
| debounce || number | false |`1000`| Time in ms to wait after a `filter`/`fields` change before requesting the server. `0` requests immediately. |
255
275
| limit || number | false |`undefined`| The count limit of fetched items per page. |
@@ -258,7 +278,7 @@ Props marked with 🔗 support two-way binding via `v-model:<key>`.
| reflow || boolean | false |`false`| When the collection's own width is narrow (≤576px), reflow the table into stacked cards instead of a horizontally-scrolling table (container-based, not the viewport). |
261
-
| filterEditingLocation || string | false |`'query-builder'`| Where the filter builder is shown: `'query-builder'`or `'none'`. The query builder is rendered only when at least one of `filterEditingLocation`/`fieldsEditingLocation`/`sortEditingLocation` is `'query-builder'`. Defaults come from the plugin config. |
281
+
| filterEditingLocation || string | false |`'query-builder'`| Where the filter is edited: `'query-builder'`, `'collection-column'`or `'collection-row'` ([column filters](Usage#column-filters)), or `'none'`. Exclusive: the filter is edited in the query builder OR in the columns, never both. The query builder is rendered only when at least one of `filterEditingLocation`/`fieldsEditingLocation`/`sortEditingLocation` is `'query-builder'`. Defaults come from the plugin config. |
262
282
| fieldsEditingLocation || string | false |`'none'`| Where users can add/remove/reorder fields: `'query-builder'` (inline in the query builder), `'collection'` (columns button in the collection header), or `'none'`. |
263
283
| sortEditingLocation || string | false |`'collection-column'`| Where sort can be edited: `'query-builder'` (inline sort builder, sorts by any sortable property), `'collection-modal'` (sort editor button in the collection header), `'collection-column'` (sortable column headers), or `'none'`. |
264
284
| naturalSortWhenEmpty || boolean | false |`false`| When `sort` is empty, send the entity's `natural_sort` to the server (request-only). No-op without `natural_sort`. |
0 commit comments