diff --git a/docs/en/UI/AspNetCore/AutoComplete-Select.md b/docs/en/UI/AspNetCore/AutoComplete-Select.md
index 86d8c14b8a..e0ad7ceb24 100644
--- a/docs/en/UI/AspNetCore/AutoComplete-Select.md
+++ b/docs/en/UI/AspNetCore/AutoComplete-Select.md
@@ -22,7 +22,8 @@ A simple usage is presented below.
data-autocomplete-display-property="name"
data-autocomplete-value-property="id"
data-autocomplete-items-property="items"
- data-autocomplete-filter-param-name="filter">
+ data-autocomplete-filter-param-name="filter"
+ data-autocomplete-allow-clear="true">
@SelectedAuthor.Name
@@ -38,6 +39,8 @@ The select must have the `auto-complete-select` class and the following attribut
- `data-autocomplete-filter-param-name`: * Filter text property name. _(For example: `filter`)_.
- `data-autocomplete-selected-item-name`: Text to display as selected item.
- `data-autocomplete-parent-selector`: jQuery selector expression for parent DOM. _(If it's in a modal, it's suggested to send the modal selector as this parameter)_.
+- `data-autocomplete-allow-clear`: If `true`, it'll allow to clear the selected value. Default value: `false`.
+- `data-autocomplete-placeholder`: Placeholder text to display when no value is selected.
Also, selected value(s) should be defined with the `` tags inside select, since pagination is applied and the selected options might haven't loaded yet.
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs
index 75ae03115a..58c7b1b45d 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelper.cs
@@ -38,6 +38,10 @@ public class AbpSelectTagHelper : AbpTagHelper
output.Attributes.Add("data-autocomplete-filter-param-name", TagHelper.AutocompleteFilterParamName);
output.Attributes.Add("data-autocomplete-selected-item-name", TagHelper.AutocompleteSelectedItemName);
output.Attributes.Add("data-autocomplete-selected-item-value", TagHelper.AutocompleteSelectedItemValue);
+ output.Attributes.Add("data-autocomplete-allow-clear", TagHelper.AllowClear);
+ output.Attributes.Add("data-autocomplete-placeholder", TagHelper.Placeholder);
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js
index 009c32d253..d1cbfa6b6b 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js
@@ -74,20 +74,26 @@
abp.dom.initializers.initializeAutocompleteSelects = function ($autocompleteSelects) {
if ($autocompleteSelects.length) {
$autocompleteSelects.each(function () {
- var $select = $(this);
- var url = $(this).data("autocompleteApiUrl");
- var displayName = $(this).data("autocompleteDisplayProperty");
- var displayValue = $(this).data("autocompleteValueProperty");
- var itemsPropertyName = $(this).data("autocompleteItemsProperty");
- var filterParamName = $(this).data("autocompleteFilterParamName");
- var selectedText = $(this).data("autocompleteSelectedItemName");
- var parentSelector = $(this).data("autocompleteParentSelector");
- if(!parentSelector && $select.parents(".modal.fade").length === 1){
+ let $select = $(this);
+ let url = $(this).data("autocompleteApiUrl");
+ let displayName = $(this).data("autocompleteDisplayProperty");
+ let displayValue = $(this).data("autocompleteValueProperty");
+ let itemsPropertyName = $(this).data("autocompleteItemsProperty");
+ let filterParamName = $(this).data("autocompleteFilterParamName");
+ let selectedText = $(this).data("autocompleteSelectedItemName");
+ let parentSelector = $(this).data("autocompleteParentSelector");
+ let allowClear = $(this).data("autocompleteAllowClear");
+ let placeholder = $(this).data("autocompletePlaceholder");
+ if (allowClear && placeholder == undefined) {
+ placeholder = " ";
+ }
+
+ if (!parentSelector && $select.parents(".modal.fade").length === 1) {
parentSelector = ".modal.fade";
}
- var name = $(this).attr("name");
- var selectedTextInputName = name + "_Text";
- var selectedTextInput = $(' ', {
+ let name = $(this).attr("name");
+ let selectedTextInputName = name + "_Text";
+ let selectedTextInput = $(' ', {
type: 'hidden',
id: selectedTextInputName,
name: selectedTextInputName,
@@ -101,13 +107,13 @@
url: url,
dataType: "json",
data: function (params) {
- var query = {};
+ let query = {};
query[filterParamName] = params.term;
return query;
},
processResults: function (data) {
- var retVal = [];
- var items = data;
+ let retVal = [];
+ let items = data;
if (itemsPropertyName) {
items = data[itemsPropertyName];
}
@@ -125,6 +131,11 @@
},
width: '100%',
dropdownParent: parentSelector ? $(parentSelector) : $('body'),
+ allowClear: allowClear,
+ placeholder: {
+ id: '-1',
+ text: placeholder
+ }
});
$select.on('select2:select', function (e) {
selectedTextInput.val(e.params.data.text);
diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json
index 0b2e115734..cd9029142c 100644
--- a/npm/ng-packs/angular.json
+++ b/npm/ng-packs/angular.json
@@ -277,6 +277,11 @@
"inject": true,
"bundleName": "ngx-datatable-material"
},
+ {
+ "input": "node_modules/ng-zorro-antd/tree/style/index.min.css",
+ "inject": false,
+ "bundleName": "ng-zorro-antd-tree"
+ },
"apps/dev-app/src/styles.scss"
],
"scripts": []
diff --git a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts
index 0dcd29113d..e7566c587d 100644
--- a/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts
+++ b/npm/ng-packs/packages/components/tree/src/lib/components/tree.component.ts
@@ -2,10 +2,13 @@ import {
Component,
ContentChild,
EventEmitter,
+ Inject,
Input,
+ Optional,
Output,
TemplateRef,
ViewEncapsulation,
+ OnInit
} from '@angular/core';
import { NzFormatBeforeDropEvent, NzFormatEmitEvent } from 'ng-zorro-antd/tree';
import { of } from 'rxjs';
@@ -13,6 +16,7 @@ import { TreeNodeTemplateDirective } from '../templates/tree-node-template.direc
import { ExpandedIconTemplateDirective } from '../templates/expanded-icon-template.directive';
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
import { LazyLoadService, LOADING_STRATEGY, SubscriptionService } from '@abp/ng.core';
+import { DISABLE_TREE_STYLE_LOADING_TOKEN } from '../disable-tree-style-loading.token';
export type DropEvent = NzFormatEmitEvent & { pos: number };
@@ -23,16 +27,18 @@ export type DropEvent = NzFormatEmitEvent & { pos: number };
encapsulation: ViewEncapsulation.None,
providers: [SubscriptionService],
})
-export class TreeComponent {
+export class TreeComponent implements OnInit {
dropPosition: number;
dropdowns = {} as { [key: string]: NgbDropdown };
- constructor(private lazyLoadService: LazyLoadService, subscriptionService: SubscriptionService) {
- const loaded$ = this.lazyLoadService.load(
- LOADING_STRATEGY.AppendAnonymousStyleToHead('ng-zorro-antd-tree.css'),
- );
- subscriptionService.addOne(loaded$);
- }
+
+ constructor(
+ private lazyLoadService: LazyLoadService,
+ subscriptionService: SubscriptionService,
+ @Optional()
+ @Inject(DISABLE_TREE_STYLE_LOADING_TOKEN)
+ private disableTreeStyleLoading: boolean | undefined,
+ ) { }
@ContentChild('menu') menu: TemplateRef;
@ContentChild(TreeNodeTemplateDirective) customNodeTemplate: TreeNodeTemplateDirective;
@@ -57,6 +63,20 @@ export class TreeComponent {
return of(false);
};
+ ngOnInit() {
+ this.loadStyle()
+ }
+
+ private loadStyle() {
+ if (disableTreeStyleLoading) {
+ return;
+ }
+ const loaded$ = this.lazyLoadService.load(
+ LOADING_STRATEGY.AppendAnonymousStyleToHead('ng-zorro-antd-tree.css'),
+ );
+ subscriptionService.addOne(loaded$);
+ }
+
onSelectedNodeChange(node) {
this.selectedNode = node.origin.entity;
if (this.changeCheckboxWithNode) {
diff --git a/npm/ng-packs/packages/components/tree/src/lib/disable-tree-style-loading.token.ts b/npm/ng-packs/packages/components/tree/src/lib/disable-tree-style-loading.token.ts
new file mode 100644
index 0000000000..a96f7cb235
--- /dev/null
+++ b/npm/ng-packs/packages/components/tree/src/lib/disable-tree-style-loading.token.ts
@@ -0,0 +1,5 @@
+import { InjectionToken } from '@angular/core';
+
+export const DISABLE_TREE_STYLE_LOADING_TOKEN = new InjectionToken(
+ 'DISABLE_TREE_STYLE_LOADING_TOKEN',
+);
diff --git a/npm/ng-packs/packages/components/tree/src/public-api.ts b/npm/ng-packs/packages/components/tree/src/public-api.ts
index 1f3dd48e00..9b5caf5976 100644
--- a/npm/ng-packs/packages/components/tree/src/public-api.ts
+++ b/npm/ng-packs/packages/components/tree/src/public-api.ts
@@ -3,3 +3,4 @@ export * from './lib/components/tree.component';
export * from './lib/utils/nz-tree-adapter';
export * from './lib/templates/tree-node-template.directive';
export * from './lib/templates/expanded-icon-template.directive';
+export * from './lib/disable-tree-style-loading.token';