-
Notifications
You must be signed in to change notification settings - Fork 423
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable hidden property for column. Adds example-column-hidden, method…
… getVisibleColumns() and alternate method updateColumns() calling event onBeforeUpdateColumns() for when a hidden property has changed but the column list itself has not changed.
- Loading branch information
Showing
4 changed files
with
479 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,378 @@ | ||
<!DOCTYPE HTML> | ||
<html> | ||
<head> | ||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
<link rel="shortcut icon" type="image/ico" href="favicon.ico" /> | ||
<title>SlickGrid example: Hidden Columns</title> | ||
<link rel="stylesheet" href="../slick.grid.css" type="text/css"/> | ||
<link rel="stylesheet" href="../controls/slick.pager.css" type="text/css"/> | ||
<link rel="stylesheet" href="../examples/examples.css" type="text/css"/> | ||
<link rel="stylesheet" href="../examples/examples-unicode-icons.css" type="text/css"/> | ||
<link rel="stylesheet" href="../controls/slick.columnpicker.css" type="text/css"/> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/flatpickr.css"> | ||
<style> | ||
.cell-title { | ||
font-weight: bold; | ||
} | ||
|
||
.cell-effort-driven { | ||
text-align: center; | ||
} | ||
|
||
.cell-selection { | ||
border-right-color: silver; | ||
border-right-style: solid; | ||
background: #f5f5f5; | ||
color: gray; | ||
text-align: right; | ||
font-size: 10px; | ||
} | ||
|
||
.slick-row.selected .cell-selection { | ||
background-color: transparent; /* show default selected row background */ | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div style="position:relative"> | ||
<div style="width:600px;"> | ||
<div class="grid-header" style="width:100%"> | ||
<label>SlickGrid</label> | ||
<span style="float:right;margin:0px 4px auto 6px;background:transparent;cursor:pointer;" class="slick-icon-search" title="Toggle search panel" | ||
onclick="toggleFilterRow()"></span> | ||
</div> | ||
<div id="myGrid" style="width:100%;height:500px;"></div> | ||
<div id="pager" style="width:100%;height:20px;"></div> | ||
</div> | ||
|
||
<div class="options-panel"> | ||
<b>Search:</b> | ||
<hr/> | ||
<div style="padding:6px;"> | ||
<label style="width:200px;float:left">Show tasks with % at least: </label> | ||
|
||
<div style="padding:2px;"> | ||
<input style="width:100px;display:inline-block;" id="pcSlider" type="range" min="1" max="100" value="1"> | ||
</div> | ||
<br/> | ||
<label style="width:200px;float:left">And title including:</label> | ||
<input type=text id="txtSearch" style="width:100px;"> | ||
<br/><br/> | ||
<button id="btnSelectRows">Select first 10 rows</button> | ||
<br/><br/> | ||
<input id="chkHideColumn" type="checkbox"/> Hide Duration Column | ||
<br/> | ||
|
||
<h2>Demonstrates:</h2> | ||
<ul> | ||
<li>a filtered Model (DataView) as a data source instead of a simple array</li> | ||
<li>grid reacting to model events (onRowCountChanged, onRowsChanged)</li> | ||
<li> | ||
<b>FAST</b> DataView recalculation and <b>real-time</b> grid updating in response to data changes.<br/> | ||
The grid holds <b>50'000</b> rows, yet you are able to sort, filter, scroll, navigate and edit as if it had 50 | ||
rows. | ||
</li> | ||
<li>adding new rows, bidirectional sorting</li> | ||
<li>column options: cannotTriggerInsert</li> | ||
<li>events: onCellChange, onAddNewRow, onKeyDown, onSelectedRowsChanged, onSort</li> | ||
<li><font color=red>NOTE:</font> all filters are immediately applied to new/edited rows</li> | ||
<li>Handling row selection against model changes.</li> | ||
<li>Paging.</li> | ||
<li>inline filter panel</li> | ||
</ul> | ||
<h2>View Source:</h2> | ||
<ul> | ||
<li><A href="https://github.com/6pac/SlickGrid/blob/master/examples/example-column-visible.html" target="_sourcewindow"> View the source for this example on Github</a></li> | ||
</ul> | ||
|
||
</div> | ||
</div> | ||
</div> | ||
|
||
<div id="inlineFilterPanel" style="display:none;background:#dddddd;color:black;"> | ||
Show tasks with title including <input type="text" id="txtSearch2"> | ||
and % at least | ||
<input style="width:100px;display:inline-block;" id="pcSlider2" type="range" min="1" max="100" value="1"> | ||
</div> | ||
|
||
<script src="../lib/firebugx.js"></script> | ||
|
||
<script src="../lib/jquery-3.1.0.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/sortablejs/Sortable.js"></script> | ||
|
||
<script src="../slick.core.js"></script> | ||
<script src="../slick.interactions.js"></script> | ||
<script src="../slick.formatters.js"></script> | ||
<script src="../slick.editors.js"></script> | ||
<script src="../plugins/slick.rowselectionmodel.js"></script> | ||
<script src="../slick.grid.js"></script> | ||
<script src="../slick.dataview.js"></script> | ||
<script src="../controls/slick.pager.js"></script> | ||
<script src="../controls/slick.columnpicker.js"></script> | ||
|
||
<script> | ||
function isIEPreVer9() { var v = navigator.appVersion.match(/MSIE ([\d.]+)/i); return (v ? v[1] < 9 : false); } | ||
|
||
var dataView; | ||
var grid; | ||
var data = []; | ||
var columns = [ | ||
{id: "sel", name: "#", field: "num", behavior: "select", cssClass: "cell-selection", width: 40, cannotTriggerInsert: true, resizable: false, selectable: false, excludeFromColumnPicker: true }, | ||
{id: "title", name: "Title", field: "title", width: 120, minWidth: 120, cssClass: "cell-title", editor: Slick.Editors.Text, validator: requiredFieldValidator, sortable: true}, | ||
{id: "duration", name: "Duration", field: "duration", editor: Slick.Editors.Text, sortable: true}, | ||
{id: "%", defaultSortAsc: false, name: "% Complete", field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar, editor: Slick.Editors.PercentComplete, sortable: true}, | ||
{id: "start", name: "Start", field: "start", minWidth: 60, editor: Slick.Editors.Flatpickr, sortable: true}, | ||
{id: "finish", name: "Finish", field: "finish", minWidth: 60, editor: Slick.Editors.Flatpickr, sortable: true}, | ||
{id: "effort-driven", name: "Effort Driven", width: 80, minWidth: 20, maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkbox, editor: Slick.Editors.Checkbox, cannotTriggerInsert: true, sortable: true} | ||
]; | ||
|
||
var options = { | ||
columnPicker: { | ||
columnTitle: "Columns", | ||
hideForceFitButton: false, | ||
hideSyncResizeButton: false, | ||
forceFitTitle: "Force fit columns", | ||
syncResizeTitle: "Synchronous resize", | ||
}, | ||
editable: true, | ||
enableAddRow: true, | ||
enableCellNavigation: true, | ||
asyncEditorLoading: true, | ||
forceFitColumns: false, | ||
topPanelHeight: 25 | ||
}; | ||
|
||
var sortcol = "title"; | ||
var sortdir = 1; | ||
var percentCompleteThreshold = 0; | ||
var searchString = ""; | ||
|
||
function requiredFieldValidator(value) { | ||
if (value == null || value == undefined || !value.length) { | ||
return {valid: false, msg: "This is a required field"}; | ||
} | ||
else { | ||
return {valid: true, msg: null}; | ||
} | ||
} | ||
|
||
function myFilter(item, args) { | ||
if (item["percentComplete"] < args.percentCompleteThreshold) { | ||
return false; | ||
} | ||
|
||
if (args.searchString != "" && item["title"].indexOf(args.searchString) == -1) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
function percentCompleteSort(a, b) { | ||
return a["percentComplete"] - b["percentComplete"]; | ||
} | ||
|
||
function comparer(a, b) { | ||
var x = a[sortcol], y = b[sortcol]; | ||
return (x == y ? 0 : (x > y ? 1 : -1)); | ||
} | ||
|
||
function toggleFilterRow() { | ||
grid.setTopPanelVisibility(!grid.getOptions().showTopPanel); | ||
} | ||
|
||
|
||
$(".grid-header .ui-icon") | ||
.addClass("ui-state-default ui-corner-all") | ||
.mouseover(function (e) { | ||
$(e.target).addClass("ui-state-hover") | ||
}) | ||
.mouseout(function (e) { | ||
$(e.target).removeClass("ui-state-hover") | ||
}); | ||
|
||
$(function () { | ||
// prepare the data | ||
for (var i = 0; i < 50000; i++) { | ||
var d = (data[i] = {}); | ||
|
||
d["id"] = "id_" + i; | ||
d["num"] = i; | ||
d["title"] = "Task " + i; | ||
d["duration"] = "5 days"; | ||
d["percentComplete"] = Math.round(Math.random() * 100); | ||
d["start"] = "01/01/2009"; | ||
d["finish"] = "01/05/2009"; | ||
d["effortDriven"] = (i % 5 == 0); | ||
} | ||
|
||
|
||
dataView = new Slick.Data.DataView({ inlineFilters: true }); | ||
grid = new Slick.Grid("#myGrid", dataView, columns, options); | ||
grid.setSelectionModel(new Slick.RowSelectionModel()); | ||
|
||
var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); | ||
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options); | ||
|
||
|
||
// move the filter panel defined in a hidden div into grid top panel | ||
$("#inlineFilterPanel") | ||
.appendTo(grid.getTopPanel()) | ||
.show(); | ||
|
||
grid.onCellChange.subscribe(function (e, args) { | ||
dataView.updateItem(args.item.id, args.item); | ||
}); | ||
|
||
grid.onAddNewRow.subscribe(function (e, args) { | ||
var item = {"num": data.length, "id": "new_" + (Math.round(Math.random() * 10000)), "title": "New task", "duration": "1 day", "percentComplete": 0, "start": "01/01/2009", "finish": "01/01/2009", "effortDriven": false}; | ||
$.extend(item, args.item); | ||
dataView.addItem(item); | ||
}); | ||
|
||
grid.onKeyDown.subscribe(function (e) { | ||
// select all rows on ctrl-a | ||
if (e.which != 65 || !e.ctrlKey) { | ||
return false; | ||
} | ||
|
||
var rows = []; | ||
for (var i = 0; i < dataView.getLength(); i++) { | ||
rows.push(i); | ||
} | ||
|
||
grid.setSelectedRows(rows); | ||
e.preventDefault(); | ||
}); | ||
|
||
grid.onSort.subscribe(function (e, args) { | ||
sortdir = args.sortAsc ? 1 : -1; | ||
sortcol = args.sortCol.field; | ||
|
||
if (isIEPreVer9()) { | ||
// using temporary Object.prototype.toString override | ||
// more limited and does lexicographic sort only by default, but can be much faster | ||
|
||
var percentCompleteValueFn = function () { | ||
var val = this["percentComplete"]; | ||
if (val < 10) { | ||
return "00" + val; | ||
} else if (val < 100) { | ||
return "0" + val; | ||
} else { | ||
return val; | ||
} | ||
}; | ||
|
||
// use numeric sort of % and lexicographic for everything else | ||
dataView.fastSort((sortcol == "percentComplete") ? percentCompleteValueFn : sortcol, args.sortAsc); | ||
} else { | ||
// using native sort with comparer | ||
// preferred method but can be very slow in IE with huge datasets | ||
dataView.sort(comparer, args.sortAsc); | ||
} | ||
}); | ||
|
||
// wire up model events to drive the grid | ||
// !! both dataView.onRowCountChanged and dataView.onRowsChanged MUST be wired to correctly update the grid | ||
// see Issue#91 | ||
dataView.onRowCountChanged.subscribe(function (e, args) { | ||
grid.updateRowCount(); | ||
grid.render(); | ||
}); | ||
|
||
dataView.onRowsChanged.subscribe(function (e, args) { | ||
grid.invalidateRows(args.rows); | ||
grid.render(); | ||
}); | ||
|
||
dataView.onPagingInfoChanged.subscribe(function (e, pagingInfo) { | ||
grid.updatePagingStatusFromView( pagingInfo ); | ||
|
||
// show the pagingInfo but remove the dataView from the object, just for the Cypress E2E test | ||
delete pagingInfo.dataView; | ||
console.log('on After Paging Info Changed - New Paging:: ', pagingInfo); | ||
}); | ||
|
||
dataView.onBeforePagingInfoChanged.subscribe(function (e, previousPagingInfo) { | ||
// show the previous pagingInfo but remove the dataView from the object, just for the Cypress E2E test | ||
delete previousPagingInfo.dataView; | ||
console.log('on Before Paging Info Changed - Previous Paging:: ', previousPagingInfo); | ||
}); | ||
|
||
var h_runfilters = null; | ||
|
||
// wire up the slider to apply the filter to the model | ||
var slider = document.getElementById("pcSlider"); | ||
var slider2 = document.getElementById("pcSlider2"); | ||
var sliderCallback = function() { | ||
Slick.GlobalEditorLock.cancelCurrentEdit(); | ||
|
||
if (percentCompleteThreshold != this.value) { | ||
window.clearTimeout(h_runfilters); | ||
h_runfilters = window.setTimeout(updateFilter, 10); | ||
percentCompleteThreshold = this.value; | ||
} | ||
} | ||
|
||
slider.oninput = sliderCallback; | ||
slider2.oninput = sliderCallback; | ||
|
||
// wire up the search textbox to apply the filter to the model | ||
$("#txtSearch,#txtSearch2").keyup(function (e) { | ||
Slick.GlobalEditorLock.cancelCurrentEdit(); | ||
|
||
// clear on Esc | ||
if (e.which == 27) { | ||
this.value = ""; | ||
} | ||
|
||
searchString = this.value; | ||
updateFilter(); | ||
}); | ||
|
||
function updateFilter() { | ||
dataView.setFilterArgs({ | ||
percentCompleteThreshold: percentCompleteThreshold, | ||
searchString: searchString | ||
}); | ||
dataView.refresh(); | ||
} | ||
|
||
$("#btnSelectRows").click(function () { | ||
if (!Slick.GlobalEditorLock.commitCurrentEdit()) { | ||
return; | ||
} | ||
|
||
var rows = []; | ||
for (var i = 0; i < 10 && i < dataView.getLength(); i++) { | ||
rows.push(i); | ||
} | ||
|
||
grid.setSelectedRows(rows); | ||
}); | ||
|
||
$("#chkHideColumn").change(function () { | ||
var hideCol = $("#chkHideColumn").prop('checked') || false; | ||
columns[2].hidden = hideCol; | ||
grid.setColumns(columns); | ||
}); | ||
|
||
// initialize the model after all the events have been hooked up | ||
dataView.beginUpdate(); | ||
dataView.setItems(data); | ||
dataView.setFilterArgs({ | ||
percentCompleteThreshold: percentCompleteThreshold, | ||
searchString: searchString | ||
}); | ||
dataView.setFilter(myFilter); | ||
dataView.endUpdate(); | ||
|
||
// if you don't want the items that are not visible (due to being filtered out | ||
// or being on a different page) to stay selected, pass 'false' to the second arg | ||
dataView.syncGridSelection(grid, true); | ||
}) | ||
</script> | ||
</body> | ||
</html> |
Oops, something went wrong.