@progress/kendo-angular-dropdowns
Version:
A wide variety of native Angular dropdown components including AutoComplete, ComboBox, DropDownList, DropDownTree, MultiColumnComboBox, MultiSelect, and MultiSelectTree
823 lines (804 loc) • 41.8 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { ChangeDetectorRef, Component, ContentChildren, ElementRef, forwardRef, HostBinding, Injector, isDevMode, NgZone, QueryList, Renderer2, ViewChild, ViewChildren } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { EventsOutsideAngularDirective, isDocumentAvailable, KendoInput, MultiTabStop, ResizeSensorComponent, SeparatorComponent, TemplateContextDirective } from '@progress/kendo-angular-common';
import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
import { PopupService } from '@progress/kendo-angular-popup';
import { AdaptiveService } from '@progress/kendo-angular-utils';
import { ComboBoxComponent } from './combobox.component';
import { ComboBoxColumnComponent } from './combobox-column/combobox-column.component';
import { DataService } from '../common/data.service';
import { DisabledItemsService } from '../common/disabled-items/disabled-items.service';
import { NavigationService } from '../common/navigation/navigation.service';
import { SelectionService } from '../common/selection/selection.service';
import { animationDuration, getSizeClass, getter, isObject, isPresent, noop } from '../common/util';
import { getRowWidthFromColumnsMeta, scrollbarWidth } from './combobox-column/util';
import { FilterableComponent } from '../common/filtering/filterable-component';
import { MultiColumnComboBoxMessages } from '../common/constants/error-messages';
import { ListComponent } from '../common/list.component';
import { ResponsiveRendererComponent } from '../common/action-sheet.component';
import { SearchBarComponent } from '../common/searchbar.component';
import { NgIf, NgTemplateOutlet, NgClass, NgFor, NgStyle } from '@angular/common';
import { SharedDropDownEventsDirective } from '../common/shared-events.directive';
import { LocalizedMessagesDirective } from '../common/localization/localized-messages.directive';
import { IconWrapperComponent } from '@progress/kendo-angular-icons';
import { Subscription } from 'rxjs';
import { take } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@progress/kendo-angular-l10n";
import * as i2 from "@progress/kendo-angular-popup";
import * as i3 from "../common/selection/selection.service";
import * as i4 from "../common/navigation/navigation.service";
import * as i5 from "../common/disabled-items/disabled-items.service";
import * as i6 from "../common/data.service";
import * as i7 from "@progress/kendo-angular-utils";
/**
* Represents the [Kendo UI MultiColumnComboBox component for Angular]({% slug overview_multicolumncombobox %}).
*/
export class MultiColumnComboBoxComponent extends ComboBoxComponent {
hostElement;
/**
* @hidden
*/
animationDuration = animationDuration;
/**
* @hidden
*/
hostClasses = true;
/**
* @hidden
*/
get isDisabled() {
return this.disabled;
}
/**
* A query list of all declared columns.
*/
columns;
/**
* @hidden
*/
set header(header) {
// updates the header padding on initial render as the resize senzor doesn't kick in as early
this.updateHeaderPadding(header && header.nativeElement);
}
/**
* @hidden
*/
set headerTable(headerTable) {
this._headerTable = headerTable;
if (this.headerTable) {
this.zone.onStable.pipe(take(1)).subscribe(() => {
this.rowWidth = this.calculateRowWidth();
});
}
}
get headerTable() {
return this._headerTable;
}
/**
* @hidden
*/
set headerColumns(columns) {
this.zone.onStable.pipe(take(1)).subscribe(() => {
this.headerColumnWidths = columns.map(column => column.nativeElement.offsetWidth);
});
}
/**
* @hidden
*/
rowWidth;
/**
* @hidden
*/
headerColumnWidths = [];
/**
* @hidden
*/
totalColumnsWidth;
get popupWidth() {
const wrapperOffsetWidth = this.wrapper.nativeElement.offsetWidth;
const min = `${wrapperOffsetWidth}px`;
const width = this.popupSettings.width || getRowWidthFromColumnsMeta(this.columns) || wrapperOffsetWidth;
const max = isNaN(width) ? width : `${width}px`;
return { min, max };
}
_headerTable;
removeWindowResizeListener = noop;
columnsChangeSubscription = new Subscription();
/**
* @hidden
*/
get tableSizeClass() {
return `${this.size ? getSizeClass('table', this.size) : ''}`;
}
/**
* @hidden
*/
get listContainerClasses() {
return ['k-popup', 'k-dropdowngrid-popup'].concat(this.popupSettings.popupClass || []);
}
constructor(localization, popupService, selectionService, navigationService, disabledItemsService, dataService, zone, changeDetector, renderer, wrapper, injector, hostElement, adaptiveService) {
super(wrapper, localization, popupService, selectionService, navigationService, disabledItemsService, dataService, zone, changeDetector, renderer, injector, hostElement, adaptiveService);
this.hostElement = hostElement;
// the row height in @progress/kendo-theme-default
this.defaultVirtualItemHeight = 36;
// use a smaller virtual page size as columns with multiple cells can cause poor performance
this.defaultVirtualPageSize = 30;
}
ngAfterViewInit() {
this.updateColumnsMediaState();
this.addWindowResizeListener();
this.windowSize = this.adaptiveService.size;
this.rowWidth = this.calculateRowWidth();
this.totalColumnsWidth = this.columns.reduce((total, currentColumn) => total + currentColumn.width, 0);
this.columnsChangeSubscription = this.columns.changes.subscribe(() => {
this.rowWidth = this.calculateRowWidth();
this.totalColumnsWidth = this.columns.reduce((total, currentColumn) => total + currentColumn.width, 0);
});
this.cdr.detectChanges();
if (this.actionSheet && isDocumentAvailable()) {
// The following syntax is used as it does not violate CSP compliance
this.actionSheet.element.nativeElement.style.setProperty('--kendo-actionsheet-height', '60vh');
this.actionSheet.element.nativeElement.style.setProperty('--kendo-actionsheet-max-height', 'none');
}
}
ngOnDestroy() {
super.ngOnDestroy();
this.removeWindowResizeListener();
if (this.columnsChangeSubscription) {
this.columnsChangeSubscription.unsubscribe();
}
}
/**
* @hidden
*/
textFrom(dataItem, field) {
return getter(dataItem, field);
}
/**
* @hidden
*
* Adds or removes a padding value at the end of the header container equal to the size of the scrollbar.
* As when the items container has a scrollbar, the column headers and the cells are misaligned.
* When the container has a scrollbar, the padding style is added, and when there is none - it is removed.
*/
updateHeaderPadding(header) {
if (!isPresent(header)) {
return;
}
// the scrollbar is rendered on the left in rtl
const headerPaddingPosition = this.localization.rtl ? 'padding-left' : 'padding-right';
if (this.optionsList.hasScrollbar() && scrollbarWidth() > 0) {
this.renderer.setStyle(header, headerPaddingPosition, `${scrollbarWidth()}px`);
}
else {
this.renderer.removeStyle(header, headerPaddingPosition);
}
}
/**
*
* @hidden
*/
getColumnWidth(index) {
if (!this.virtual) {
return this.columns.get(index).width;
}
return this.headerColumnWidths[index];
}
verifySettings() {
if (!isDevMode()) {
return;
}
if (isPresent(this.data) && this.data.length > 0 && this.data.some((item) => !isObject(item))) {
throw new Error(MultiColumnComboBoxMessages.data);
}
if (!isPresent(this.valueField) || !isPresent(this.textField)) {
throw new Error(MultiColumnComboBoxMessages.textAndValue);
}
super.verifySettings();
}
addWindowResizeListener() {
if (!isDocumentAvailable()) {
return;
}
this.zone.runOutsideAngular(() => (this.removeWindowResizeListener = this.renderer.listen(window, 'resize', this.updateColumnsMediaState.bind(this))));
}
updateColumnsMediaState() {
if (!(isPresent(this.columns) && isDocumentAvailable()) || this.isActionSheetExpanded) {
return;
}
this.columns.forEach((column) => {
const matchesMedia = !column.media || window.matchMedia(column.media).matches;
if (column.matchesMedia !== matchesMedia) {
column.matchesMedia = matchesMedia;
if (this.isOpen) {
// enter the zone only if the popup is actually open
// update its width in case it's dependent on the columns' width
this.zone.run(() => (this.popupRef.popupElement.style.width = this.popupWidth.max));
}
}
});
}
calculateRowWidth() {
if (this.isActionSheetExpanded || !this.virtual) {
return;
}
return this.headerTable?.nativeElement.offsetWidth;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiColumnComboBoxComponent, deps: [{ token: i1.LocalizationService }, { token: i2.PopupService }, { token: i3.SelectionService }, { token: i4.NavigationService }, { token: i5.DisabledItemsService }, { token: i6.DataService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.Injector }, { token: i0.ElementRef }, { token: i7.AdaptiveService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: MultiColumnComboBoxComponent, isStandalone: true, selector: "kendo-multicolumncombobox", host: { properties: { "class.k-dropdowngrid": "this.hostClasses", "class.k-disabled": "this.isDisabled" } }, providers: [
SelectionService,
DataService,
NavigationService,
DisabledItemsService,
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.multicolumncombobox',
},
{
multi: true,
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: KendoInput,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: FilterableComponent,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: MultiTabStop,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
], queries: [{ propertyName: "columns", predicate: ComboBoxColumnComponent }], viewQueries: [{ propertyName: "header", first: true, predicate: ["header"], descendants: true }, { propertyName: "headerTable", first: true, predicate: ["headerTable"], descendants: true }, { propertyName: "headerColumns", predicate: ["columnHeader"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
<ng-container
kendoMultiColumnComboBoxLocalizedMessages
i18n-noDataText="
kendo.multicolumncombobox.noDataText|The text displayed in the popup when there are no items
"
noDataText="NO DATA FOUND"
i18n-clearTitle="kendo.multicolumncombobox.clearTitle|The title of the clear button"
clearTitle="clear"
i18n-selectButtonText="kendo.multicolumncombobox.selectButtonText|The title of the select button"
selectButtonText="Select"
i18n-popupLabel="
kendo.multicolumncombobox.popupLabel|The label of the popup element that contains the list of options
when its role is 'region'
"
popupLabel="Options list"
></ng-container>
<ng-container
kendoDropDownSharedEvents
[hostElement]="hostElement"
[(isFocused)]="isFocused"
(handleBlur)="handleBlur()"
(onFocus)="handleFocus()"
>
<span *ngIf="prefixTemplate" class="k-input-prefix k-input-prefix-horizontal">
<ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
</ng-template>
</span>
<kendo-separator *ngIf="prefixTemplate && prefixTemplate.showSeparator"></kendo-separator>
<input
kendoSearchbar
[ariaControls]="ariaControls"
[ariaExpanded]="isOpen"
[id]="focusableId"
[isLoading]="loading"
[isSuggestable]="suggest"
[isFilterable]="filterable"
[activeDescendant]="activeDescendant"
[userInput]="text"
[suggestedText]="getSuggestion()"
[disabled]="disabled"
[readonly]="readonly"
[tabIndex]="tabIndex"
[isRequired]="isControlRequired"
[placeholder]="placeholder"
[inputAttributes]="inputAttributes"
(onNavigate)="handleNavigate($event)"
(valueChange)="searchBarChange($event)"
(onBlur)="handleInputBlur()"
(onFocus)="handleInputFocus()"
(click)="handleClick()"
/>
<span
*ngIf="clearButton && !loading && !disabled && (!readonly || readonly && isAdaptiveModeEnabled && windowSize !== 'large') && text?.length"
class="k-clear-value"
[style.visibility]="clearButtonVisiblity"
aria-hidden="true"
[attr.title]="messageFor('clearTitle')"
(click)="clearValue($event)"
[kendoEventsOutsideAngular]="{
mousedown: preventEventDefault
}"
>
<kendo-icon-wrapper name="x" [svgIcon]="xIcon"> </kendo-icon-wrapper>
</span>
<span *ngIf="loading" class="k-i-loading k-input-loading-icon k-icon"></span>
<kendo-separator *ngIf="suffixTemplate && suffixTemplate.showSeparator"></kendo-separator>
<span *ngIf="suffixTemplate" class="k-input-suffix k-input-suffix-horizontal">
<ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
</ng-template>
</span>
<button
#select
tabindex="-1"
aria-hidden="true"
unselectable="on"
type="button"
class="k-input-button k-button k-icon-button"
[ngClass]="selectButtonClasses"
[attr.aria-label]="messageFor('selectButtonText')"
[attr.disabled]="disabled ? '' : null"
[kendoEventsOutsideAngular]="{
mousedown: preventEventDefault
}"
>
<kendo-icon-wrapper
[name]="icon || 'caret-alt-down'"
innerCssClass="k-button-icon"
[svgIcon]="svgIcon || caretAltDownIcon"
>
</kendo-icon-wrapper>
</button>
</ng-container>
<ng-template #popupTemplate>
<!--popup/actionsheet content-->
<ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
</ng-template>
<kendo-resize-sensor *ngIf="isOpen || isAdaptiveModeEnabled" (resize)="onResize()"> </kendo-resize-sensor>
<!-- when the popupSettings.appendTo value is set to 'component', this container is used -->
<ng-container #container></ng-container>
<!--adaptive rendering-->
<responsive-renderer
[sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
[isActionSheetExpanded]="isActionSheetExpanded"
[title]="title"
[showTextInput]="true"
[subtitle]="subtitle"
(closePopup)="togglePopup(false)"
(textInputChange)="onAdaptiveTextBoxChange($event)"
(navigate)="handleNavigate($event)"
[placeholder]="placeholder"
>
</responsive-renderer>
<ng-template #sharedPopupActionSheetTemplate>
<!--user-defined header template -->
<ng-template
*ngIf="headerTemplate"
[templateContext]="{
templateRef: headerTemplate?.templateRef
}"
>
</ng-template>
<!--data table-->
<div class="k-data-table" [ngClass]="tableSizeClass">
<!--grid header-->
<div #header class="k-table-header">
<div #headerWrap class="k-table-header-wrap">
<table #headerTable class="k-table" role="presentation">
<colgroup>
<ng-container *ngFor="let column of columns">
<col *ngIf="!column.hidden && column.matchesMedia" [style.width.px]="column.width" />
</ng-container>
</colgroup>
<thead class="k-table-thead">
<tr class="k-table-row">
<ng-container *ngFor="let column of columns">
<th
#columnHeader
*ngIf="!column.hidden && column.matchesMedia"
class="k-table-th"
[ngStyle]="column.headerStyle"
[ngClass]="column.headerClass"
>
<ng-container *ngIf="!column.headerTemplate">
{{ column.title || column.field }}
</ng-container>
<ng-template
*ngIf="column.headerTemplate"
[templateContext]="{
templateRef: column.headerTemplate?.templateRef,
$implicit: column,
column: column
}"
>
</ng-template>
</th>
</ng-container>
</tr>
</thead>
</table>
</div>
</div>
<!-- item template -->
<ng-template #rowTemplate let-dataItem>
<ng-container *ngFor="let column of columns; let i = index">
<span
*ngIf="!column.hidden && column.matchesMedia"
class="k-table-td"
[ngClass]="column.class"
[style.width.px]="getColumnWidth(i)"
[style.max-width.px]="getColumnWidth(i)"
[ngStyle]="column.style"
>
<ng-container *ngIf="!column.cellTemplate">
{{ textFrom(dataItem, column.field) }}
</ng-container>
<ng-template
*ngIf="column.cellTemplate"
[templateContext]="{
templateRef: column.cellTemplate?.templateRef,
$implicit: dataItem,
dataItem: dataItem,
column: column
}"
>
</ng-template>
</span>
</ng-container>
</ng-template>
<kendo-list
#optionsList
[optionPrefix]="optionPrefix"
[data]="data"
[textField]="textField"
[valueField]="valueField"
[template]="{ templateRef: rowTemplate }"
[groupTemplate]="groupTemplate"
[fixedGroupTemplate]="fixedGroupTemplate"
[height]="listHeight"
[show]="isOpen"
[id]="listBoxId"
[virtual]="virtual"
[type]="'dropdowngrid'"
[rowWidth]="rowWidth"
[showStickyHeader]="showStickyHeader"
(pageChange)="pageChange($event)"
(listResize)="updateHeaderPadding(header)"
(popupListScroll)="headerWrap.scrollLeft = $event.target.scrollLeft;"
>
</kendo-list>
<!--no-data template-->
<div class="k-no-data" *ngIf="data.length === 0">
<ng-template
[ngIf]="noDataTemplate"
[templateContext]="{
templateRef: noDataTemplate?.templateRef
}"
>
</ng-template>
<ng-template [ngIf]="!noDataTemplate">
<div>{{ messageFor('noDataText') }}</div>
</ng-template>
</div>
<!--user-defined footer template-->
<ng-container *ngIf="footerTemplate">
<div class="k-table-footer">
<table class="k-table">
<tfoot class="k-table-tfoot">
<tr class="k-table-row">
<td class="k-table-td">
<ng-template
[templateContext]="{
templateRef: footerTemplate.templateRef
}"
>
</ng-template>
</td>
</tr>
</tfoot>
</table>
</div>
</ng-container>
</div>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoDropDownListLocalizedMessages],\n [kendoDropDownTreeLocalizedMessages],\n [kendoComboBoxLocalizedMessages],\n [kendoMultiColumnComboBoxLocalizedMessages],\n [kendoAutoCompleteLocalizedMessages],\n [kendoMultiSelectLocalizedMessages],\n [kendoMultiSelectTreeLocalizedMessages]\n " }, { kind: "directive", type: SharedDropDownEventsDirective, selector: "[kendoDropDownSharedEvents]", inputs: ["hostElement", "clearButtonClicked", "isFocused"], outputs: ["isFocusedChange", "onFocus", "handleBlur"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SeparatorComponent, selector: "kendo-separator", inputs: ["orientation"] }, { kind: "component", type: SearchBarComponent, selector: "input[kendoSearchbar]", inputs: ["tagListId", "readonly", "disabled", "isRequired", "isSuggestable", "isFilterable", "userInput", "suggestedText", "inputAttributes", "id", "activeDescendant", "tabIndex", "isLoading", "ariaControls", "ariaExpanded", "placeholder"], outputs: ["valueChange", "onBlur", "onFocus", "onClick", "onNavigate"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }, { kind: "component", type: ResponsiveRendererComponent, selector: "responsive-renderer", inputs: ["title", "showActionButtons", "subtitle", "size", "showTextInput", "sharedPopupActionSheetTemplate", "isActionSheetExpanded", "text", "placeholder"], outputs: ["closePopup", "textInputChange", "navigate", "onExpand", "onCollapse", "onApply", "onCancel"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ListComponent, selector: "kendo-list", inputs: ["selected", "focused", "textField", "valueField", "height", "template", "groupTemplate", "fixedGroupTemplate", "show", "id", "optionPrefix", "multipleSelection", "virtual", "type", "checkboxes", "ariaLive", "isMultiselect", "isActionSheetExpanded", "showStickyHeader", "rowWidth", "data", "size", "rounded"], outputs: ["onClick", "pageChange", "listResize", "popupListScroll"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: MultiColumnComboBoxComponent, decorators: [{
type: Component,
args: [{
providers: [
SelectionService,
DataService,
NavigationService,
DisabledItemsService,
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.multicolumncombobox',
},
{
multi: true,
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: KendoInput,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: FilterableComponent,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
{
provide: MultiTabStop,
useExisting: forwardRef(() => MultiColumnComboBoxComponent),
},
],
selector: 'kendo-multicolumncombobox',
template: `
<ng-container
kendoMultiColumnComboBoxLocalizedMessages
i18n-noDataText="
kendo.multicolumncombobox.noDataText|The text displayed in the popup when there are no items
"
noDataText="NO DATA FOUND"
i18n-clearTitle="kendo.multicolumncombobox.clearTitle|The title of the clear button"
clearTitle="clear"
i18n-selectButtonText="kendo.multicolumncombobox.selectButtonText|The title of the select button"
selectButtonText="Select"
i18n-popupLabel="
kendo.multicolumncombobox.popupLabel|The label of the popup element that contains the list of options
when its role is 'region'
"
popupLabel="Options list"
></ng-container>
<ng-container
kendoDropDownSharedEvents
[hostElement]="hostElement"
[(isFocused)]="isFocused"
(handleBlur)="handleBlur()"
(onFocus)="handleFocus()"
>
<span *ngIf="prefixTemplate" class="k-input-prefix k-input-prefix-horizontal">
<ng-template [ngTemplateOutlet]="prefixTemplate?.templateRef">
</ng-template>
</span>
<kendo-separator *ngIf="prefixTemplate && prefixTemplate.showSeparator"></kendo-separator>
<input
kendoSearchbar
[ariaControls]="ariaControls"
[ariaExpanded]="isOpen"
[id]="focusableId"
[isLoading]="loading"
[isSuggestable]="suggest"
[isFilterable]="filterable"
[activeDescendant]="activeDescendant"
[userInput]="text"
[suggestedText]="getSuggestion()"
[disabled]="disabled"
[readonly]="readonly"
[tabIndex]="tabIndex"
[isRequired]="isControlRequired"
[placeholder]="placeholder"
[inputAttributes]="inputAttributes"
(onNavigate)="handleNavigate($event)"
(valueChange)="searchBarChange($event)"
(onBlur)="handleInputBlur()"
(onFocus)="handleInputFocus()"
(click)="handleClick()"
/>
<span
*ngIf="clearButton && !loading && !disabled && (!readonly || readonly && isAdaptiveModeEnabled && windowSize !== 'large') && text?.length"
class="k-clear-value"
[style.visibility]="clearButtonVisiblity"
aria-hidden="true"
[attr.title]="messageFor('clearTitle')"
(click)="clearValue($event)"
[kendoEventsOutsideAngular]="{
mousedown: preventEventDefault
}"
>
<kendo-icon-wrapper name="x" [svgIcon]="xIcon"> </kendo-icon-wrapper>
</span>
<span *ngIf="loading" class="k-i-loading k-input-loading-icon k-icon"></span>
<kendo-separator *ngIf="suffixTemplate && suffixTemplate.showSeparator"></kendo-separator>
<span *ngIf="suffixTemplate" class="k-input-suffix k-input-suffix-horizontal">
<ng-template [ngTemplateOutlet]="suffixTemplate?.templateRef">
</ng-template>
</span>
<button
#select
tabindex="-1"
aria-hidden="true"
unselectable="on"
type="button"
class="k-input-button k-button k-icon-button"
[ngClass]="selectButtonClasses"
[attr.aria-label]="messageFor('selectButtonText')"
[attr.disabled]="disabled ? '' : null"
[kendoEventsOutsideAngular]="{
mousedown: preventEventDefault
}"
>
<kendo-icon-wrapper
[name]="icon || 'caret-alt-down'"
innerCssClass="k-button-icon"
[svgIcon]="svgIcon || caretAltDownIcon"
>
</kendo-icon-wrapper>
</button>
</ng-container>
<ng-template #popupTemplate>
<!--popup/actionsheet content-->
<ng-container *ngTemplateOutlet="sharedPopupActionSheetTemplate"></ng-container>
</ng-template>
<kendo-resize-sensor *ngIf="isOpen || isAdaptiveModeEnabled" (resize)="onResize()"> </kendo-resize-sensor>
<!-- when the popupSettings.appendTo value is set to 'component', this container is used -->
<ng-container #container></ng-container>
<!--adaptive rendering-->
<responsive-renderer
[sharedPopupActionSheetTemplate]="sharedPopupActionSheetTemplate"
[isActionSheetExpanded]="isActionSheetExpanded"
[title]="title"
[showTextInput]="true"
[subtitle]="subtitle"
(closePopup)="togglePopup(false)"
(textInputChange)="onAdaptiveTextBoxChange($event)"
(navigate)="handleNavigate($event)"
[placeholder]="placeholder"
>
</responsive-renderer>
<ng-template #sharedPopupActionSheetTemplate>
<!--user-defined header template -->
<ng-template
*ngIf="headerTemplate"
[templateContext]="{
templateRef: headerTemplate?.templateRef
}"
>
</ng-template>
<!--data table-->
<div class="k-data-table" [ngClass]="tableSizeClass">
<!--grid header-->
<div #header class="k-table-header">
<div #headerWrap class="k-table-header-wrap">
<table #headerTable class="k-table" role="presentation">
<colgroup>
<ng-container *ngFor="let column of columns">
<col *ngIf="!column.hidden && column.matchesMedia" [style.width.px]="column.width" />
</ng-container>
</colgroup>
<thead class="k-table-thead">
<tr class="k-table-row">
<ng-container *ngFor="let column of columns">
<th
#columnHeader
*ngIf="!column.hidden && column.matchesMedia"
class="k-table-th"
[ngStyle]="column.headerStyle"
[ngClass]="column.headerClass"
>
<ng-container *ngIf="!column.headerTemplate">
{{ column.title || column.field }}
</ng-container>
<ng-template
*ngIf="column.headerTemplate"
[templateContext]="{
templateRef: column.headerTemplate?.templateRef,
$implicit: column,
column: column
}"
>
</ng-template>
</th>
</ng-container>
</tr>
</thead>
</table>
</div>
</div>
<!-- item template -->
<ng-template #rowTemplate let-dataItem>
<ng-container *ngFor="let column of columns; let i = index">
<span
*ngIf="!column.hidden && column.matchesMedia"
class="k-table-td"
[ngClass]="column.class"
[style.width.px]="getColumnWidth(i)"
[style.max-width.px]="getColumnWidth(i)"
[ngStyle]="column.style"
>
<ng-container *ngIf="!column.cellTemplate">
{{ textFrom(dataItem, column.field) }}
</ng-container>
<ng-template
*ngIf="column.cellTemplate"
[templateContext]="{
templateRef: column.cellTemplate?.templateRef,
$implicit: dataItem,
dataItem: dataItem,
column: column
}"
>
</ng-template>
</span>
</ng-container>
</ng-template>
<kendo-list
#optionsList
[optionPrefix]="optionPrefix"
[data]="data"
[textField]="textField"
[valueField]="valueField"
[template]="{ templateRef: rowTemplate }"
[groupTemplate]="groupTemplate"
[fixedGroupTemplate]="fixedGroupTemplate"
[height]="listHeight"
[show]="isOpen"
[id]="listBoxId"
[virtual]="virtual"
[type]="'dropdowngrid'"
[rowWidth]="rowWidth"
[showStickyHeader]="showStickyHeader"
(pageChange)="pageChange($event)"
(listResize)="updateHeaderPadding(header)"
(popupListScroll)="headerWrap.scrollLeft = $event.target.scrollLeft;"
>
</kendo-list>
<!--no-data template-->
<div class="k-no-data" *ngIf="data.length === 0">
<ng-template
[ngIf]="noDataTemplate"
[templateContext]="{
templateRef: noDataTemplate?.templateRef
}"
>
</ng-template>
<ng-template [ngIf]="!noDataTemplate">
<div>{{ messageFor('noDataText') }}</div>
</ng-template>
</div>
<!--user-defined footer template-->
<ng-container *ngIf="footerTemplate">
<div class="k-table-footer">
<table class="k-table">
<tfoot class="k-table-tfoot">
<tr class="k-table-row">
<td class="k-table-td">
<ng-template
[templateContext]="{
templateRef: footerTemplate.templateRef
}"
>
</ng-template>
</td>
</tr>
</tfoot>
</table>
</div>
</ng-container>
</div>
</ng-template>
`,
standalone: true,
imports: [LocalizedMessagesDirective, SharedDropDownEventsDirective, NgIf, NgTemplateOutlet, SeparatorComponent, SearchBarComponent, EventsOutsideAngularDirective, IconWrapperComponent, NgClass, ResizeSensorComponent, ResponsiveRendererComponent, TemplateContextDirective, NgFor, NgStyle, ListComponent]
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.PopupService }, { type: i3.SelectionService }, { type: i4.NavigationService }, { type: i5.DisabledItemsService }, { type: i6.DataService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.Injector }, { type: i0.ElementRef }, { type: i7.AdaptiveService }]; }, propDecorators: { hostClasses: [{
type: HostBinding,
args: ['class.k-dropdowngrid']
}], isDisabled: [{
type: HostBinding,
args: ['class.k-disabled']
}], columns: [{
type: ContentChildren,
args: [ComboBoxColumnComponent]
}], header: [{
type: ViewChild,
args: ['header', { static: false }]
}], headerTable: [{
type: ViewChild,
args: ['headerTable', { static: false }]
}], headerColumns: [{
type: ViewChildren,
args: ['columnHeader']
}] } });