+ `,
+ styleUrls: ['./app.component.less', './edit-ruleset-dialog.component.less']
+})
+export class EditRulesetDialogComponent {
+ text: string;
+ state: 'valid' | 'invalid-json' | 'invalid-query' = 'valid';
+
+ constructor(
+ public dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public data: EditRulesetDialogData
+ ) {
+ this.text = JSON.stringify(data.ruleset, null, 2);
+ this.validate();
+ }
+
+ onChange(value: string): void {
+ this.text = value;
+ this.validate();
+ }
+
+ private validate(): void {
+ try {
+ const val = JSON.parse(this.text.trim());
+ if (this.data.validate(val)) {
+ this.state = 'valid';
+ } else {
+ this.state = 'invalid-query';
+ }
+ } catch {
+ this.state = 'invalid-json';
+ }
+ }
+
+ save(): void {
+ try {
+ const val = JSON.parse(this.text.trim());
+ if (this.data.validate(val)) {
+ this.dialogRef.close(val);
+ }
+ } catch {
+ // ignore
+ }
+ }
+}
diff --git a/projects/ngx-query-builder-demo/src/styles.less b/projects/ngx-query-builder-demo/src/styles.less
index 0136798a..bcc0f7aa 100644
--- a/projects/ngx-query-builder-demo/src/styles.less
+++ b/projects/ngx-query-builder-demo/src/styles.less
@@ -1,3 +1,15 @@
/* You can add global styles to this file, and also import other style files */
+@import '@angular/material/prebuilt-themes/indigo-pink.css';
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
+
+.cdk-overlay-pane.resizable-dialog {
+ resize: both;
+ overflow: auto;
+}
+
+.cdk-overlay-pane.resizable-dialog .mat-dialog-container {
+ max-width: none;
+ max-height: none;
+ height: 100%;
+}
diff --git a/projects/ngx-query-builder/README.md b/projects/ngx-query-builder/README.md
index ab720bed..a0a77d83 100644
--- a/projects/ngx-query-builder/README.md
+++ b/projects/ngx-query-builder/README.md
@@ -4,7 +4,18 @@
[](https://img.shields.io/npm/dt/@kerwin612%2Fngx-query-builder.svg)
[](https://gitpod.io/#https://github.com/kerwin612/ngx-query-builder)
-A modernized Angular 4+ query builder based on jQuery QueryBuilder. Support for heavy customization with Angular components and provides a flexible way to handle custom data types.
+A modernized Angular 4+ query builder based on jQuery QueryBuilder. Support for heavy customization with Angular components and provides a flexible way to handle custom data types.
+
+## Changes from kerwin612/ngx-query-builder
+
+- Upgraded Angular from version 18 to **19.2.14**.
+- Added optional **NOT** support for rulesets via the `allowNot` input.
+- Demo layout was revamped and now features a two-way bound JSON editor.
+- Editing the JSON textbox updates the query tree and vice versa.
+- The JSON editor validates input with lighter red for query errors and darker red for JSON errors.
+- Optional buttons allow converting a rule to a ruleset and back with `allowConvertToRuleset`.
+- Optional up/down arrows enable reordering rules when `allowRuleUpDown` is set.
+- Added a `customCollapsedSummary` callback to display summaries for collapsed rulesets.
***Forked from (https://github.com/zebzhao/Angular-QueryBuilder) as the original project has stopped updating and does not support the latest Angular versions, so I will continue to maintain it and support the latest versions of Angular.***
@@ -84,8 +95,8 @@ export class AppComponent {
##### `app.component.html`
```html
-
-
+
+
```
@@ -113,8 +124,14 @@ config: QueryBuilderConfig = {
#### `ngx-query-builder`
|Name| Type |Required| Default |Description|
|:--- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--- |:---------------------------------|:--- |
-|`allowRuleset`| `boolean` |Optional| `true` | Displays the `+ Ruleset` button if `true`. |
-|`allowCollapse`| `boolean` |Optional| `false` | Enables collapsible rule sets if `true`. |
+|`allowRuleset`| `boolean` |Optional| `true` | Displays the `+ Ruleset` button if `true`. |
+|`allowCollapse`| `boolean` |Optional| `true` | Enables collapsible rule sets if `true`. |
+|`allowConvertToRuleset`| `boolean` |Optional| `false` | Displays the `Convert to Ruleset` button if `true`. Rulesets with a single entry also show a `Convert to Rule` button (except the root ruleset). |
+|`allowRuleUpDown`| `boolean` |Optional| `false` | Displays up and down arrows on rules and nested rulesets for reordering. |
+|`ruleName`| `string` |Optional| `'Rule'` | Label used in default buttons for rules. |
+|`rulesetName`| `string` |Optional| `'Ruleset'` | Label used in default buttons for rulesets. |
+|`defaultRuleAttribute`| `string` |Optional| | Name of the field to use as the default when adding new rules. |
+|`allowNot`| `boolean` |Optional| `false` | Adds a `NOT` button and sets a `not` attribute on the ruleset JSON. |
|`classNames`| [`QueryBuilderClassNames`](/projects/ngx-query-builder/src/lib/models/query-builder.interfaces.ts#L48) |Optional| | CSS class names for different child elements in `query-builder` component. |
|`config`| [`QueryBuilderConfig`](/projects/ngx-query-builder/src/lib/models/query-builder.interfaces.ts#L85) |Required| | Configuration object for the main component. |
|`data`| [`Ruleset`](/projects/ngx-query-builder/src/lib/models/query-builder.interfaces.ts) |Optional| { condition: 'and', rules: [] } | (Use `ngModel` or `value` instead.) |
@@ -123,6 +140,8 @@ config: QueryBuilderConfig = {
|`operatorMap`| `{ [key: string]: string[] }` |Optional| | Used to map field types to list of operators. |
|`persistValueOnFieldChange`| `boolean` |Optional| `false` | If `true`, when a field changes to another of the same type, and the type is one of: string, number, time, date, or boolean, persist the previous value. This option is ignored if config.calculateFieldChangeValue is provided. |
|`config.calculateFieldChangeValue`| `(currentField: Field, nextField: Field, currentValue: any) => any` |Optional| | Used to calculate the new value when a rule's field changes. |
+|`config.customCollapsedSummary`| `(ruleset: RuleSet) => string` |Optional| | Generates a custom summary string when a ruleset is collapsed. |
+|`config.rulesetNameSanitizer`| `(value: string) => string` |Optional| | Sanitizes the name when naming or updating a ruleset. Defaults to `value.toUpperCase().replace(/ /g, '_').replace(/[^A-Z0-9_]/g, '')`. |
|`value`| [`Ruleset`](/projects/ngx-query-builder/src/lib/models/query-builder.interfaces.ts) |Optional| { condition: 'and', rules: [] } | Object that stores the state of the component. |
## Structural Directives
@@ -258,7 +277,7 @@ Can be used to customize the default empty warning message, alternatively can sp
|`getDisabledState`|`() => boolean`| Retrieves or determines the disabled state of the component|
## Dependencies
-- Angular 18+
+- Angular 19+
# Development
diff --git a/projects/ngx-query-builder/package.json b/projects/ngx-query-builder/package.json
index 54d842ee..75d9fbaa 100644
--- a/projects/ngx-query-builder/package.json
+++ b/projects/ngx-query-builder/package.json
@@ -10,10 +10,10 @@
"url": "https://github.com/kerwin612/ngx-query-builder/issues"
},
"homepage": "https://github.com/kerwin612/ngx-query-builder",
- "peerDependencies": {
- "@angular/common": "^18.1.0",
- "@angular/core": "^18.1.0"
- },
+ "peerDependencies": {
+ "@angular/common": "^19.0.0",
+ "@angular/core": "^19.0.0"
+ },
"dependencies": {
"tslib": "^2.3.0"
},
diff --git a/projects/ngx-query-builder/src/lib/components/add-named-ruleset-dialog.component.ts b/projects/ngx-query-builder/src/lib/components/add-named-ruleset-dialog.component.ts
new file mode 100644
index 00000000..ee0fe13b
--- /dev/null
+++ b/projects/ngx-query-builder/src/lib/components/add-named-ruleset-dialog.component.ts
@@ -0,0 +1,34 @@
+import { Component, Inject } from '@angular/core';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+
+export interface AddNamedRulesetDialogData {
+ names: string[];
+ rulesetName: string;
+}
+
+@Component({
+ selector: 'lib-add-named-ruleset-dialog',
+ standalone: false,
+ template: `
+