Setting ComboBox value doesn't display the new value

Hello,
I am trying to validate user input in a ComboBox with customValueSpecifier. When the user input is not valid I want to set a valid value. I can set it without problem, but combobox doesn't display the new value.

<ejs-combobox
  id="comboHoras"
  #comboHoras
  [(ngModel)]="hora"
  [dataSource]="horas"
  class="timePicker"
  allowCustom="true"
  fields="fields"
  (customValueSpecifier)="validar($event)"
></ejs-combobox>


import { ComponentInputOnInitViewChild } from '@angular/core';
import { ComboBoxComponent } from '@syncfusion/ej2-angular-dropdowns';
import { Turno } from '../services/sigeca.api';

@Component({
  selector: 'sc-combo-horas',
  templateUrl: './combo-horas.component.html',
  styleUrls: ['./combo-horas.component.scss']
})
export class ComboHorasComponent implements OnInit {

  @Input() turnoTurno;
  @Input() fechaDate;

  @ViewChild('comboHoras'comboHorasComboBoxComponent;

  horas = new Array<any>();
  horastring;
  fields = { text: 'text'value: 'value' };
  jsonany;

  constructor() {

  }

  ngOnInit(): void {
    this.hora = this.fecha.toLocaleTimeString([], { hour: '2-digit'minute: '2-digit'hour12: false });
    this.horasTurno();
  }

  horasTurno() {
    this.turno.horas.forEach(hora => {
      let textArg = ('00' + hora).slice(-2) + ':00';
      let valueArg = textArg;
      this.horas.push({text: textArgvalue: valueArg});
      textArg = ('00' + hora).slice(-2) + ':30';
      valueArg = textArg;
      this.horas.push({text: textArgvalue: valueArg});
    });
    // this.horas.push(('00' + (this.turno.horas[this.turno.horas.length - 1] + 1)).slice(-2) + ':00');
  }

  validar(event) {
    const horaMinuto = event.text.split(':');
    if (horaMinuto.length !== 2) {
      this.resetHora();
      return;
    }
    if (isNaN(+horaMinuto[0]) || this.turno.horas.findIndex(h => h === +horaMinuto[0]) === -1) {
      this.resetHora();
      return;
    }
    if (isNaN(+horaMinuto[1]) || +horaMinuto[1] < 0 || +horaMinuto[1] > 59) {
      this.resetHora();
      return;
    }
  }

  resetHora() {
    // Changing this.hora changes the combo value because is the bounded variable, but it doesn't change dispalyed text
    this.hora = new Date().toLocaleTimeString([], { hour: '2-digit'minute: '2-digit'hour12: false });
    console.log(this.comboHoras.value);
    // Changing combo value does change it's value, but it doesn't change displayed text
    this.comboHoras.value = '05:45';
    // Setting text doesn't change displayed text either
    this.comboHoras.text = new Date().toLocaleTimeString([], { hour: '2-digit'minute: '2-digit'hour12: false });
    console.log(this.comboHoras.value);
  }

}

Any idea why this is happening?

Thanks in advance

7 Replies 1 reply marked as answer

BC Berly Christopher Syncfusion Team March 19, 2021 03:38 PM UTC

Hi Matia, 
  
Greetings from Syncfusion support. 
  
We have checked the reported issue and when you type the custom value in the combo box component then customValueSpecifier event will be fired. But the value will not be added to the popup element. So, we need to push the entered custom value in the data source as mentioned in the below demo sample and documentation.  
  
  
  
  
For your convenience, we have prepared the sample and attached it below. 
  
  let newItem: { [keystring]: Object } = { 
    Name: customValue, 
    Code: customValue 
  }; 
  // new object added to data source. 
  (this.comboObj.dataSource as Object[]).push(newItem); 
  // close the popup element. 
  this.comboObj.hidePopup(); 
  // pass new object to addItem method. 
  this.comboObj.addItem(newItem); 
  // select the newly added item. 
  this.comboObj.value = customValue; 
 
  
Still facing issues, please share any issue reproducing sample or modify the attached sample with reported issue that will help us to check and proceed further at our end. 
  
Regards, 
Berly B.C 



MF Matia Fundazioa March 23, 2021 10:36 AM UTC

Hi Berly,
The example provided doesn't use customValueSpecifier. I have made a small proyect as a proof of concept using customValueSpecifier but I can't change the value:

import { ComponentViewChild } from '@angular/core';
import { ComboBoxComponentCustomValueSpecifierEventArgs } from '@syncfusion/ej2-angular-dropdowns';

@Component({
  selector: 'app-root',
  template: `
  <ejs-combobox
  id="country"
  #sample
  [dataSource]="data"
  [fields]="fields"
  allowCustom="true"
  (customValueSpecifier)="newCountry($event)"
  [(value)]="country">
  ejs-combobox>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'customValue';
  countrystring;

  @ViewChild('sample'sampleComboBoxComponent;

  public fieldsany = { text: 'Name'value: 'Code' };
  public data: { [keystring]: any; }[] = [
    { Name: 'Australia'Code: 'AU' },
    { Name: 'Bermuda'Code: 'BM' },
    { Name: 'Canada'Code: 'CA' },
    { Name: 'Cameroon'Code: 'CM' },
    { Name: 'Denmark'Code: 'DK' },
    { Name: 'France'Code: 'FR' },
    { Name: 'Finland'Code: 'FI' },
    { Name: 'Germany'Code: 'DE' },
    { Name: 'Greenland'Code: 'GL' },
    { Name: 'Hong Kong'Code: 'HK' },
    { Name: 'India'Code: 'IN' },
    { Name: 'Italy'Code: 'IT' }
  ];

  newCountry(eventCustomValueSpecifierEventArgs) {
    // I try to change user enterd value
    let text = event.text;
    if (text === 'Holland') {
      text = 'Nederland';
    }
    const newItem: { [keystring]: any; } = { 'Name': text'Code': text };
    // new object added to data source.
    (this.sample.dataSource as any[]).push(newItem);
    // close the popup element.
    this.sample.hidePopup();
    // pass new object to addItem method.
    this.sample.addItem(newItem);
    // select the newly added item.
    this.sample.value = text;
    // The bounded variable updates OK, but combobox doesn't reflect the change
    console.log(this.country);
  }
}



The customValueSpecifier gets called endlessly and finally throws the following error:
core.js:6241 ERROR RangeError: Maximum call stack size exceeded at SafeSubscriber.unsubscribe (Subscription.js:37) at SafeSubscriber.unsubscribe (Subscriber.js:69) at SafeSubscriber.__tryOrUnsub (Subscriber.js:186) at SafeSubscriber.next (Subscriber.js:122) at Subscriber._next (Subscriber.js:72) at Subscriber.next (Subscriber.js:49) at EventEmitter.next (Subject.js:39) at FormBase.push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.trigger (component-base.js:306) at FormBase.customValue (ej2-dropdowns.es2015.js:7661) at FormBase.hidePopup (ej2-dropdowns.es2015.js:7838) defaultErrorLogger @ core.js:6241 handleError @ core.js:6294 handleError @ core.js:13881 executeListenerWithErrorHandling @ core.js:21863 wrapListenerIn_markDirtyAndPreventDefault @ core.js:21902 schedulerFn @ core.js:37225

Could you please provide a working example of customValueSpecifier event used to change combobox value?
Thanks



BC Berly Christopher Syncfusion Team March 24, 2021 07:32 AM UTC

Hi Matia, 
  
We were able to reproduce the reported issue. As you requested, we have added the work around solution for adding the entered custom value into the ComboBox component in the customValueSpecifier event. Kindly refer the below code example and sample. 
  
public customValueSpecifier(args) { 
  // I try to change user enterd value 
  let text = args.text; 
  if (text === "Holland") { 
    text = "Nederland"; 
  } 
  const newItem: { [keystring]: any } = { Name: textCode: text }; 
  // close the popup element. 
  this.comboObj.hidePopup(); 
  // pass new object to addItem method. 
  this.comboObj.addItem(newItem); 
  // select the newly added item. 
  this.comboObj.value = text; 
  // The bounded variable updates OK, but combobox doesn't reflect the change 
  console.log(this.country); 
} 
 
  
  
Screenshot: 
  
 
  
Regards, 
Berly B.C 



MF Matia Fundazioa March 24, 2021 07:48 AM UTC

Hi Berly,
The provided code doesn't work either. The thing isn't to provide only a custom value, it's to change it in the customValueSpecifier. In the example code, if you enter Holland it has to be changed to Nederland and it doesn't:


It crashes as reported.
Regards


BC Berly Christopher Syncfusion Team March 25, 2021 09:29 AM UTC

Hi Matia, 
  
While entered the custom value and the focus out the component then popup will be hide and entered value will be added to the li element. If we call the HidePopup() method again, then the mentioned console error “Maximum call stack exceeded” issue occurred in the application. 
  
So, we have modified the sample based on the requirement for entering the “Holland” value to “Nederland” and attached it below. 
  
    public customValueSpecifier(args) { 
        let text = args.text; 
        if (text == "Holland") { 
          text = "Nederland"; 
        } 
        const newItem: { [keystring]: any } = { Name: textCode: text }; 
        this.comboObj.addItem(newItem); 
        // select the newly added item. 
        this.comboObj.value = text; 
        // The bounded variable updates OK, but combobox doesn't reflect the change 
        console.log(this.country); 
        setTimeout(() => { 
          (this.comboObj as any).inputElement.value = text; 
        }, 10); 
      } 
 
  
  
Regards, 
Berly B.C 


Marked as answer

MF Matia Fundazioa March 25, 2021 09:41 AM UTC

Hi Berly,
Now it works as expected, although the solution seems a little bit hackish.
I had tested without hiding the popup and no success, so the missing bit was to set the value to the inputElement.value with a delay and not to this.comboObj.value as stated earlier. 
setTimeout(() => {
      (this.comboObj as any).inputElement.value = text;
    }, 10);

Thank you very much



BC Berly Christopher Syncfusion Team March 26, 2021 08:17 AM UTC

Hi Matia, 
  
Most welcome. Please let us know if you need further assistance on this. 
  
Regards, 
Berly B.C 


Loader.
Up arrow icon