Multi-Range Selection

FlexGrid has a ListBox selection mode that allows users to select non-contiguous ranges of rows. But, it does not have a built-in selection mode that allows user to select multiple, non-contiguous ranges of cells.

You can add multi-range selection support by handling a few events. For example, press the Control key while selecting ranges with the mouse on the grid below (the console shows the list of selected ranges as the selection changes):

Id
From
To
Sales
Expenses
Amount
Extra
0
Austria
Belgium
7,092.74
2,052.16
1,863.36
3,505.65
1
Belgium
Chile
7,472.34
4,641.64
7,613.66
582.69
2
Chile
Denmark
2,587.20
183.69
3,201.71
8,757.83
3
Denmark
Finland
4,961.53
2,309.52
5,279.30
4,311.46
4
Finland
Japan
124.04
436.21
830.36
6,584.06
5
Japan
UK
3,711.76
2,384.52
3,947.84
1,143.59
6
UK
Austria
8,146.50
3,832.00
4,946.55
7,164.32
7
Austria
Belgium
7,976.86
3,410.67
6,780.40
3,268.20
8
Belgium
Chile
9,118.18
481.62
1,829.30
1,887.57
9
Chile
Denmark
8,480.60
3,764.00
1,066.47
5,127.46
10
Denmark
Finland
159.02
94.37
3,314.30
4,077.94
11
Finland
Japan
1,746.83
2,104.05
2,211.49
7,083.96
12
Japan
UK
341.06
3,466.10
8,171.42
4,293.88
13
UK
Austria
1,137.70
3,092.04
8,845.50
1,856.08
14
Austria
Belgium
1,602.64
2,556.20
8,932.43
2,779.91
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// This file locates: "Scripts/Lesson/C1FlexGrid/MultiRangeSelection.js".
c1.documentReady(function () {
    // create some random data
    var data = [];
    var countries = 'Austria,Belgium,Chile,Denmark,Finland,Japan,UK'.split(',');
    for (var i = 0; i < 300; i++) {
        data.push({
            id: i,
            from: countries[i % countries.length],
            to: countries[(i + 1) % countries.length],
            sales: Math.random() * 10000,
            expenses: Math.random() * 5000,
            amount: Math.random() * 10000,
            extra: Math.random() * 10000,
        });
    }
 
    var theGrid = wijmo.Control.getControl('#theGrid');
    theGrid.itemsSource = data;
 
    // add an extended selection manager to the grid
    var xsm = new ExtendedSelectionManager(theGrid);
    xsm.selectedRanges.collectionChanged.addHandler(function (s, e) {
        var arr = xsm.selectedRanges;
        console.log('selectedRanges: ' + arr.length);
        for (var i = 0; i < arr.length; i++) {
            console.log('  ' + i + wijmo.format(': ({row},{col})-({row2}-{col2})', arr[i]));
        }
    });
});
 
// ** ExtendedSelectionManager (transpiled from TypeScript)
 
'use strict';
var ExtendedSelectionManager = (function () {
    function ExtendedSelectionManager(flex) {
        var _this = this;
        this._selRanges = new wijmo.collections.ObservableArray();
        this._extending = false;
        // start/end extended selection mode
        flex.addEventListener(flex.hostElement, 'mousedown', function (e) {
            _this._extending = e.button == 0 && (e.ctrlKey || e.metaKey);
            if (!_this._extending && _this._selRanges.length) {
                _this._selRanges.clear();
            }
        }, true);
        // end extended selection mode
        flex.addEventListener(flex.hostElement, 'mouseup', function (e) {
            _this._extending = false;
        });
        // extend selection when selection is changing
        flex.selectionChanging.addHandler(function (s, e) {
            if (_this._extending) {
                var xrng = _this._selRanges, curr = flex.selection, last = xrng.length ? xrng[xrng.length - 1] : null;
                if (last && curr.intersects(last)) {
                    xrng.setAt(xrng.length - 1, curr);
                }
                else {
                    _this._selRanges.push(curr);
                }
            }
        });
        // clear extended selection after a selection change
        flex.selectionChanged.addHandler(function (s, e) {
            var xrng = _this._selRanges;
            if (!_this._extending && xrng.length) {
                xrng.clear();
            }
        });
        // apply selected style to a cell
        flex.formatItem.addHandler(function (s, e) {
            if (e.panel == flex.cells) {
                _this._updateCellStyle(e.row, e.col, e.cell);
            }
        });
        // update selection styles when extended selections change
        this._selRanges.collectionChanged.addHandler(function () {
            setTimeout(function () {
                var rng = flex.viewRange;
                for (var r = rng.row; r <= rng.row2; r++) {
                    for (var c = rng.col; c <= rng.col2; c++) {
                        var cell = flex.cells.getCellElement(r, c);
                        _this._updateCellStyle(r, c, cell);
                    }
                }
            });
        });
    }
    Object.defineProperty(ExtendedSelectionManager.prototype, "selectedRanges", {
        // gets the array of selected ranges
        get: function () {
            return this._selRanges;
        },
        enumerable: true,
        configurable: true
    });
    // update the selected style for a given cell
    ExtendedSelectionManager.prototype._updateCellStyle = function (r, c, cell) {
        var selected = false;
        for (var i = 0; i < this._selRanges.length && !selected; i++) {
            selected = this._selRanges[i].contains(r, c);
        }
        wijmo.toggleClass(cell, 'extended-selection', selected);
    };
    return ExtendedSelectionManager;
}());
1
2
3
4
5
// This file locates: "Content/css/Lesson/C1FlexGrid/MultiRangeSelection.css".
.extended-selection.wj-cell:not(.wj-header):not(.wj-group):not(.wj-alt):not(.wj-state-selected):not(.wj-state-multi-selected) {
    color: white;
    background: #a47aff;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Web.Mvc;
 
namespace LearnMvcClient.Controllers
{
    public partial class C1FlexGridController : Controller
    {
        // GET: MultiRangeSelection
        public ActionResult MultiRangeSelection()
        {
            return View();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
@model IEnumerable<FlexGridData.Sale>
 
<h1>
    @Html.Raw(Resources.C1FlexGrid.MultiRangeSelection_Title)
</h1>
<p>
    @Html.Raw(Resources.C1FlexGrid.MultiRangeSelection_Text1)
</p>
<p>
    @Html.Raw(Resources.C1FlexGrid.MultiRangeSelection_Text2)
</p>
@Html.C1().FlexGrid().Id("theGrid").ShowAlternatingRows(false).Height(300)