0

I have been scratching my head since the last so many days for the solution of an issue but unable to find it. Following is the description of the problem related to the dx tag box. https://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxTagBox/

Problem Description: I need to add custom values to the dxtagbox that are not already the members of the dxtagbox list. Following are my html and ts codes to achieve this thing. I have tried multiple things but no success up till now.

common.component.html

<div class="row">
<div class="form-group col-md-12 mt-2">
  <label>Region</label>
  <dx-tag-box id="region-lookup" [dataSource]="regionListLookup" class="time-box" [showClearButton]="true"
    style="height: auto !important;" [acceptCustomValue]="true"
    [applyValueMode]="'useButtons'" (onKeyUp)="onEmptyingList($event)" (onValueChanged)="onClearingList($event)" [showSelectionControls]=true
    [searchEnabled]="true" [value]="regions"
    displayExpr="Value" valueExpr="Key">
  </dx-tag-box>
</div>

common.component.ts

regions = [];
populateRegionslookup() {
 this.regionListLookup = {
  paginate: true,
  store: new CustomStore({
    key: 'Key',
    load: async (loadOptions) => {
      console.log('this: ', this);
      console.log('loadOptions: ', loadOptions);
      const paginatedData = { Text: loadOptions.searchValue, PageNo: loadOptions.skip, PageSize: loadOptions.take};
      const result = await this.reportsService.getRegionsMetaData(paginatedData)
        .toPromise();
      console.log('this.reportsService.getRegionsMetaData("{' + loadOptions.searchValue + ' })', result);
      result.map((resultItem) => {
        resultItem.Value = `${resultItem.Key} - ${resultItem.Value}`;
        return resultItem;
      });
      return result;
    },
    byKey: (key) => {
      console.log('from byKey: ', key);
      //code to return from api by key
    }
  })
 };
}
onEmptyingList(event) {
 if (event.event.key == 'Backspace' || event.event.key == 'Delete') {
   //For Tagbox
   if(event.element.id == 'region-lookup') {
     this.taggedRegions = event.value;
     this.timeReportsSearchModel.Region = this.taggedRegions;
     this.missingOfficeTagBoxComponent && this.missingOfficeTagBoxComponent.instance.getDataSource().reload();
   }
  }
}

onClearingList(event) {
 //For Tag Box
 if(event.element.id == 'region-lookup') {
   this.taggedRegions = event.value;
   this.timeReportsSearchModel.Region = this.taggedRegions;
   this.missingOfficeTagBoxComponent && this.missingOfficeTagBoxComponent.instance.getDataSource().reload();
  }
}

constructor(){
 this.regions = ["customValue1","customValue2","customValue3","customValue4"]
 this.populateRegionslookup();
}

Here, I want to forcefully add "regions" array value to the tagbox although these values are not coming from the api that is used to populate the tagbox items. I am not even able to type in the custom values in the tagbox on ui as shown in the devexpress' documentation.

Is there any way to achieve this or Am I just wasting my time and i should try some other approach?

Kindly help me out. Thanks

Sarim Javaid Khan
  • 810
  • 15
  • 30
  • `this.regions` is never added to the `DataSource`, how are you expecting it to appear? – briosheje May 30 '19 at 10:22
  • @briosheje This is what I need without having added these records in datasource. What is the need of [acceptCustomValue]="true" then? – Sarim Javaid Khan May 31 '19 at 09:46
  • From the docs: _Specifies whether the widget allows a user to enter a custom value. Requires the onCustomItemCreating handler implementation._ . Regardless whether you're not implementing the onCustomItemCreating method, you are confusing the meaning of the property: **it allows the USER to add values that does not exist in the datasource**. That means that whenever the user types a custom value, it **can** be added to the tag-box. You just need to **push** `this.regions` to your existing datasource (to `result`), that's it, it has nothing to do with that property, to me. – briosheje May 31 '19 at 10:32
  • @briosheje and how can I push that item to the existing datasource as it is the paginated datasource? Any idea? – Sarim Javaid Khan Jun 11 '19 at 17:18
  • 1
    Yes, you can easily add that to `result` when declaring the custom store (using concat, for example). Can you please share the structure of `result`? It's an array of objects, of course, but do object have a signature? – briosheje Jun 12 '19 at 06:39

1 Answers1

0

I have found the solution. I added the new values to the "result" object that the "load" method is returning. At the time of loading more data, I remove the already added members from the result array so they are not repeated.

load: async (loadOptions) => {
      console.log('this: ', this);
      console.log('loadOptions: ', loadOptions);
      const paginatedData = { Text: loadOptions.searchValue, PageNo: loadOptions.skip, PageSize: loadOptions.take};
      const result = await this.reportsService.getRegionsMetaData(paginatedData)
        .toPromise();
      console.log('this.reportsService.getRegionsMetaData("{' + loadOptions.searchValue + ' })', result);
      result.map((resultItem) => {
        resultItem.Value = `${resultItem.Key} - ${resultItem.Value}`;
        return resultItem;
      });
      this.addNewItemsToRegionLookup(result);
      return result;
    }
Sarim Javaid Khan
  • 810
  • 15
  • 30