Search code examples
javascripthtmlangulartypescriptslickgrid

Angular Slickgrid- how to update or replace particular cell value with the option selected in context-menu


I'm refereeing this example of slickgrid for context-menu

In the image given below I'm using angular-slickgrid along with ngx-contextmenu, where I'm displaying my context menu only when a particular cell is clicked in status column, Based on particular cell value different option has been displayed in context-menu.

My problem is when I want to update or replace that particular cell value with the selected option from context menu eg: "Inprogress" should replace or update as "Suspended" from context-menu.

Image of angular-slickgrid with ngx-context menu

HTML code

/**************HTML code********************/    

 /**********angular-slickgrid code************/                                       
<div id="container">
 <angular-slickgrid                                                                     
  gridId="grid" 
 (onAngularGridCreated)="angularGridReady($event)" 
  gridWidth="'90%'" 
  [columnDefinitions]="columnDefinitions"   
  [gridOptions]="gridOptions" 
  [dataset]="dataset" 
  (onGridStateChanged)="gridStateChanged($event)">
  </angular-slickgrid>
</div>   

/*************ngx-contextmenu code***********/ 

<context-menu #editMenuRight>
  <ng-template *ngFor="let item of mainOption" contextMenuItem>
     <li #myLi class="myLi" data="low" (click)="test1()">{{item?.option}}</li>
  </ng-template>                                                                             
</context-menu>

Angular Component code

/*************Angular Component code***********/ 

import { Component, OnInit, Injectable, ViewEncapsulation, HostListener, ViewChild, Input,
ElementRef } from "@angular/core";
import { Headers, RequestOptions } from '@angular/http';
import { Http, Response } from '@angular/http';
import {
Column, GridOption, AngularGridInstance,
Filters, ExtensionName, FieldType, Formatter, Formatters,
Editors,EditorArgs, EditorValidator, Statistic, GridStateChange,
GridOdataService, OperatorType, OnEventArgs, MultipleSelectOption
} from 'angular-slickgrid';
import { ContextMenuComponent } from 'ngx-contextmenu';
import { ContextMenuService } from 'ngx-contextmenu'; 

@Component({
selector: 'app-schedule',
templateUrl: './schedule.component.html',
styleUrls: ['./schedule.component.css'],
encapsulation: ViewEncapsulation.None
})

export class ScheduleComponent implements OnInit {

/*******my option which I'm showing for particular cell if cell value matches with option****/
 public mainOption: any[];
 public scheduleOption: any[] = [{
 option: 'Scheduled',
 }, {
 option: 'Suspended',
 },
 {
 option: 'Abort',
 }];
 public suspendedOption: any[] = [{
 option: 'Suspended',
}, {
option: 'Scheduled',
},
{
option: 'Abort',
}];
public inprogressOption: any[] = [{
option: 'Inprogress',
}, {
option: 'Suspended',
},
{
option: 'Abort',
}];
public abortOption: any[] = [
{
option: 'Abort',
}];
public completeOption: any[] = [
{
  option: 'Completed',
}];
@ViewChild('editMenuRight') public editMenuRight: ContextMenuComponent;
@ViewChild("myLi") divView: ElementRef;
@Input() contextMenu: ContextMenuComponent;

constructor(private http: Http,
private httpClient: HttpClient,
private elementRef:ElementRef,
private remoteservercommunicationservice: RemoteServerCommunicationService,
public pathstorageservice: PathStorageService,
private globaldataservice: GlobalDataService,
private contextMenuService: ContextMenuService)
);

angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.gridObj = angularGrid && angularGrid.slickGrid || {};
 }

/********* display context-menu code******/
public onContextMenu($event, item: any): void {
console.log(item);
console.log($event);
setTimeout(() => {
this.contextMenuService.show.next({
contextMenu: this.contextMenu,
  event: $event,
  item: item,
});
$event.preventDefault();
$event.stopPropagation();
});
}

 ngOnInit() {
   this.columnDefinitions = [
  {
    id: 'Status',
    name: 'Status',
    field: 'Status',
    sortable: true,
    filterable: true,
    onCellClick: (e, args) => {
      let v = args.dataContext.Status;
      var cell = this.angularGrid.slickGrid.getCellFromEvent(e);
      var msg = this.angularGrid.slickGrid.getColumns()[cell.cell].id;
      console.log(cell);
      console.log(msg);
      /******** replacing option based on cell value******/
       if (v == "Scheduled")
      {
        this.mainOption = this.scheduleOption; /***** replacing option here******/
        this.onContextMenu(e,'right'); /***opening context-menu on cell click if its true***/ 
        return  this.mainOption;
      }
      if (v == "Inprogress")
      {
        this.mainOption = this.inprogressOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Completed")
      {
        this.mainOption = this.completeOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Abort")
      {
        this.mainOption = this.abortOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Suspended")
      {
        this.mainOption = this.suspendedOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
     return  this.mainOption;
     }
   }
  ]
 }
   /*** my problem is here, I want to fetch particular <li> tag value and replace or update the 
        particular cell with that fetch value after click in context menu or with particular option 
        selected in menu***********/   

 ngAfterViewInit() {
 $(document).ready(function () {
  $("#editMenuRight").click(function (e) {
    if (!$(e.target).is("li")) {
      return;
    }
    if (! this.gridObj.getEditorLock().commitCurrentEdit()) {
      return;
    }
    var row = $(this).data("row");
    this.dataset[row].Status = $(e.target).attr("data");
    this.gridObj.updateRow(row);
   });
  });
  }

Solution

  • I've figure out to update the cell using ngx-context menu below is the gif image of my solution hope it may help someone.

    Slickgrid with ngx-context menu

    Html code

    /********************HTML code*******************/
    <context-menu #editMenuRight>
     <ng-template (execute)="gridUpdate()" *ngFor="let item of mainOption" contextMenuItem>
        <ul id="contextMenu">
            <li #myLi class="myLi" data="Low">
                <img src="assets\images\statusMenu\{{item?.src}}" style="width:20px; 
                 height:15px; display: inline-block;" class="image">
                <div>
                    {{item?.option}}
                </div>
            </li>
        </ul>
     </ng-template>
    </context-menu>
    

    Component-code

    /*********Component code***********/
    import { Component, OnInit, Injectable, ViewEncapsulation, HostListener, ViewChild, 
    Input,
    ElementRef } from "@angular/core";
    import { Headers, RequestOptions } from '@angular/http';
    import { Http, Response } from '@angular/http';
    import {
    Column, GridOption, AngularGridInstance,
    Filters, ExtensionName, FieldType, Formatter, Formatters,
    Editors,EditorArgs, EditorValidator, Statistic, GridStateChange,
    GridOdataService, OperatorType, OnEventArgs, MultipleSelectOption
    } from 'angular-slickgrid';
    import { ContextMenuComponent } from 'ngx-contextmenu';
    import { ContextMenuService } from 'ngx-contextmenu'; 
    
    @Component({
    selector: 'app-schedule',
    templateUrl: './schedule.component.html',
    styleUrls: ['./schedule.component.css'],
    encapsulation: ViewEncapsulation.None
    })
    
    export class ScheduleComponent implements OnInit {
    
    /***********************context-menu option & src id for image icon ****************/
    cellValue: any;
    public mainOption: any[];
    public scheduleOption: any[] = [{
    option: 'Scheduled', src:'schedule.png'
    }, {
    option: 'Suspended', src:'suspended.png'
    },
    {
    option: 'Abort', src:'abort.png'
    }];
    public suspendedOption: any[] = [{
    option: 'Suspended', src:'suspended.png'
    }, {
    option: 'Scheduled', src:'schedule.png'
    },
    {
    option: 'Abort',  src:'abort.png'
    }];
    public inprogressOption: any[] = [{
    option: 'Inprogress', src:'inprogress.png'
    }, {
    option: 'Suspended', src:'suspended.png'
    },
    {
    option: 'Abort', src:'abort.png'
    }];
    public abortOption: any[] = [
    {
    option: 'Abort',  src:'abort.png'
    }];
    public completeOption: any[] = [
    {
      option: 'Completed', src:'complete.png'
     }];
    
    /****************************************/
    
    @ViewChild('editMenuRight') public editMenuRight: ContextMenuComponent;
    @Input() contextMenu: ContextMenuComponent;
    
      constructor(private http: Http,
      private httpClient: HttpClient,
      private elementRef:ElementRef,
      private remoteservercommunicationservice: RemoteServerCommunicationService,
      public pathstorageservice: PathStorageService,
      private globaldataservice: GlobalDataService,
      private contextMenuService: ContextMenuService)
     );
    
     angularGridReady(angularGrid: AngularGridInstance) {
     this.angularGrid = angularGrid;
     this.gridObj = angularGrid && angularGrid.slickGrid || {};
     }
    
     ngOnInit() {
     this.columnDefinitions = [
     {
     id: 'Status',
     name: 'Status',
     field: 'Status',
     sortable: true,
     filterable: true,
     onCellClick: (e, args) => {
      let v = args.dataContext.Status;
          console.log(v);
          var cell = this.angularGrid.slickGrid.getCellFromEvent(e);
          this.cellValue = cell.row;        // to get particular cell row number on click
          var msg = this.angularGrid.slickGrid.getColumns()[cell.cell].id;
          console.log(cell);
          console.log(msg);
    
      /******** replacing option based on cell value******/
       if (v == "Scheduled")
      {
        this.mainOption = this.scheduleOption; /***** replacing option here******/
        this.onContextMenu(e,'right'); /***opening context-menu on cell click if its 
        true***/ 
        return  this.mainOption;
      }
      if (v == "Inprogress")
      {
        this.mainOption = this.inprogressOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Completed")
      {
        this.mainOption = this.completeOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Abort")
      {
        this.mainOption = this.abortOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
      if (v == "Suspended")
      {
        this.mainOption = this.suspendedOption;
        this.onContextMenu(e,'right');
        return  this.mainOption;
      }
     return  this.mainOption;
        }
       }
     ]
    }
      /**********context menu open code*************/
     public onContextMenu($event, item: any): void {
     console.log(item);
     console.log($event);
     setTimeout(() => {
     this.contextMenuService.show.next({
      contextMenu: this.contextMenu,
      event: $event,
      item: item,
     });
    $event.preventDefault();
    $event.stopPropagation();
    });
    }
    /******************************************/
    
    /****************************event to fetch selected option of context menu */
    fetchValue(event){
     let check1 = event.target.innerText;
     this.check2 = check1;
      console.log(check1);
      console.log(event.target.innerText);
      }
     /***********************************************************/
    
     /**********************event to update the grid with selected value from context- 
      menu*******/
     gridUpdate(){
     this.fetchValue(event);
     console.log(this.cellValue);
     const updatedItem = 
     this.angularGrid.gridService.getDataItemByRowNumber(this.cellValue);
     updatedItem.Status = this.check2;
     this.angularGrid.gridService.updateItem(updatedItem);
    
     }
    
     /**********************************************/
    

    CSS

    /***************context-menu css*********************/
    
     #contextMenu {
     font-size: 11px;
     list-style: none;
     padding: 0;
     }
    
     .myLi {
     padding-left: 0px;
     display: inline-block;
     }
    
     .myLi img {
     float: left;
      }
     /********************************/