I'm attempting to select a row within a Tabulator table once the data or table has been rendered/loaded. I'm not particularly fussed which callback is used, but when a user navigates to this page the table should load a predetermined record (which I will parse as a parameter).
The callback itself works well, as I can display a JS alert, however I'm still unable to select a line within Tabulator.
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator(
"#example-table", {
height: (window.innerHeight), // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically
headerFilterPlaceholder: '', //default place holder text for filters
selectable: 1, //allows row within table to be selected and have selected state (not to be confused with row click function), can be set to have multiple selected (integer), true or false
data: [ **DATA1** ], //assign data to table
dataTree: true,
dataTreeStartExpanded: true,
dataTreeBranchElement: false, //adds or removes right angle leading from parent to child
dataTreeChildIndent: 25, //changes the indent padding
dataTreeCollapseElement: !1,
dataTreeStartExpanded: !0, //changes whether or not the entire table begins expanded
dataTreeCollapseElement: "<span>▼ </span>",
dataTreeExpandElement: "<span>► </span>",
layout: "fitColumns", //fit columns to width of table (optional)
columns: [ **COLUMN1** ],
rowClick:function(e, row) //triggered when the row is clicked
{
var scriptParam = **SCRIPTPARAM1**;
var rowId = row.getData().id;
var fieldName = **FIELDNAME1**;
var theList = [scriptParam, rowId, fieldName];
var doThis = "fmp://$/**FILE**?script=**SCRIPT1**¶m=" + theList;
window.location.href = doThis;
},
rowDblClick:function(e, row) //triggered when the row is double clicked
{
table.selectRow(**ROWID**);
},
rowContext:function(e, row) //triggered when the row is right clicked
{
alert('right click');
e.preventDefault(); //overrides the browsers native right click function
},
cellEdited: function(cell)
{
var parameter = 1.1;
var distribute = cell.getColumn().getDefinition().distribute;
var id = cell.getData().id;
var table = cell.getColumn().getDefinition().fmTable;
var field = cell.getColumn().getDefinition().fmTable + "::" + cell.getColumn().getDefinition().fmField;
var table = cell.getColumn().getDefinition().fmTable;
var scriptBefore = cell.getColumn().getDefinition().script_before;
var scriptAfter = cell.getColumn().getDefinition().script_after;
var value = cell.getValue();
var theList = [parameter, distribute, id, table, field, value];
var doThis = "fmp://$/**FileName**?script=**ScriptName**¶m=" + theList;
window.location.href = doThis;
},
rowFormatter: function(row) {
var rowColor = row.getData().color
row.getElement().style.backgroundColor = rowColor;
},
renderComplete:function()
{
table.selectRow(**ROWID**);
}
}
);
I'm expecting that once the page is loaded, the row I defined as **ROWID** (which for my testing is ID 1) is selected. FYI, the double click function (regardless of which row is clicked) performs as expected, selecting the correct row.
To further this, I'm looking to (at times) select a child row of the data tree, for example:
const tabledata1 = [{
id: "1",
name: "Oli Bob",
location: "United Kingdom",
gender: "male",
col: "red",
dob: "14/04/1984",
_children: [{
id: "2",
name: "Mary May",
location: "Germany",
gender: "female",
col: "blue",
dob: "14/05/1982"
},
{
name: "Christine Lobowski",
location: "France",
gender: "female",
col: "green",
dob: "22/05/1982"
},
{
name: "Brendon Philips",
location: "USA",
gender: "male",
col: "orange",
dob: "01/08/1980",
_children: [{
name: "Margret Marmajuke",
location: "Canada",
gender: "female",
col: "yellow",
dob: "31/01/1999"
},
{
name: "Frank Harbours",
location: "Russia",
gender: "male",
col: "red",
dob: "12/05/1966"
},
]
},
]
},
{
name: "Jamie Newhart",
location: "India",
gender: "male",
col: "green",
dob: "14/05/1985"
},
{
name: "Gemma Jane",
location: "China",
gender: "female",
col: "red",
dob: "22/05/1982",
_children: [{
name: "Emily Sykes",
location: "South Korea",
gender: "female",
col: "maroon",
dob: "11/11/1970"
}, ]
},
{
name: "James Newman",
location: "Japan",
gender: "male",
col: "red",
dob: "22/03/1998"
},
];
const table = new Tabulator("#example-table", {
height: 205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
data: tabledata1, //assign data to table
selectable: true, //make rows selectable
layout: "fitColumns", //fit columns to width of table (optional)
autoColumns: true,
dataTree: true,
dataTreeStartExpanded: true,
renderComplete: function() {
console.log('done');
this.selectRow(2);
}
});
table.selectRow(ROWID); wont work until table is initialized you
have to do this.selectRow
Check this jsfiddle
renderComplete: function() {
const rows = this.getRows();
console.log('rows', rows);
for (let i = 0; i < rows.length; i++) {
const childRows = rows[i].getTreeChildren();
if (childRows.length > 0) {
// console.log('childRows', childRows);
// this.selectRow(childRows);
for (let j = 0; j < childRows.length; j++) {
const gender = childRows[j].getData().gender;
console.log('gender', gender);
if (gender === 'male') {
this.selectRow(childRows[j]);
const childRows2 = childRows[j].getTreeChildren();
}
}
}
}
}
});
Related
I have figured out how to programmatically copy and insert a new row in my Tabulator table utilizing a right-click and the rowContextMenu property; however I am having difficulty programmatically modifying data within the cells of the newly inserted row.
An abbreviated version of my Tabulator table setup code is as follows:
function TabulatorTimeSheet(divId) {
try {
var myActionContextMenu = [
{
label: "Copy & Paste Row",
action: function (e, row) {
var myTable = row.getTable();
var rowData = row.getData();
var idx = 0;
myTable.addData(rowData, false)
.then(function (newRows) {
//NOTE: The [Added] column of the new row needs to be set to "true".
newRows.forEach(newRow => {
idx = newRow.getPosition(true);
myTable.updateRow(idx, { Added: "true" });
});
myTable.redraw(true);
})
}
}
]
var table = new Tabulator(divId, {
height: "100%",
data: [],
layout: "fitDataFill",
selectable: 1,
cellEdited: function (cell) {
var myTable = cell.getTable();
var row = cell.getRow();
var rowData = row.getData();
rowData["Changed"] = "true";
},
rowContextMenu: myActionContextMenu,
columns: [
{ title: "Date Worked", field: "DateComp", responsive: 0, hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Start Time", field: "TimeStart", responsive: 0, hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Finish Time", field: "TimeFinish", responsive: 0, hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Added", field: "Added", visible: true, responsive: 0, hozAlign: "center" },
{ title: "Changed", field: "Changed", visible: false, responsive: 0, hozAlign: "center" } ]
});
table.setData(myEndPointURL, { caseSelector: myCaseSelector, emplId: myEmployeeId });
}
catch (error) {
console.log(error);
}
The addData() function inserts a copy of the selected row, as expected; however, I am unable to modify the Added cell of the newly inserted row. Regardless of my efforts, I still see a blank cell.
Any assistance is greatly appreciated.
Most of your setup looks fine. Instead of doing myTable.updateRow, use newRows.update({field: 'new val'}). Because you already have the row reference, you don't need to get the id. I think that will solve your issue.
A few other things.
You are only inserting one row, so instead of myTable.addData, use myTable.addRow. Then, the return value will only be 1 row, so you don't need the forEach.
The table.redraw probably isn't necessary.
Here is a very simple example that should do all that you need it to. I omitted the context menu as it isn't relevant to the issue, but you just need to move the function into there and it should be good.
https://jsfiddle.net/nrayburn/65cngder/6/
title pretty much says it, I have users that have different roles they can choose from and I need to toggle the row selection functionality on/off depending on the role they choose, is this possible or do you have to recreate the tabulator to change this value?
This option is not toggleable once the table has been instantiated, but you could use a Selection Eligibility function to determine if the row should currently be selectable:
var table = new Tabulator("#example-table", {
selectableCheck:function(row){
//row - row component
return row.getData().age > 18; //allow selection of rows where the age is greater than 18
},
});
You could tweak the above example to look at a global boolean that you toggle to determine if the table is selectable
In this I can select rows with name Oli Bob only See Documentation
Use as per your convinience
selectableCheck:function(row){
//row - row component
return row.getData().age > 18; //allow selection of rows where the age is greater than 18
},
const tabledata = [{
name: "Oli Bob",
location: "United Kingdom",
gender: "male",
col: "red",
dob: "14/04/1984"
},
{
name: "Oli Bob",
location: "United Kingdom",
gender: "male",
col: "red",
dob: "14/04/1984"
},
{
name: "Jamie Newhart",
location: "India",
gender: "male",
col: "green",
dob: "14/05/1985"
}
];
let selectable = false;
const table = new Tabulator("#example-table", {
data: tabledata,
selectable: true,
selectableCheck: function(row) {
const name = row.getData().name;
return name === "Oli Bob";
},
columns: [{
title: "Row Num",
formatter: "rownum"
},
{
title: "Name",
field: "name",
width: 200
},
],
});
<script src="https://unpkg.com/tabulator-tables#4.4.3/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.4.3/dist/css/tabulator.min.css" rel="stylesheet" />
<div id="example-table"></div>
I have a column which is formatted using the built in money formatter. I would like to change the text of the cell to red if the numeric value of the cell is negative. I can't create a custom formatter because the column formatter option is already set to money.
You have to use a custom formatter, Mimic the money formatter in this code. I can't think of anything else
let tabledata = [{
id: 1,
name: "Oli ",
money: 1,
col: "red",
dob: ""
},
{
id: 2,
name: "Mary ",
money: -1,
col: "blue",
dob: "14/05/1982"
},
{
id: 3,
name: "Christine ",
money: 0,
col: "green",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon ",
money: 10,
col: "orange",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret ",
money: -10,
col: "yellow",
dob: "31/01/1999"
},
];
for (let i = 0; i < tabledata.length; i++) {
if (tabledata[i].money < 0) {
tabledata[i].money = "<span class='red'>$" +
tabledata[i].money +
"</span>"
} else {
tabledata[i].money = '$' + tabledata[i].money;
}
}
const table = new Tabulator("#example-table", {
data: tabledata,
layout: "fitColumns",
columns: [{
title: "id",
field: "id"
},
{
title: "name",
field: "name"
},
{
title: "money",
field: "money",
formatter: "html"
},
{
title: "col",
field: "col"
},
{
title: "dob",
field: "dob"
},
]
});
.red {
color: red;
}
<!DOCTYPE html>
<html lang="en">
<script src="https://unpkg.com/tabulator-tables#4.2.4/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.2.4/dist/css/tabulator.min.css" rel="stylesheet" />
<body>
<div id="example-table"></div>
</body>
</html>
I think I found a solution for this problem:
formatter:function(cell,params,callback) {
let money = cell.getTable().modules.format.getFormatter("money");
cell.getElement().style...
return money(cell,params,callback);
}
https://jsfiddle.net/baumrock/vxpbhLsg/14/
Even in the example given # the Tabulator site:
http://tabulator.info/basic/4.2
the date column does not sort, unlike the others. Is there a fix for that?
Date sorting for Tabulator is dependent on MomentJS.
Import Moment Js to your code
{title: "Date Of Birth", field: "dob", sorter:"date", sorterParams:{format:"DD/MM/YY"}},
Please check this Snippet
const tabledata1 = [
{id: 1, name: "Oli ", money: "0", col: "red", dob: "14/05/1982"},
{id: 2, name: "Mary ", money: "0", col: "blue", dob: "14/05/1982"},
{id: 3, name: "Christine ", money: "0", col: "green", dob: "22/05/1982"},
{id: 4, name: "Brendon ", money: "0", col: "orange", dob: "01/08/1980"},
{id: 5, name: "Margret ", money: "0", col: "yellow", dob: "31/01/1999"},
];
const table = new Tabulator("#example-table", {
height: 205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
data: tabledata1, //assign data to table
layout: "fitColumns", //fit columns to width of table (optional)
columns: [ //Define Table Columns
{title: "Name", field: "name", width: 150},
{
title: "money",
field: "money",
align: "left",
formatter: "money"
},
{title: "Favourite Color", field: "col"},
{title: "Date Of Birth", field: "dob", sorter:"date", sorterParams:{format:"DD/MM/YY"}},
]
});
function removeData() {
table.clearData();
}
function update() {
table.updateOrAddData(tabledata2);
// table.addData(tabledata2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://unpkg.com/tabulator-tables#4.2.4/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.2.4/dist/css/tabulator.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
<div id="example-table"></div>
I have a question regarding Export to Excel in free-jqgrid 4.15.4. I want to know how to use this resultset {"groupOp":"AND","rules":[{"field":"FirstName","op":"eq","data":"Amit"}]} into my Business Logic Method.
Just for more clarification, I've using OfficeOpenXml and if I don't use filtered resultset(aforementioned) it is working fine and I'm able to download file with full records in an excel sheet. But I'm not sure what to do or how to utilize the resultset {"groupOp":"AND","rules":[{"field":"FirstName","op":"eq","data":"Amit"}]}
If required I can share my controller and BL code.
I have added a fiddle which shows implementation of Export to Excel button in jqGrid pager.
Before coming to here, I've read and tried to understand from following questions:
1] jqgrid, export to excel (with current filter post data) in an asp.net-mvc site
2] Export jqgrid filtered data as excel or CSV
Here is the code :
$(function () {
"use strict";
var mydata = [
{ id: "10", FirstName: "test", LastName: "TNT", Gender: "Male" },
{ id: "11", FirstName: "test2", LastName: "ADXC", Gender: "Male" },
{ id: "12", FirstName: "test3", LastName: "SDR", Gender: "Female" },
{ id: "13", FirstName: "test4", LastName: "234", Gender: "Male" },
{ id: "14", FirstName: "test5", LastName: "DAS", Gender: "Male" },
];
$("#list").jqGrid({
data: mydata,
colNames: ['Id', 'First Name', 'Last Name', 'Gender'],
colModel: [
{
label: "Id",
name: 'Id',
hidden: true,
search: false,
},
{
label: "FirstName",
name: 'FirstName',
searchoptions: {
searchOperators: true,
sopt: ['eq', 'ne', 'lt', 'le','ni', 'ew', 'en', 'cn', 'nc'],
}, search: true,
},
{
label: "LastName",
name: 'LastName',
searchoptions: {
searchOperators: true,
sopt: ['eq', 'ne', 'lt', 'ni', 'ew', 'en', 'cn', 'nc'],
}, search: true,
},
{
label: "Gender",
name: 'Gender',
search: true, edittype: 'select', editoptions: { value: 'Male:Male;Female:Female' }, stype: 'select',
},
],
onSelectRow: function (id) {
if (id && id !== lastsel) {
jQuery('#list').restoreRow(lastsel);
jQuery('#list').editRow(id, true);
lastsel = id;
}
},
loadComplete: function (id) {
if ($('#list').getGridParam('records') === 0) {
//$('#grid tbody').html("<div style='padding:6px;background:#D8D8D8;'>No records found</div>");
}
else {
var lastsel = 0;
if (id && id !== lastsel) {
jQuery('#list').restoreRow(lastsel);
jQuery('#list').editRow(id, true);
lastsel = id;
}
}
},
loadonce: true,
viewrecords: true,
gridview: true,
width: 'auto',
height: '150px',
emptyrecords: "No records to display",
iconSet:'fontAwesome',
pager: true,
jsonReader:
{
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "Id"
},
});
jQuery("#list").jqGrid("navButtonAdd", {
caption: "",
buttonicon: "fa-table",
title: "Export To Excel",
onClickButton: function (e) {
var projectId = null;
var isFilterAreUsed = $('#grid').jqGrid('getGridParam', 'search'),
filters = $('#grid').jqGrid('getGridParam', 'postData').filters;
var Urls = "/UsersView/ExportToExcel_xlsxFormat?filters="+ encodeURIComponent(filters); //' + encodeURIComponent(filters);/
if (totalRecordsCount > 0) {
$.ajax({
url: Urls,
type: "POST",
//contentType: "application/json; charset=utf-8",
data: { "searchcriteria": filters, "projectId": projectId, "PageName": "MajorsView" },
//datatype: "json",
success: function (data) {
if (true) {
window.location = '/UsersView/SentFiletoClientMachine?file=' + data.filename;
}
else {
$("#resultDiv").html(data.errorMessage);
$("#resultDiv").addClass("text-danger");
}
},
error: function (ex) {
common.handleAjaxError(ex.status);
}
});
}
else {
bootbox.alert("There are no rows to export in the Participant List")
if (dialog) {
dialog.modal('hide');
}
}
}
});
});
https://jsfiddle.net/ap43xecs/10/
There are exist many option to solve the problem. The simplest one consist of sending ids of filtered rows to the server instead of sending filters parameter. Free jqGrid supports lastSelectedData parameter and thus you can use $('#grid').jqGrid('getGridParam', 'lastSelectedData') to get the array with items sorted and filtered corresponds to the current filter and sorting criteria. Every item of the returned array should contain Id property (or id property) which you can use on the server side to filter the data before exporting.
The second option would be to implement server side filtering based on the filters parameter, which you send currently to the server. The old answer (see FilterObjectSet) provides an example of filtering in case of usage Entity Framework. By the way, the answer and another one contain code, which I used for exporting grid data to Excel using Open XML SDK. You can compare it with your existing code.
In some situations it could be interesting to export grid data to Excel without writing any server code. The corresponding demo could be found in the issue and UPDATED part of the answer.