Wijmo5 flexgrid with Angular8 - Changing Datamap selection reverts changed text

Posted by: madhuchhanda_kar on 9 March 2020, 2:59 pm EST

    • Post Options:
    • Link

    Posted 9 March 2020, 2:59 pm EST

    I am using wijmo 5 flexgrid with Angular 8 and trying to create an inline editable grid with Edit button at every row. Each row has a datamap column and a text column both of which should be editable when the Edit button of that specific row is clicked. After clicking Edit button, first the text field (Employee Name) is edited. After that, when I change selection of the datamap dropdown (Department), the changed text in the text field reverts to the original text. How to keep the changed text in Employee Name text field after selection change in Department datamap field? The Code is in the link : https://stackblitz.com/edit/angular-g9wk57?file=app%2Fapp.component.ts

    app.component.ts

    import { Component, ViewChild } from '@angular/core';
    import { CollectionView, ObservableArray } from 'wijmo/wijmo';
    import * as wjCore from 'wijmo/wijmo';
    import * as wjInput from 'wijmo/wijmo.input';
    import * as wjGrid from 'wijmo/wijmo.grid';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      private _currentEditItem: any = null;
    
      public data : any;
      public deptList: any = [
        {'deptId':'D1', 'deptName':'Accounts'},
        {'deptId':'D2', 'deptName':'Development'},
        {'deptId':'D3', 'deptName':'HR'}
        ];
    
        public empList: any = [
          {'empId':'E1', 'empName':'AA', 'deptId':'D3'},
          {'empId':'E2', 'empName':'BB', 'deptId':'D2'},
          {'empId':'E3', 'empName':'CC', 'deptId':'D1'},
          {'empId':'E4', 'empName':'DD', 'deptId':'D2'}
        ];
    
      @ViewChild('flex') flex:wjGrid.FlexGrid;
    
    public deptMap = new wjGrid.DataMap(this.deptList, 'deptId', 'deptName');
        constructor() {
          this.data = new wjCore.CollectionView(this.empList);
      }  
    
    initializeGrid(flex: wjGrid.FlexGrid) {
        flex.rows.defaultSize = 40;
        // custom formatter to paint buttons and editors
        flex.formatItem.addHandler((s: wjGrid.FlexGrid, e: wjGrid.FormatItemEventArgs) => {
          if (e.panel == s.cells) {
            let col = s.columns[e.col],
              item = s.rows[e.row].dataItem;
            if (item == this._currentEditItem) {
              // create editors and buttons for the item being edited
              switch (col.binding) {
                case 'buttons':
                  e.cell.innerHTML = document.getElementById('tplBtnEditMode').innerHTML;
                  e.cell['dataItem'] = item;
                  break;            
                case 'empName':
                  e.cell.innerHTML = '<input class="form-control" ' +
                    'id="' + col.binding + '" ' +
                    'value="' + s.getCellData(e.row, e.col, true) + '"/>';
                  break;
              }
            } else {
              // create buttons for items not being edited
              switch (col.binding) {
                case 'buttons':
                  e.cell.innerHTML = document.getElementById('tplBtnViewMode').innerHTML;
                  e.cell['dataItem'] = item;
                  break;
              }
            }
          }
        });
    
        // handle button clicks
        flex.addEventListener(flex.hostElement, 'click', (e: MouseEvent) => {
          let targetBtn: HTMLButtonElement;
          if (e.target instanceof HTMLButtonElement) {
            targetBtn = e.target;
          }
          // else if (e.target instanceof HTMLSpanElement && e.target.classList.contains('glyphicon')) {
          //   targetBtn = e.target.parentElement as HTMLButtonElement;
          // }
          if (targetBtn) {
            // get button's data item
            let item = wjCore.closest(targetBtn, '.wj-cell')['dataItem'];
            // handle buttons
            switch (targetBtn.id) {
              // start editing this item
              case 'btnEdit':
                this._editItem(item);
                break;
              // remove this item from the collection
              // case 'btnDelete':
              //   (<wjCore.CollectionView>flex.collectionView).remove(item);
              //   break;
              // commit edits
              case 'btnOK':
                this._commitEdit();
                break;
              // cancel edits
              case 'btnCancel':
                this._cancelEdit();
                break;
            }
          }
          e.preventDefault();
        });
    
        // exit edit mode when scrolling the grid or losing focus
        flex.scrollPositionChanged.addHandler(this._cancelEdit.bind(this));
        flex.lostFocus.addHandler(this._cancelEdit.bind(this));
      }
    
      private _editItem(item: any) {
        this._cancelEdit();
        this._currentEditItem = item;
        this.flex.invalidate();
      }
    
      private _commitEdit() {
        if (this._currentEditItem) {
          this.flex.columns.forEach((col: any) => {
            let input = <HTMLInputElement>this.flex.hostElement.querySelector('#' + col.binding);
            if (input) {
              let value = wjCore.changeType(input.value, col.dataType, col.format);
              if (wjCore.getType(value) == col.dataType) {
                this._currentEditItem[col.binding] = value;
              }
            }
          });
        }
    
        console.log(this._currentEditItem);
        this._currentEditItem = null;
        this.flex.invalidate();
      }
    
      private _cancelEdit() {
        if (this._currentEditItem) {
          this._currentEditItem = null;
          this.flex.invalidate();
        }
      }
    
    }
    
    

    app.component.html

    
    <div class="header">
        <div class="container">
            <h1>
                DataMap
            </h1>
        </div>
    </div>
    
    <!-- content -->
    <div class="container">
        <div>
            <wj-flex-grid #flex [itemsSource]="data"
                [headersVisibility]="'Column'" (initialized)="initializeGrid(flex)">
                <wj-flex-grid-column [header]="'Employee Name'" [binding]="'empName'" [width]="'4*'">
                </wj-flex-grid-column>
                <wj-flex-grid-column [header]="'Department'" [binding]="'deptId'" [width]="'4*'" [dataMap]="deptMap">
                </wj-flex-grid-column>
                <wj-flex-grid-column [header]="'Actions'" [binding]="'buttons'" [width]="'3*'"></wj-flex-grid-column>
            </wj-flex-grid>
    
            <!-- template for buttons on items in view mode -->
            <div id="tplBtnViewMode" style="display:none">
                <button id="btnEdit" class="btn btn-default btn-sm">
            Edit
        </button>
            </div>
    
            <!-- template for buttons on items in edit mode -->
            <div id="tplBtnEditMode" style="display:none">
                <button id="btnOK" class="btn btn-primary btn-sm">
            OK
        </button>
                <button id="btnCancel" class="btn btn-warning btn-sm">
            Cancel
        </button>
            </div>
        </div>
    </div>
    
  • Posted 11 March 2020, 12:59 am EST

    Hi Madhu,

    The reason that the Employee name is reverted back is because when the DataMap is edited, the CollectionView internally commits the edits and refreshed the FlexGrid. But, the edit in the input field is not committed yet so the CollectionView does not know about the new value and refreshes the FlexGrid with the original value.

    To solve this issue, instead of using DataMap, you can use ComboBox to edit the values.

    Please refer to the updated sample link below:

    https://stackblitz.com/edit/angular-ehavh9

    Regards,

    Ashwin

  • Posted 9 April 2020, 6:15 pm EST

    Thanks Aswin, it works.

Need extra support?

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

Learn More

Forum Channels