Implementing multiselect in FlexGrid

Posted by: muhammad.rifatullah on 25 June 2018, 6:56 pm EST

    • Post Options:
    • Link

    Posted 25 June 2018, 6:56 pm EST

    Hi,

    I am new at wijmo. I want to implement multiselect in flexgrid using pureJS.

    For example, we have a table with user name, and his favorite fruits (this column multiselect).

    Currently I am using CustomGridEditor, but the data is not initialized and the checkedItems is applied to all row.

    Thank you very much

  • Posted 27 June 2018, 12:10 am EST

    Hi,

    To make the CustomGridEditor support Multiselect properly first you need to make few changes in CustomGridEditor.js.

    Please refer to following code snippet:

    Add following lines of code in _beginningEdit method

    
    var data=grid.getCellData(this._rng.row, this._rng.col, false);
    if((data instanceof Array)&&(this._ctl instanceof wijmo.input.MultiSelect)){
    	this._ctl.checkedItems=data;
    }
    
    

    After this line

    this._ctl['text'] = grid.getCellData(this._rng.row, this._rng.col, true);
    

    Then in _closeEditor method change these lines

    if (!wijmo.isUndefined(ctl['value'])) {
    	this._grid.setCellData(this._rng.row, this._rng.col, ctl['value']);
    }
    else if (!wijmo.isUndefined(ctl['text'])) {
    	this._grid.setCellData(this._rng.row, this._rng.col, ctl['text']);
    }
    

    With following lines

    if(this._ctl instanceof wijmo.input.MultiSelect){
    	this._grid.setCellData(this._rng.row, this._rng.col, ctl.checkedItems);
    }
    else if (!wijmo.isUndefined(ctl['value'])) {
    	this._grid.setCellData(this._rng.row, this._rng.col, ctl['value']);
    }
    else if (!wijmo.isUndefined(ctl['text'])) {
    	this._grid.setCellData(this._rng.row, this._rng.col, ctl['text']);
    }
    

    After making the required changes it should work fine.

    Please refer to following sample for the same:-

    https://stackblitz.com/edit/js-3iesr9-ttgc3w?file=index.js

    ~Manish

  • Posted 27 June 2018, 5:59 pm EST

    Thank you very much.

    What if the products are array of object?

    I try, but in cell data, it outputs the object, not the value of selectedValuePath.

  • Posted 27 June 2018, 6:07 pm EST

    Btw, still, in your example, https://stackblitz.com/edit/js-3iesr9-ttgc3w?file=index.js, if you change the value, it will be implemented to another value. to reproduce please follow the following scenario;

    1. change selected products of row 1,.
    2. change selected products of another row, ex 3. see row 1.
    3. change selected products of another row again, ex 5. see row 1 and 3.
  • Posted 29 June 2018, 2:20 am EST

    Hi,

    We are indeed sorry for the issue in the last sample. We can fix that by assigning new array for each individual data cell.

    In _closeEditor method replace this code

    this._grid.setCellData(this._rng.row, this._rng.col, ctl.checkedItems);
    

    //with following

    this._grid.setCellData(this._rng.row, this._rng.col, ctl.checkedItems.map(item=>item));
    

    For adding support for an array of object we need few more minor adjustments.

    First, define a function which will determine if the given objects are equal based on some condition

    function areObjectEqual(obj1,obj2){  
    	/* if ref are equal objects are definitely equal   
    	can also compare value types */ 
    	if(obj1===obj2){ 
    		return true; 
    	} 
    	for(let key in obj1){ 
    		if(obj1[key]!=obj2[key]){ 
    			return false; 
    		}	 
    	} 
    	return true; 
    }
    

    //then in _beginningEdit method instead of assigning the data from grid directly to multiselect first create a new array of objects that contains the values from grid then assign it to multiselect.checkedItems

    //if multiselect

    var data=grid.getCellData(this._rng.row, this._rng.col, false);
    if((data instanceof Array)&&(this._ctl instanceof wijmo.input.MultiSelect)){ 
    	var checked=[]; 
    	data.forEach(dataItem=>{ 
    		for(let item of this._ctl.itemsSource){ 
    			if(areObjectEqual(dataItem,item)){ 
    				checked.push(item); 
    				break; 
    			} 
    		} 
    	});
    	this._ctl.checkedItems=checked;
    }
    

    Finally to display the array of objects into grid’s cell you need to handle the formatItem event and convert the array to the required display string value:-

    
    grid.formatItem.addHandler((s,e)=>{ 
    	if(e.panel!=s.cells||e.editRange){ 
    		return;
    	} 
    	if(s.columns[e.col].binding!="products"){ 
    		return; 
    	}
    	var dataItem=s.rows[e.row].dataItem.products; 
    	var displayString=dataItem.reduce((acc,curr)=>{
    		if(acc){
    			return acc+","+curr.value; 
    		}else{
    			return curr.value; 
    		} 
    	},""); 
    	e.cell.innerHTML=displayString; 
    });
    

    Please refer to the following updated sample and let us know if you still face any issues:-

    https://stackblitz.com/edit/js-3iesr9-kfqjmy?file=index.js

    ~Manish

  • Posted 1 July 2018, 3:57 pm EST

    Thank you very much!

  • Posted 30 October 2022, 6:22 pm EST - Updated 30 October 2022, 8:23 pm EST

    Hi~ there

    I`m using FlexGrid in Multi Select Combo overriding flexgrid getCellData function.

    I hope fully support multi Select in wijmo (FlexGridSearch, FlexGridFilter …)

    Like this.

    
    // For using Multi Select - Override getCellData function
    // Pure javascript
    // Wijmo-5.20221.857
    
    //1. Set Custom column editor.
    theGrid.getColumn("ROLE_ID").editor = new wijmo.input.MultiSelect(document.createElement('div'));
    theGrid.getColumn("ROLE_ID").editor.displayMemberPath = 'ROLE_NM';  //jsondata Code Name key
    theGrid.getColumn("ROLE_ID").editor.itemsSource = jsonData; //list of json
    
    //2. Copy Origin getCellData
    theGrid.cells.getCellDataOrigin = theGrid.cells.getCellData;
    
    //3. Override getCellData
    theGrid.cells.getCellData = function(e, t, i) {
    
        let grid = this._g;   
    
        if (grid.getColumn(t).editor instanceof wijmo.input.MultiSelect && i) {
            
            let displayString = '';
            
            if (grid.cells.getCellDataOrigin(e, t)) {
    
                grid.cells.getCellDataOrigin(e, t).forEach(function(item, idx) {    
    
                    let val = (item[grid.getColumn(t).editor.displayMemberPath])||'Null';
    
                    displayString += (idx > 0)? ', '+val : val;
                })
    
            }
    
            return displayString;
    
        } else {
    
            return grid.cells.getCellDataOrigin(e, t, i)
    
        }                 
    
    }
  • Posted 31 October 2022, 8:24 pm EST

    Hi,

    In the latest builds, you do not need to override the getCellData() method, Multiselect is supported as an editor natively. Please refer to the following sample:

    https://stackblitz.com/edit/js-6qvjzh?file=data.js,index.js,index.html

    Regarding, Multiselect support for FlexgridSearch and FlexgridFilter, we are sorry but it is not supported because Filter and search works at the data level(CollectionView) whereas editor is supported only at the presentation layer(Flexgrid).

    Regards

Need extra support?

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

Learn More

Forum Channels