HereToLearn_
HereToLearn_

Reputation: 1180

Kendo Angular2 MultiSelect not binding to the returned response

I am building an Angular2 application where on one of the pages we have MultiSelect component. Upon typing minimum of 3 characters it makes web service call and starts to show possible matches. When we select items in MultiSelect and save; I am saving ID's of the selected items in a table which is there just to save selected id's from the multiselect. To retrieve the data back in my web api call I am returning the object type which has all the information to display what I had save earlier in MultiSelect which includes Code as well as rest of supporting fields in CPTdata

My problem is when I browse to the page where I have MultiSelect control the selected value does not bind/display to the control. I looked at the web api response and validate that the selected values along with supporting fields are present there. Is there some other step I need to complete in order to display the saved values that I had selected earlier ?

Here is my html code:

<kendo-multiselect id="txtCptCode"  #CptCodemultiselect
                             [filterable]="true"
                            (filterChange)="handleCptFilter($event)"
                             [data]="CPTdata"
                             [textField]="'Code'"
                            (valueChange)="CptValueChange($event)"
                             [valueField]="'CptId'"
                             [(ngModel)]="Model.CPTCodes">
         </kendo-multiselect>

Here is handleCptFilter

handleCptFilter(value: any) {
      if (value.length >= 3) {
          this.cptRequest.value = value;
          this._surgeryRequestFormService.getCPTByCodeOrDesc1(this.cptRequest).subscribe(
              data => {
                  this.CPTdata = data;
              },
              error => {
                  console.log("Error", error);

              }
          )

      }
      else {
          console.log("Do nothing");
      }

};

Here is CptValueChange

public CptValueChange(value: any): void {
    var _this = this;
    var model = new surgeryReservationModel();

    if ((this.CPTdata != null) && (value != null || undefined || "")) {
        for (let entry of this.CPTdata) {
            for (let selectedCPT of value) {
                if (entry.Code == selectedCPT.Code) {
                    var CPTDescription;
                    if (_this.Model.CPTDescription != null)
                    {
                        CPTDescription = _this.Model.CPTDescription;
                        _this.Model.CPTDescription = (CPTDescription + "\n" + entry.ShortDescription);
                    }
                    else if (_this.Model.CPTDescription == null)
                    {
                      _this.Model.CPTDescription = entry.ShortDescription;
                    }

                    //    _this.surgeryReservationModel.CPTCodeId = entry.CptId;
                    console.log("CPT Description is " + "" + _this.Model.CPTDescription);
                    break;
                }
            }
        }
        console.log("valueChange", value);
    }
}

Upvotes: 0

Views: 1137

Answers (1)

jgraff
jgraff

Reputation: 46

As the Kendo documentation notes,

By default, when the Enter key is pressed or after the component loses focus, values that do not appear in the supplied list of items are dismissed.

I had the same problem with kendo-combobox: populating the items in the control with an API changes if previously selected items display. Change the search text and select something, and your selected items can disappear.

Short of:

  1. using another Angular control that behaves the way you want, or
  2. adding another control to display all the already selected items,

...the recommended Telerik approach is to use [allowCustom]=true then write a valueNormalizer function to add in dummy items that are missing.

// (pseudocode here)
valueNormalizer(text Observable<string>){
   if(text not in itemList){
      itemList.append({ text: text, value: text });
   } else {
      return {
      value: this.listItems[this.listItems.length - 1].value + 1, 
      text: text
      }
   }
}

I'm putting aside any discussion about whether this functionality makes sense - this is just how you could do it!

Upvotes: 1

Related Questions