Different data types in the same column

Posted by: productinfo on 28 March 2019, 2:23 am EST

  • Posted 28 March 2019, 2:23 am EST

    Hello We want to use different dataType in columns. For example some of them will be dataMap, and some of them input. That is, the dataType in a column varies by row based. How can we do that?

  • Posted 28 March 2019, 8:11 am EST

    <wj-flex-grid #flexGrid [itemsSource]=“collectionView”>

    <wj-flex-grid-column [width]=“150” [header]=“‘line_id’” [binding]=“‘line_id’”>

    <wj-flex-grid-column [width]=“‘‘" [header]=“‘code’” [binding]=“‘code’”>

    <wj-flex-grid-column [width]="’
    ’” [header]=“‘value’” [binding]=“‘value’”>

    import * as wjCore from ‘wijmo/wijmo’;

    import {Control} from ‘wijmo/wijmo’;

    import * as wjGrid from ‘wijmo/wijmo.grid’;

    import * as wjInput from ‘wijmo/wijmo.input’;

    import {findIndex, isEmpty} from ‘lodash’;

    data = ;

    r1Data;

    r2Data;

    r3Data;

    collectionView: wjCore.CollectionView;

    combinedMapData = ;

    ngOnInit() {

    this.data = [

    {

    line_id: 1,

    code: ‘0001’,

    type: ‘input’,

    value: ‘Test123’

    },

    {

    line_id: 2,

    code: ‘0002’,

    type: ‘dropdown’,

    value: 26

    },

    {

    line_id: 3,

    code: ‘0003’,

    type: ‘number’,

    value: 123

    },

    {

    line_id: 4,

    code: ‘0003’,

    type: ‘date’,

    value: new Date()

    },

    {

    line_id: 5,

    code: ‘0005’,

    type: ‘dropdown’,

    value: 38

    }

    ];

    this.r1Data = [
      {
        line_id: 1,
        id: 11,
        description: 'row_1_unit_1'
      },
      {
        line_id: 1,
        id: 12,
        description: 'row_1_unit_2'
      },
      {
        line_id: 1,
        id: 13,
        description: 'row_1_unit_3'
      }
    ];
    
    this.r2Data = [
      {
        line_id: 2,
        id: 21,
        description: 'row_2_unit_1'
      },
      {
        line_id: 2,
        id: 25,
        description: 'row_2_unit_2'
      },
      {
        line_id: 2,
        id: 26,
        description: 'row_2_unit_3'
      }
    ];
    
    this.r3Data = [
      {
        line_id: 5,
        id: 37,
        description: 'row_5_unit_1'
      },
      {
        line_id: 5,
        id: 38,
        description: 'row_5_unit_2'
      },
      {
        line_id: 5,
        id: 33,
        description: 'row_5_unit_3'
      }
    ];
    
    this.combinedMapData = [...this.r1Data, ...this.r2Data, ...this.r3Data];
    this.collectionView = new wjCore.CollectionView(this.data);
    this.flexGrid.prepareCellForEdit.addHandler((s, e: any) => {
      if (!(e.panel.cellType === wjGrid.CellType.Cell && s.columns[e.col].binding === 'value')) {
        return;
      }
      const rootEl = document.createElement('div');
      rootEl.style.width = '100%';
      rootEl.style.height = '100%';
      let control;
      const inputType = s.rows[e.row].dataItem['type'];
      const lineId = s.rows[e.row].dataItem['line_id'];
      switch (inputType) {
        case 'number':
          control = new wjInput.InputNumber(rootEl, {
            step: 5
          });
          control.value = Number(s.getCellData(e.row, e.col, false));
          break;
        case 'date':
          control = new wjInput.InputDate(rootEl, {});
          control.value = s.getCellData(e.row, e.col, false);
          break;
        case 'dropdown':
          control = new wjInput.ComboBox(rootEl, {
            itemsSource: this.getDataMap(lineId),
            displayMemberPath: 'description',
            selectedValuePath: 'id'
          });
          control.getDisplayValues = (item => {
            if (!item) {
              return this.combinedMapData.map(itemMap => itemMap.description);
            }
            const x = this.combinedMapData.filter((cItem) => {
              return cItem.line_id === item.line_id;
            }).map(itemMap => itemMap.description);
            return x;
          });
          break;
        case 'string':
          control = document.createElement('TextArea');
          control.value = s.getCellData(e.row, e.col, false);
          rootEl.appendChild(control);
          break;
        default:
          return;
      }
      if (s.activeEditor) {
        const parentCell = s.activeEditor.parentElement;
        parentCell.style.padding = '0';
        parentCell.insertBefore(rootEl, s.activeEditor);
        control.focus();
    
        if (!wjCore.isUndefined(control['text'])) {
          control['text'] = s.activeEditor.value;
        }
      }
    
      const cellEditEndHandler = (s2, args) => {
        s2.cellEditEnding.removeHandler(cellEditEndHandler);
        if (!args.cancel) {
          args.cancel = true;
    
          switch (inputType) {
            case 'number':
            case 'string':
            case 'date':
              s2.setCellData(args.row, args.col, control.value, false);
              break;
            case 'dropdown':
              s2.setCellData(args.row, args.col, control.selectedValue, false);
              break;
            default:
          }
          if (control.dispose) {
            control.dispose();
          }
        }
      };
      s.cellEditEnding.addHandler(cellEditEndHandler);
    });
    

    }

    getDataMap(lineId) {

    const item = ;

    for (let i = 0; i < this.combinedMapData.length; i++) {

    if (this.combinedMapData[i].line_id === lineId) {

    item.push(this.combinedMapData[i]);

    }

    }

    return item;

    }

    We solved this code. But we have another problem. Combobox is set to “id”, dispilayMemberPath is set to “description”. The display shows the value “id” after the editing has finished. But what should be is the value of “description”. All comboboxs have a different itemSource.

  • Posted 28 March 2019, 8:13 am EST

    selectedValuePath: “id”, displayMemberPath: “description”

  • Posted 29 March 2019, 5:22 am EST

    The rows with data type as data map are displaying the value of “id” instead of “description” since valueof row is being set using setCellData, also using the selectedValue property of combo box which will return the value of selectedValuePath. Instead, its suggested to use selectedItem property.

    Please refer to the updated sample:

    https://stackblitz.com/edit/angular-udjieh?file=src/app/app.component.ts

  • Posted 29 March 2019, 7:48 am EST

    your suggestion is not exactly solution for my problem because i cannot set same value for display and selected member path.

    I found something, it seems like solution my case but i am not sure whether it is true. Can you check my codes and tell me whether there is a better way?

    <wj-flex-grid #flexGrid [itemsSource]="collectionView">
              <wj-flex-grid-column [width]="150" [header]="'line_id'" [binding]="'line_id'"></wj-flex-grid-column>
              <wj-flex-grid-column [width]="'*'" [header]="'mcode'" [binding]="'code'"></wj-flex-grid-column>
              <wj-flex-grid-column [width]="'*'" [header]="'unit_set'" [binding]="'value'">
                <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell">
                  <div [ngSwitch]="getCellType(cell)">
                    <label *ngSwitchCase="'dropdown'">{{getDescription(cell.item.value).description}}</label>
                    <label *ngSwitchCase="'date'">{{cell.item.value | klDate}}</label>
                    <label *ngSwitchDefault>{{cell.item.value}}</label>
                  </div>
                </ng-template>
              </wj-flex-grid-column>
            </wj-flex-grid>
    
    
    /* add 2 method  */
    getCellType(cell) {
        return cell.item.type;
      }
    
      getDescription(value) {
        return this.combinedMapData.find(data => data.id === value);
      }
    
    
  • Posted 29 March 2019, 7:48 am EST

    switch (inputType) {
                case 'number':
                case 'string':
                case 'date':
                  s2.setCellData(args.row, args.col, control.value, false);
                  break;
                case 'dropdown':
                  s2.setCellData(args.row, args.col, control.selectedValue, false);
                  break;
                default:
              }
    
  • Posted 1 April 2019, 6:53 am EST

    Hi,

    It seems that your solution is working as expected. Could you please let me know if you are facing any issues with it?

  • Posted 2 April 2019, 5:09 am EST

    Your solution is better than our previous solution , in our solution, we were taking into account that the value of displayMemberPath and selectedValuePath should be same so we were doing something like this:

    s2.setCellData(args.row, args.col, control.selectedItem.description, false);
    

    But that was not the case as you said. In your solution, you are using a cell template that automatically gets the description of the cell in case of dropdown row.

    <label *ngSwitchCase="'dropdown'">{{getDescription(cell.item.value).description}}</label>
    

    Also, in our case, when the grid was loaded for the first time, the combo box showed the id of the object instead of its description, until it was first used. So we had to use the itemFormatter property of flexgrid to set the value of the combo box which had performance issues.

    This problem is also solved by the cell template as it also gets the initial value of combo box.

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels