valtech-components 2.0.397 → 2.0.399

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ import { Browser } from '@capacitor/browser';
11
11
  import * as i1$1 from '@angular/platform-browser';
12
12
  import * as i1$2 from '@angular/forms';
13
13
  import { ReactiveFormsModule, FormsModule, Validators } from '@angular/forms';
14
- import { map as map$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs/operators';
14
+ import { map as map$1 } from 'rxjs/operators';
15
15
  import * as i1$3 from 'ng-otp-input';
16
16
  import { NgOtpInputComponent, NgOtpInputModule } from 'ng-otp-input';
17
17
  import * as i2 from '@ionic/angular';
@@ -7513,6 +7513,366 @@ const isAtEnd = (elementRef) => {
7513
7513
  return rect.bottom <= windowHeight;
7514
7514
  };
7515
7515
 
7516
+ class MultiSelectSearchComponent {
7517
+ constructor() {
7518
+ this.labelProperty = 'name';
7519
+ this.valueProperty = 'id';
7520
+ this.langService = inject(LangService);
7521
+ this.icon = inject(IconService);
7522
+ this.changeDetector = inject(ChangeDetectorRef);
7523
+ this.searchTerm = '';
7524
+ this.filteredItems = [];
7525
+ this.selectedItems = [];
7526
+ this.displayValue = '';
7527
+ this.previousOptions = [];
7528
+ this.isProcessingChanges = false;
7529
+ this.label = this.langService.getText('_global', 'selectMultiple', 'Seleccionar múltiples');
7530
+ this.placeholder = this.langService.getText('_global', 'selectOptions', 'Seleccione opciones');
7531
+ }
7532
+ ngOnInit() {
7533
+ this.applyDefaultValue();
7534
+ this.initializeItems();
7535
+ this.syncControlValueWithSelectedItems();
7536
+ this.updateDisplayValue();
7537
+ this.subscribeToValueChanges();
7538
+ }
7539
+ ngOnDestroy() {
7540
+ if (this.valueChangesSubscription) {
7541
+ this.valueChangesSubscription.unsubscribe();
7542
+ }
7543
+ }
7544
+ ngOnChanges(changes) {
7545
+ if (this.isProcessingChanges) {
7546
+ return;
7547
+ }
7548
+ if (changes['props']) {
7549
+ try {
7550
+ this.isProcessingChanges = true;
7551
+ if (this.valueChangesSubscription) {
7552
+ this.valueChangesSubscription.unsubscribe();
7553
+ }
7554
+ if (this.props?.options) {
7555
+ const optionsChanged = !this.areOptionsEqual(this.previousOptions, this.props.options);
7556
+ if (optionsChanged) {
7557
+ this.previousOptions = [...this.props.options];
7558
+ this.initializeItems();
7559
+ }
7560
+ }
7561
+ this.syncControlValueWithSelectedItems();
7562
+ this.updateDisplayValue();
7563
+ this.subscribeToValueChanges();
7564
+ }
7565
+ finally {
7566
+ this.isProcessingChanges = false;
7567
+ }
7568
+ }
7569
+ }
7570
+ ionViewWillEnter() {
7571
+ if (this.isProcessingChanges) {
7572
+ return;
7573
+ }
7574
+ try {
7575
+ this.isProcessingChanges = true;
7576
+ this.initializeItems();
7577
+ this.syncControlValueWithSelectedItems();
7578
+ this.updateDisplayValue();
7579
+ this.subscribeToValueChanges();
7580
+ }
7581
+ finally {
7582
+ this.isProcessingChanges = false;
7583
+ }
7584
+ }
7585
+ subscribeToValueChanges() {
7586
+ if (!this.props?.control)
7587
+ return;
7588
+ this.valueChangesSubscription = this.props.control.valueChanges.subscribe(value => {
7589
+ if (this.isProcessingChanges)
7590
+ return;
7591
+ try {
7592
+ this.isProcessingChanges = true;
7593
+ this.syncControlValueWithSelectedItems();
7594
+ this.updateDisplayValue();
7595
+ }
7596
+ finally {
7597
+ this.isProcessingChanges = false;
7598
+ }
7599
+ });
7600
+ }
7601
+ areOptionsEqual(prevOptions, newOptions) {
7602
+ if (prevOptions === newOptions)
7603
+ return true;
7604
+ if (!prevOptions || !newOptions)
7605
+ return prevOptions === newOptions;
7606
+ if (prevOptions.length !== newOptions.length)
7607
+ return false;
7608
+ for (let i = 0; i < prevOptions.length; i++) {
7609
+ if (prevOptions[i][this.valueProperty] !== newOptions[i][this.valueProperty]) {
7610
+ return false;
7611
+ }
7612
+ }
7613
+ return true;
7614
+ }
7615
+ initializeItems() {
7616
+ this.filteredItems = this.props?.options || [];
7617
+ }
7618
+ syncControlValueWithSelectedItems() {
7619
+ if (!this.props?.control) {
7620
+ this.selectedItems = [];
7621
+ return;
7622
+ }
7623
+ const controlValue = this.props.control.value;
7624
+ if (!Array.isArray(controlValue) || controlValue.length === 0) {
7625
+ this.selectedItems = [];
7626
+ return;
7627
+ }
7628
+ if (this.props.options && this.props.options.length > 0) {
7629
+ const map = new Map(this.props.options.map(opt => [opt[this.valueProperty], opt]));
7630
+ this.selectedItems = controlValue
7631
+ .map(value => map.get(value))
7632
+ .filter(item => item !== undefined);
7633
+ }
7634
+ else {
7635
+ this.selectedItems = [];
7636
+ }
7637
+ }
7638
+ applyDefaultValue() {
7639
+ applyDefaultValueToControl(this.props);
7640
+ }
7641
+ onFilter(event) {
7642
+ if (!event || event.trim() === '') {
7643
+ this.filteredItems = this.props?.options ? [...this.props.options] : [];
7644
+ this.changeDetector.detectChanges();
7645
+ return;
7646
+ }
7647
+ if (!this.props?.options || this.props.options.length === 0) {
7648
+ this.filteredItems = [];
7649
+ this.changeDetector.detectChanges();
7650
+ return;
7651
+ }
7652
+ const search = replaceSpecialChars(event.toLowerCase());
7653
+ this.filteredItems = this.props.options.filter(element => {
7654
+ const label = element[this.labelProperty]
7655
+ ? replaceSpecialChars(String(element[this.labelProperty]).toLowerCase())
7656
+ : '';
7657
+ const value = element[this.valueProperty]
7658
+ ? replaceSpecialChars(String(element[this.valueProperty]).toLowerCase())
7659
+ : '';
7660
+ return label.includes(search) || value.includes(search);
7661
+ });
7662
+ this.changeDetector.detectChanges();
7663
+ }
7664
+ onFocus() {
7665
+ console.log('onFocus');
7666
+ }
7667
+ onBlur() {
7668
+ console.log('onBlur');
7669
+ }
7670
+ openModal() {
7671
+ if (this.modal) {
7672
+ this.modal.present();
7673
+ }
7674
+ }
7675
+ preventDefaultBehavior(event) {
7676
+ event.preventDefault();
7677
+ event.stopPropagation();
7678
+ this.openModal();
7679
+ }
7680
+ cancelModal() {
7681
+ // Reset filter and show all options when closing modal
7682
+ this.searchTerm = '';
7683
+ this.filteredItems = this.props?.options ? [...this.props.options] : [];
7684
+ this.changeDetector.detectChanges();
7685
+ if (this.modal) {
7686
+ this.modal.dismiss();
7687
+ }
7688
+ }
7689
+ toggleItem(item) {
7690
+ const index = this.selectedItems.findIndex(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
7691
+ if (index === -1) {
7692
+ this.selectedItems.push(item);
7693
+ }
7694
+ else {
7695
+ this.selectedItems.splice(index, 1);
7696
+ }
7697
+ this.updateDisplayValue();
7698
+ }
7699
+ isItemSelected(item) {
7700
+ return this.selectedItems.some(selectedItem => selectedItem[this.valueProperty] === item[this.valueProperty]);
7701
+ }
7702
+ clearSelection() {
7703
+ this.selectedItems = [];
7704
+ this.updateDisplayValue();
7705
+ }
7706
+ applySelection() {
7707
+ this.applyChanges();
7708
+ this.cancelModal();
7709
+ }
7710
+ updateDisplayValue() {
7711
+ if (this.selectedItems.length === 0) {
7712
+ this.displayValue = '';
7713
+ return;
7714
+ }
7715
+ if (this.selectedItems.length === 1) {
7716
+ this.displayValue = this.selectedItems[0][this.labelProperty];
7717
+ }
7718
+ else {
7719
+ this.displayValue = `${this.selectedItems.length} elementos seleccionados`;
7720
+ }
7721
+ }
7722
+ applyChanges() {
7723
+ if (!this.props?.control) {
7724
+ return;
7725
+ }
7726
+ try {
7727
+ this.isProcessingChanges = true;
7728
+ const values = this.selectedItems.map(item => item[this.valueProperty]);
7729
+ this.props.control.setValue(values);
7730
+ this.props.control.markAsDirty();
7731
+ this.props.control.updateValueAndValidity();
7732
+ }
7733
+ finally {
7734
+ this.isProcessingChanges = false;
7735
+ }
7736
+ }
7737
+ reset() {
7738
+ this.selectedItems = [];
7739
+ this.displayValue = '';
7740
+ if (this.props?.control) {
7741
+ this.props.control.setValue([]);
7742
+ }
7743
+ this.changeDetector.detectChanges();
7744
+ }
7745
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7746
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MultiSelectSearchComponent, isStandalone: true, selector: "val-multi-select-search", inputs: { label: "label", labelProperty: "labelProperty", valueProperty: "valueProperty", placeholder: "placeholder", props: "props" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
7747
+ <ion-input
7748
+ type="text"
7749
+ [value]="displayValue"
7750
+ [placeholder]="props?.placeholder || placeholder"
7751
+ readonly
7752
+ (mousedown)="preventDefaultBehavior($event)"
7753
+ />
7754
+
7755
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7756
+
7757
+ <ion-modal
7758
+ #modal
7759
+ trigger="open-modal"
7760
+ [initialBreakpoint]="1"
7761
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7762
+ (didDismiss)="cancelModal()"
7763
+ >
7764
+ <ng-template>
7765
+ <ion-header>
7766
+ <ion-toolbar>
7767
+ <ion-title>{{ label }}</ion-title>
7768
+ <ion-buttons slot="end">
7769
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7770
+ </ion-buttons>
7771
+ </ion-toolbar>
7772
+ <ion-toolbar>
7773
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7774
+ </ion-toolbar>
7775
+ </ion-header>
7776
+ <ion-content>
7777
+ <ion-list>
7778
+ <ion-item *ngFor="let item of filteredItems" button (click)="toggleItem(item)" detail="false">
7779
+ <ion-checkbox
7780
+ [checked]="isItemSelected(item)"
7781
+ slot="start"
7782
+ (ionChange)="toggleItem(item)"
7783
+ ></ion-checkbox>
7784
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7785
+ </ion-item>
7786
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7787
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7788
+ </ion-item>
7789
+ </ion-list>
7790
+ </ion-content>
7791
+ <ion-footer *ngIf="selectedItems.length > 0">
7792
+ <ion-toolbar>
7793
+ <ion-buttons slot="end">
7794
+ <ion-button (click)="clearSelection()">Limpiar</ion-button>
7795
+ <ion-button fill="solid" (click)="applySelection()">Aplicar ({{ selectedItems.length }})</ion-button>
7796
+ </ion-buttons>
7797
+ </ion-toolbar>
7798
+ </ion-footer>
7799
+ </ng-template>
7800
+ </ion-modal>
7801
+ `, isInline: true, styles: ["ion-header{padding:8px 8px 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: IonicModule }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCheckbox, selector: "ion-checkbox", inputs: ["alignment", "checked", "color", "disabled", "indeterminate", "justify", "labelPlacement", "mode", "name", "value"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonModal, selector: "ion-modal" }, { kind: "directive", type: i2.BooleanValueAccessor, selector: "ion-checkbox,ion-toggle" }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: SearchbarComponent, selector: "val-searchbar", inputs: ["disabled"], outputs: ["filterEvent", "focusEvent", "blurEvent"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] }); }
7802
+ }
7803
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MultiSelectSearchComponent, decorators: [{
7804
+ type: Component,
7805
+ args: [{ selector: 'val-multi-select-search', standalone: true, imports: [CommonModule, IonicModule, FormsModule, SearchbarComponent, ReactiveFormsModule], template: `
7806
+ <ion-input
7807
+ type="text"
7808
+ [value]="displayValue"
7809
+ [placeholder]="props?.placeholder || placeholder"
7810
+ readonly
7811
+ (mousedown)="preventDefaultBehavior($event)"
7812
+ />
7813
+
7814
+ <ion-input style="position: absolute;" [formControl]="props.control" type="hidden"></ion-input>
7815
+
7816
+ <ion-modal
7817
+ #modal
7818
+ trigger="open-modal"
7819
+ [initialBreakpoint]="1"
7820
+ [breakpoints]="[0, 0.5, 0.75, 1]"
7821
+ (didDismiss)="cancelModal()"
7822
+ >
7823
+ <ng-template>
7824
+ <ion-header>
7825
+ <ion-toolbar>
7826
+ <ion-title>{{ label }}</ion-title>
7827
+ <ion-buttons slot="end">
7828
+ <ion-button (click)="cancelModal()">Cerrar</ion-button>
7829
+ </ion-buttons>
7830
+ </ion-toolbar>
7831
+ <ion-toolbar>
7832
+ <val-searchbar (filterEvent)="onFilter($event)" (focusEvent)="onFocus()" (blurEvent)="onBlur()" />
7833
+ </ion-toolbar>
7834
+ </ion-header>
7835
+ <ion-content>
7836
+ <ion-list>
7837
+ <ion-item *ngFor="let item of filteredItems" button (click)="toggleItem(item)" detail="false">
7838
+ <ion-checkbox
7839
+ [checked]="isItemSelected(item)"
7840
+ slot="start"
7841
+ (ionChange)="toggleItem(item)"
7842
+ ></ion-checkbox>
7843
+ <ion-label>{{ item[labelProperty] }}</ion-label>
7844
+ </ion-item>
7845
+ <ion-item *ngIf="filteredItems.length === 0" lines="none">
7846
+ <ion-label color="dark">No se encontraron resultados</ion-label>
7847
+ </ion-item>
7848
+ </ion-list>
7849
+ </ion-content>
7850
+ <ion-footer *ngIf="selectedItems.length > 0">
7851
+ <ion-toolbar>
7852
+ <ion-buttons slot="end">
7853
+ <ion-button (click)="clearSelection()">Limpiar</ion-button>
7854
+ <ion-button fill="solid" (click)="applySelection()">Aplicar ({{ selectedItems.length }})</ion-button>
7855
+ </ion-buttons>
7856
+ </ion-toolbar>
7857
+ </ion-footer>
7858
+ </ng-template>
7859
+ </ion-modal>
7860
+ `, styles: ["ion-header{padding:8px 8px 0}\n"] }]
7861
+ }], ctorParameters: () => [], propDecorators: { modal: [{
7862
+ type: ViewChild,
7863
+ args: ['modal']
7864
+ }], label: [{
7865
+ type: Input
7866
+ }], labelProperty: [{
7867
+ type: Input
7868
+ }], valueProperty: [{
7869
+ type: Input
7870
+ }], placeholder: [{
7871
+ type: Input
7872
+ }], props: [{
7873
+ type: Input
7874
+ }] } });
7875
+
7516
7876
  class FormComponent {
7517
7877
  constructor(fb, elementRef) {
7518
7878
  this.fb = fb;
@@ -7522,16 +7882,8 @@ class FormComponent {
7522
7882
  this.onSelectChange = new EventEmitter();
7523
7883
  this.types = InputType;
7524
7884
  this.subscriptions = [];
7525
- // Cache processed field properties
7526
- this.processedSections = [];
7527
- this.previousValues = new Map();
7528
7885
  }
7529
7886
  ngOnInit() {
7530
- this.createForm();
7531
- this.processAllSections();
7532
- this.setupChangeTracking();
7533
- }
7534
- createForm() {
7535
7887
  const formControls = {};
7536
7888
  this.props.sections.forEach(section => {
7537
7889
  section.fields.forEach(field => {
@@ -7546,27 +7898,36 @@ class FormComponent {
7546
7898
  });
7547
7899
  });
7548
7900
  this.form = this.fb.group(formControls);
7901
+ this.props.sections.forEach(section => {
7902
+ section.fields
7903
+ .filter(x => x.type === this.types.SELECT || x.type === this.types.TEXT || x.type === this.types.SEARCH_SELECT || x.type === this.types.MULTI_SELECT)
7904
+ .forEach(field => {
7905
+ this.trackSelectChanges(field.name);
7906
+ });
7907
+ });
7549
7908
  }
7550
- processAllSections() {
7551
- console.log('[FormComponent] Processing all sections - ONE TIME ONLY');
7552
- this.processedSections = this.props.sections.map(section => ({
7553
- name: section.name,
7554
- fields: section.fields.map(field => this.processField(field))
7555
- }));
7909
+ ngOnDestroy() {
7910
+ // Cleanup subscriptions to avoid memory leaks
7911
+ this.subscriptions.forEach(sub => sub.unsubscribe());
7912
+ }
7913
+ trackSelectChanges(fieldName) {
7914
+ const control = this.getControl(fieldName);
7915
+ const subscription = control.valueChanges.subscribe(value => {
7916
+ this.onSelectChange.emit({ field: fieldName, value });
7917
+ });
7918
+ this.subscriptions.push(subscription);
7919
+ }
7920
+ async submitHandler(token) {
7921
+ this.onSubmit.emit({ fields: this.form.getRawValue(), token });
7922
+ }
7923
+ getControl(field) {
7924
+ return this.Form.get(field);
7556
7925
  }
7557
- processField(field) {
7558
- // Generate token if not provided
7926
+ getFieldProp(field) {
7927
+ field.token;
7559
7928
  if (!field.token) {
7560
7929
  field.token = `input-${field.type}-${field.name}`;
7561
7930
  }
7562
- // Debug: verificar opciones para select fields - SOLO UNA VEZ
7563
- if (field.type === this.types.SEARCH_SELECT || field.type === this.types.MULTI_SELECT || field.type === this.types.MULTI_SELECT_SIMPLE) {
7564
- console.log(`[FormComponent] Processing field ${field.name} options:`, {
7565
- type: field.type,
7566
- optionsCount: field.options?.length || 0,
7567
- options: field.options?.slice(0, 2) || []
7568
- });
7569
- }
7570
7931
  if (field.type === this.types.NUMBER_FROM_TO) {
7571
7932
  const fromControl = this.getControl(`${field.name}_from`);
7572
7933
  const toControl = this.getControl(`${field.name}_to`);
@@ -7578,11 +7939,12 @@ class FormComponent {
7578
7939
  fromControl.enable();
7579
7940
  toControl.enable();
7580
7941
  }
7581
- // Modify original field object to maintain reactivity
7582
- field.fromControl = fromControl;
7583
- field.toControl = toControl;
7584
- field.control = undefined; // Remove control for NUMBER_FROM_TO fields
7585
- return field;
7942
+ return {
7943
+ ...field,
7944
+ fromControl,
7945
+ toControl,
7946
+ control: undefined, // Remove control for NUMBER_FROM_TO fields
7947
+ };
7586
7948
  }
7587
7949
  else {
7588
7950
  const control = this.getControl(field.name);
@@ -7592,65 +7954,12 @@ class FormComponent {
7592
7954
  else {
7593
7955
  control.enable();
7594
7956
  }
7595
- // Modify original field object to maintain reactivity
7596
- field.control = control;
7597
- return field;
7957
+ return {
7958
+ ...field,
7959
+ control,
7960
+ };
7598
7961
  }
7599
7962
  }
7600
- setupChangeTracking() {
7601
- this.props.sections.forEach(section => {
7602
- section.fields
7603
- .filter(x => x.type === this.types.SELECT || x.type === this.types.TEXT || x.type === this.types.SEARCH_SELECT || x.type === this.types.MULTI_SELECT || x.type === this.types.MULTI_SELECT_SIMPLE)
7604
- .forEach(field => {
7605
- console.log(`[FormComponent] Tracking changes for field: ${field.name}, type: ${field.type}`);
7606
- this.trackSelectChanges(field.name);
7607
- });
7608
- });
7609
- }
7610
- ngOnDestroy() {
7611
- // Cleanup subscriptions to avoid memory leaks
7612
- this.subscriptions.forEach(sub => sub.unsubscribe());
7613
- }
7614
- trackSelectChanges(fieldName) {
7615
- const control = this.getControl(fieldName);
7616
- // Initialize previous value
7617
- this.previousValues.set(fieldName, control.value);
7618
- const subscription = control.valueChanges
7619
- .pipe(distinctUntilChanged$1()) // Evitar valores duplicados
7620
- .subscribe(value => {
7621
- console.log(`[FormComponent] valueChanges for ${fieldName}:`, {
7622
- field: fieldName,
7623
- newValue: value,
7624
- previousValue: this.previousValues.get(fieldName),
7625
- willEmit: this.previousValues.get(fieldName) !== value
7626
- });
7627
- // Evitar loops - solo emitir si el valor realmente cambió
7628
- const previousValue = this.previousValues.get(fieldName);
7629
- if (previousValue !== value) {
7630
- this.previousValues.set(fieldName, value);
7631
- console.log(`[FormComponent] EMITTING onSelectChange:`, { field: fieldName, value });
7632
- this.onSelectChange.emit({ field: fieldName, value });
7633
- }
7634
- else {
7635
- console.log(`[FormComponent] SKIPPING emit - same value for ${fieldName}`);
7636
- }
7637
- });
7638
- this.subscriptions.push(subscription);
7639
- }
7640
- async submitHandler(token) {
7641
- this.onSubmit.emit({ fields: this.form.getRawValue(), token });
7642
- }
7643
- getControl(field) {
7644
- return this.Form.get(field);
7645
- }
7646
- /**
7647
- * @deprecated This method is now only used internally.
7648
- * Use processedSections property instead to avoid multiple calls.
7649
- */
7650
- getFieldProp(field) {
7651
- console.warn('[FormComponent] getFieldProp is deprecated and should not be called directly');
7652
- return this.processField(field);
7653
- }
7654
7963
  get isAtEndOfForm() {
7655
7964
  return isAtEnd(this.elementRef);
7656
7965
  }
@@ -7663,19 +7972,6 @@ class FormComponent {
7663
7972
  data: this.props,
7664
7973
  };
7665
7974
  }
7666
- // Helper method to reset field value without triggering change event
7667
- resetField(fieldName, emitEvent = false) {
7668
- const control = this.getControl(fieldName);
7669
- const currentValue = control.value;
7670
- console.log(`[FormComponent] Resetting field ${fieldName}:`, { currentValue, emitEvent });
7671
- // Update our cache to avoid triggering change event
7672
- if (!emitEvent) {
7673
- this.previousValues.set(fieldName, '');
7674
- }
7675
- control.setValue('', { emitEvent });
7676
- control.markAsPristine();
7677
- control.markAsUntouched();
7678
- }
7679
7975
  get actions() {
7680
7976
  if (!this.form) {
7681
7977
  return [];
@@ -7706,53 +8002,56 @@ class FormComponent {
7706
8002
  size: 'large',
7707
8003
  }"
7708
8004
  ></val-display>
7709
- <div class="section" *ngFor="let s of processedSections">
8005
+ <div class="section" *ngFor="let s of props.sections">
7710
8006
  <val-title [props]="{ content: s.name, size: 'large', color: '', bold: false }"></val-title>
7711
8007
  <div class="input" *ngFor="let f of s.fields">
7712
8008
  <val-title [props]="{ content: f.label, size: 'small', color: 'dark', bold: false }"></val-title>
7713
8009
  <ng-container *ngIf="f.type === types.TEXT">
7714
- <val-text-input [props]="f"></val-text-input>
8010
+ <val-text-input [props]="getFieldProp(f)"></val-text-input>
7715
8011
  </ng-container>
7716
8012
  <ng-container *ngIf="f.type === types.CHECK">
7717
8013
  <val-check-input></val-check-input>
7718
8014
  </ng-container>
7719
8015
  <ng-container *ngIf="f.type === types.COMMENT">
7720
- <val-comment-input [props]="f"></val-comment-input>
8016
+ <val-comment-input [props]="getFieldProp(f)"></val-comment-input>
7721
8017
  </ng-container>
7722
8018
  <ng-container *ngIf="f.type === types.DATE">
7723
- <val-date-input [props]="f"></val-date-input>
8019
+ <val-date-input [props]="getFieldProp(f)"></val-date-input>
7724
8020
  </ng-container>
7725
8021
  <ng-container *ngIf="f.type === types.EMAIL">
7726
- <val-email-input [props]="f"></val-email-input>
8022
+ <val-email-input [props]="getFieldProp(f)"></val-email-input>
7727
8023
  </ng-container>
7728
8024
  <ng-container *ngIf="f.type === types.FILE">
7729
- <val-file-input [props]="f"></val-file-input>
8025
+ <val-file-input [props]="getFieldProp(f)"></val-file-input>
7730
8026
  </ng-container>
7731
8027
  <ng-container *ngIf="f.type === types.HOUR">
7732
- <val-hour-input [props]="f"></val-hour-input>
8028
+ <val-hour-input [props]="getFieldProp(f)"></val-hour-input>
7733
8029
  </ng-container>
7734
8030
  <ng-container *ngIf="f.type === types.NUMBER">
7735
- <val-number-input [props]="f"></val-number-input>
8031
+ <val-number-input [props]="getFieldProp(f)"></val-number-input>
7736
8032
  </ng-container>
7737
8033
  <ng-container *ngIf="f.type === types.NUMBER_FROM_TO">
7738
- <val-number-from-to [props]="f"></val-number-from-to>
8034
+ <val-number-from-to [props]="getFieldProp(f)"></val-number-from-to>
7739
8035
  </ng-container>
7740
8036
  <ng-container *ngIf="f.type === types.PASSWORD">
7741
- <val-password-input [props]="f"></val-password-input>
8037
+ <val-password-input [props]="getFieldProp(f)"></val-password-input>
7742
8038
  </ng-container>
7743
8039
  <ng-container *ngIf="f.type === types.PIN_CODE">
7744
- <val-pin-input [props]="f"></val-pin-input>
8040
+ <val-pin-input [props]="getFieldProp(f)"></val-pin-input>
7745
8041
  </ng-container>
7746
8042
  <ng-container *ngIf="f.type === types.RADIO">
7747
- <val-radio-input [props]="f"></val-radio-input>
8043
+ <val-radio-input [props]="getFieldProp(f)"></val-radio-input>
7748
8044
  </ng-container>
7749
8045
  <ng-container *ngIf="f.type === types.SELECT">
7750
- <val-select-input [props]="f"></val-select-input>
8046
+ <val-select-input [props]="getFieldProp(f)"></val-select-input>
7751
8047
  </ng-container>
7752
8048
  <ng-container *ngIf="f.type === types.SEARCH_SELECT">
7753
- <val-select-search [props]="f"></val-select-search>
8049
+ <val-select-search [props]="getFieldProp(f)"></val-select-search>
7754
8050
  </ng-container>
7755
- <val-hint [props]="f"></val-hint>
8051
+ <ng-container *ngIf="f.type === types.MULTI_SELECT">
8052
+ <val-multi-select-search [props]="getFieldProp(f)"></val-multi-select-search>
8053
+ </ng-container>
8054
+ <val-hint [props]="getFieldProp(f)"></val-hint>
7756
8055
  </div>
7757
8056
  <val-divider [props]="{ fill: 'solid', size: 'medium', color: 'medium' }"></val-divider>
7758
8057
  <ng-content></ng-content>
@@ -7763,7 +8062,7 @@ class FormComponent {
7763
8062
  ></val-button-group>
7764
8063
  </form>
7765
8064
  </div>
7766
- `, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["props"] }, { kind: "component", type: CheckInputComponent, selector: "val-check-input" }, { kind: "component", type: ButtonGroupComponent, selector: "val-button-group", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: DividerComponent, selector: "val-divider", inputs: ["props"] }, { kind: "component", type: HintComponent, selector: "val-hint", inputs: ["props"] }, { kind: "component", type: CommentInputComponent, selector: "val-comment-input", inputs: ["props"] }, { kind: "component", type: DateInputComponent, selector: "val-date-input", inputs: ["props"] }, { kind: "component", type: FileInputComponent, selector: "val-file-input", inputs: ["props"] }, { kind: "component", type: HourInputComponent, selector: "val-hour-input", inputs: ["props"] }, { kind: "component", type: EmailInputComponent, selector: "val-email-input", inputs: ["props"] }, { kind: "component", type: NumberInputComponent, selector: "val-number-input", inputs: ["props"] }, { kind: "component", type: NumberFromToComponent, selector: "val-number-from-to", inputs: ["props"] }, { kind: "component", type: RadioInputComponent, selector: "val-radio-input", inputs: ["props"] }, { kind: "component", type: PasswordInputComponent, selector: "val-password-input", inputs: ["props"] }, { kind: "component", type: PinInputComponent, selector: "val-pin-input", inputs: ["props"] }, { kind: "component", type: SelectSearchComponent, selector: "val-select-search", inputs: ["label", "labelProperty", "valueProperty", "multiple", "placeholder", "props"] }, { kind: "component", type: SearchSelectorComponent, selector: "val-select-input", inputs: ["props"] }] }); }
8065
+ `, isInline: true, styles: [":root{--ion-color-primary: #7026df;--ion-color-primary-rgb: 112, 38, 223;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #6321c4;--ion-color-primary-tint: #7e3ce2;--ion-color-secondary: #e2ccff;--ion-color-secondary-rgb: 226, 204, 255;--ion-color-secondary-contrast: #000000;--ion-color-secondary-contrast-rgb: 0, 0, 0;--ion-color-secondary-shade: #c7b4e0;--ion-color-secondary-tint: #e5d1ff;--ion-color-texti: #354c69;--ion-color-texti-rgb: 53, 76, 105;--ion-color-texti-contrast: #ffffff;--ion-color-texti-contrast-rgb: 255, 255, 255;--ion-color-texti-shade: #2f435c;--ion-color-texti-tint: #495e78;--ion-color-darki: #090f1b;--ion-color-darki-rgb: 9, 15, 27;--ion-color-darki-contrast: #ffffff;--ion-color-darki-contrast-rgb: 255, 255, 255;--ion-color-darki-shade: #080d18;--ion-color-darki-tint: #222732;--ion-color-medium: #9e9e9e;--ion-color-medium-rgb: 158, 158, 158;--ion-color-medium-contrast: #000000;--ion-color-medium-contrast-rgb: 0, 0, 0;--ion-color-medium-shade: #8b8b8b;--ion-color-medium-tint: #a8a8a8;--swiper-pagination-color: var(--ion-color-primary);--swiper-navigation-color: var(--ion-color-primary);--swiper-pagination-bullet-inactive-color: var(--ion-color-medium)}@media (prefers-color-scheme: dark){:root{--ion-color-texti: #8fc1ff;--ion-color-texti-rgb: 143, 193, 255;--ion-color-texti-contrast: #000000;--ion-color-texti-contrast-rgb: 0, 0, 0;--ion-color-texti-shade: #7eaae0;--ion-color-texti-tint: #9ac7ff;--ion-color-darki: #ffffff;--ion-color-darki-rgb: 255, 255, 255;--ion-color-darki-contrast: #000000;--ion-color-darki-contrast-rgb: 0, 0, 0;--ion-color-darki-shade: #e0e0e0;--ion-color-darki-tint: #ffffff;--ion-color-primary: #8f49f8;--ion-color-primary-rgb: 143, 73, 248;--ion-color-primary-contrast: #ffffff;--ion-color-primary-contrast-rgb: 255, 255, 255;--ion-color-primary-shade: #7e40da;--ion-color-primary-tint: #9a5bf9}}.ion-color-texti{--ion-color-base: var(--ion-color-texti);--ion-color-base-rgb: var(--ion-color-texti-rgb);--ion-color-contrast: var(--ion-color-texti-contrast);--ion-color-contrast-rgb: var(--ion-color-texti-contrast-rgb);--ion-color-shade: var(--ion-color-texti-shade);--ion-color-tint: var(--ion-color-texti-tint)}.ion-color-darki{--ion-color-base: var(--ion-color-darki);--ion-color-base-rgb: var(--ion-color-darki-rgb);--ion-color-contrast: var(--ion-color-darki-contrast);--ion-color-contrast-rgb: var(--ion-color-darki-contrast-rgb);--ion-color-shade: var(--ion-color-darki-shade);--ion-color-tint: var(--ion-color-darki-tint)}.section{margin-top:1rem}.input{margin:.5rem 0}@media (min-width: 768px){.input{margin:.75rem 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["props"] }, { kind: "component", type: CheckInputComponent, selector: "val-check-input" }, { kind: "component", type: ButtonGroupComponent, selector: "val-button-group", inputs: ["props"], outputs: ["onClick"] }, { kind: "component", type: DividerComponent, selector: "val-divider", inputs: ["props"] }, { kind: "component", type: HintComponent, selector: "val-hint", inputs: ["props"] }, { kind: "component", type: CommentInputComponent, selector: "val-comment-input", inputs: ["props"] }, { kind: "component", type: DateInputComponent, selector: "val-date-input", inputs: ["props"] }, { kind: "component", type: FileInputComponent, selector: "val-file-input", inputs: ["props"] }, { kind: "component", type: HourInputComponent, selector: "val-hour-input", inputs: ["props"] }, { kind: "component", type: EmailInputComponent, selector: "val-email-input", inputs: ["props"] }, { kind: "component", type: NumberInputComponent, selector: "val-number-input", inputs: ["props"] }, { kind: "component", type: NumberFromToComponent, selector: "val-number-from-to", inputs: ["props"] }, { kind: "component", type: RadioInputComponent, selector: "val-radio-input", inputs: ["props"] }, { kind: "component", type: PasswordInputComponent, selector: "val-password-input", inputs: ["props"] }, { kind: "component", type: PinInputComponent, selector: "val-pin-input", inputs: ["props"] }, { kind: "component", type: SelectSearchComponent, selector: "val-select-search", inputs: ["label", "labelProperty", "valueProperty", "multiple", "placeholder", "props"] }, { kind: "component", type: MultiSelectSearchComponent, selector: "val-multi-select-search", inputs: ["label", "labelProperty", "valueProperty", "placeholder", "props"] }, { kind: "component", type: SearchSelectorComponent, selector: "val-select-input", inputs: ["props"] }] }); }
7767
8066
  }
7768
8067
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FormComponent, decorators: [{
7769
8068
  type: Component,
@@ -7788,6 +8087,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7788
8087
  PasswordInputComponent,
7789
8088
  PinInputComponent,
7790
8089
  SelectSearchComponent,
8090
+ MultiSelectSearchComponent,
7791
8091
  SearchSelectorComponent,
7792
8092
  ], template: `
7793
8093
  <div class="container">
@@ -7800,53 +8100,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7800
8100
  size: 'large',
7801
8101
  }"
7802
8102
  ></val-display>
7803
- <div class="section" *ngFor="let s of processedSections">
8103
+ <div class="section" *ngFor="let s of props.sections">
7804
8104
  <val-title [props]="{ content: s.name, size: 'large', color: '', bold: false }"></val-title>
7805
8105
  <div class="input" *ngFor="let f of s.fields">
7806
8106
  <val-title [props]="{ content: f.label, size: 'small', color: 'dark', bold: false }"></val-title>
7807
8107
  <ng-container *ngIf="f.type === types.TEXT">
7808
- <val-text-input [props]="f"></val-text-input>
8108
+ <val-text-input [props]="getFieldProp(f)"></val-text-input>
7809
8109
  </ng-container>
7810
8110
  <ng-container *ngIf="f.type === types.CHECK">
7811
8111
  <val-check-input></val-check-input>
7812
8112
  </ng-container>
7813
8113
  <ng-container *ngIf="f.type === types.COMMENT">
7814
- <val-comment-input [props]="f"></val-comment-input>
8114
+ <val-comment-input [props]="getFieldProp(f)"></val-comment-input>
7815
8115
  </ng-container>
7816
8116
  <ng-container *ngIf="f.type === types.DATE">
7817
- <val-date-input [props]="f"></val-date-input>
8117
+ <val-date-input [props]="getFieldProp(f)"></val-date-input>
7818
8118
  </ng-container>
7819
8119
  <ng-container *ngIf="f.type === types.EMAIL">
7820
- <val-email-input [props]="f"></val-email-input>
8120
+ <val-email-input [props]="getFieldProp(f)"></val-email-input>
7821
8121
  </ng-container>
7822
8122
  <ng-container *ngIf="f.type === types.FILE">
7823
- <val-file-input [props]="f"></val-file-input>
8123
+ <val-file-input [props]="getFieldProp(f)"></val-file-input>
7824
8124
  </ng-container>
7825
8125
  <ng-container *ngIf="f.type === types.HOUR">
7826
- <val-hour-input [props]="f"></val-hour-input>
8126
+ <val-hour-input [props]="getFieldProp(f)"></val-hour-input>
7827
8127
  </ng-container>
7828
8128
  <ng-container *ngIf="f.type === types.NUMBER">
7829
- <val-number-input [props]="f"></val-number-input>
8129
+ <val-number-input [props]="getFieldProp(f)"></val-number-input>
7830
8130
  </ng-container>
7831
8131
  <ng-container *ngIf="f.type === types.NUMBER_FROM_TO">
7832
- <val-number-from-to [props]="f"></val-number-from-to>
8132
+ <val-number-from-to [props]="getFieldProp(f)"></val-number-from-to>
7833
8133
  </ng-container>
7834
8134
  <ng-container *ngIf="f.type === types.PASSWORD">
7835
- <val-password-input [props]="f"></val-password-input>
8135
+ <val-password-input [props]="getFieldProp(f)"></val-password-input>
7836
8136
  </ng-container>
7837
8137
  <ng-container *ngIf="f.type === types.PIN_CODE">
7838
- <val-pin-input [props]="f"></val-pin-input>
8138
+ <val-pin-input [props]="getFieldProp(f)"></val-pin-input>
7839
8139
  </ng-container>
7840
8140
  <ng-container *ngIf="f.type === types.RADIO">
7841
- <val-radio-input [props]="f"></val-radio-input>
8141
+ <val-radio-input [props]="getFieldProp(f)"></val-radio-input>
7842
8142
  </ng-container>
7843
8143
  <ng-container *ngIf="f.type === types.SELECT">
7844
- <val-select-input [props]="f"></val-select-input>
8144
+ <val-select-input [props]="getFieldProp(f)"></val-select-input>
7845
8145
  </ng-container>
7846
8146
  <ng-container *ngIf="f.type === types.SEARCH_SELECT">
7847
- <val-select-search [props]="f"></val-select-search>
8147
+ <val-select-search [props]="getFieldProp(f)"></val-select-search>
8148
+ </ng-container>
8149
+ <ng-container *ngIf="f.type === types.MULTI_SELECT">
8150
+ <val-multi-select-search [props]="getFieldProp(f)"></val-multi-select-search>
7848
8151
  </ng-container>
7849
- <val-hint [props]="f"></val-hint>
8152
+ <val-hint [props]="getFieldProp(f)"></val-hint>
7850
8153
  </div>
7851
8154
  <val-divider [props]="{ fill: 'solid', size: 'medium', color: 'medium' }"></val-divider>
7852
8155
  <ng-content></ng-content>