Programmatic filter trigger on antd tables - antd

Is there a way to programmatically trigger filtering on Antd Table Columns?
I'm building a custom Header which is a standalone styled component (So, I set the prop showHeader={ false } on the table and use my custom header to communicate with the table by setting states).
I want to be able to use it to trigger filtering on the table columns.
For sorting, I can pass a value to the sortOrder prop and trigger the sorter function externally. For filtering however, I don't have any obvious way to trigger the filter function.
{
title: 'Title',
dataIndex: 'title',
width: '40%',
key: 'title',
sorter: (a, b) => a.title.localeCompare(b.title),
sortOrder: { this.state.columns['title'].sortOrder }
},
{
title: 'Type',
dataIndex: 'operation',
key: 'defectType',
width: '10%',
filters: Object.keys(topicType).map(key => ({ text: topicType[key], value: key })),
onFilter: (value, record) => String(value) === record.defectType
},

Just managed to get this figured.
If you want to explicitly filter your items on a table and manage the filter state on your own; you need to pass the filteredValue prop on the column configuration.
Setting this to null renders the whole list without filtering.

Related

HOw to hide and Show ag-grid columns based on Header name rather than field name

I am trying to hide/show column based on headername using ag-grid. As you can see below, I have used setColumnsVisible to achieve the same. But I need to this based on headername amd not field.
{ headerName: 'Rating Name', field: 'newRatingName', filter: true}
this.gridColumnApi.setColumnsVisible(['newRatingName', 'newRatingReleaseDate'], false);true }
Is some other way to achieve it?
If you have access to the columnApi, then I'd suggest you get the column using the columnApi and the headerName, and then use that to set the visibility.
For example:
const ratingNameColumn = this.gridColumnApi.getAllColumns().find(x => x.colDef.headerName == 'Rating Name');
this.gridColumnApi.setColumnVisible(ratingNameColumn, false);
Here's a StackBlitz for you.
You can use hide property in the column definition to conditionally hide your column. This is a boolean property that can be set to true/false. For example:
{ headerName: 'Rating Name',
field: 'newRatingName',
filter: true,
hide: this.shouldHide(),
}
shouldHide = () => (true);

Tabulator copyToClipboard method isn't working as anticipated

I am new to the Tabulator plug-in and I am attempting to copy data from one table to another using the Tabulator copyToClipboard method but with no success.
In my application I have created eleven <div> elements (one for the [Crew Leader] and one each for up to ten [Crew Members]) to serve as containers for the Tabulator tables to be instantiated. I am hoping to copy data from the [Crew Leader] table and paste it into each of the affected [Crew Member] tables thus mitigating data re-entry. This sequence of copy/paste events is triggered by the click event bound to a <button> in the header of the [Crew Leader] table. The following function is called by the <button> click event:
function CloneTable() {
// Verify the [Crew Leader] Tabulator table is present....
var tableLeader = Tabulator.prototype.findTable("#CrewLeaderTable");
if (tableLeader.length > 0) {
alert("The Tabulator table #CrewLeaderTable was found.\ntable.length = " + tableLeader.length);
tableLeader.copyToClipboard("all");
alert("The table contents were copied to the clipboard.");
}
else {
alert("The Tabulator table #CrewLeaderTable was not found.");
}
}
The first alert message verifies that the #CrewLeaderTable object has been found as anticipated. However, the second alert verification is never received thus indicating failure of the Tabulator copyToClipboard method.
I have read through as much of the relevant Tabulator documentation as I can find and I am hoping I have simply overlooked something in my setup.
The following is a copy of my Tabulator constructor:
var table = new Tabulator(divid, {
height: "100%",
layout: "fitDataFill",
movableRows: true, //enable user movable rows
tabEndNewRow: true, //create empty new row on tab
rowContextMenu: myActionContextMenu,
keybindings: {
"navUp": true, //enable navUp keybinding using the "up arrow" key
"navDown": true, //enable navDown keybinding using the "down arrow" key
},
columns: [
{ title: "Phase Code", field: "phaseCode", width: 144, editor: "select", editorParams: { values: function (cell) { return window.laborPhaseCodes; } } },
{ title: "Date Worked", field: "dateComp", hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Start Time", field: "timeStart", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Finish Time", field: "timeFinish", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Memo", field: "memo", width: 144, hozAlign: "left", editor: "input" },
{ title: "<button type='button' id='btnClone' class='btn btn-success btn-sm py-0' style='font-size:10px;'>Clone</button>", headerSort: false, headerClick: tabCloneTable }
],
cellEdited: function (cell) {
}
});
I have spent a couple of days trying to figure out the best way to "clone" the data from one table into another. The Tabulator documentation is fairly comprehensive but I fear I have overlooked something. Any assistance is greatly appreciated.
It looks like copyToClipboard doesn't return the data, it is maintained internally and not accessible. But, with what you are doing set/getData works fine.
Here is an example, https://jsfiddle.net/nrayburn/19sjg74k/7/.
Basically, what you want to do is call getData on the parent table and setData on the child table.
const crewLeaderTable = Tabulator.prototype.findTable('#CrewLeaderTable')[0];
const crewMemberTable = Tabulator.prototype.findTable('#CrewMember1Table')[0];
const crewLeaderData = crewLeaderTable.getData();
// You could also use replaceData or addData, depending on the requirements
crewMemberTable.setData(crewLeaderData);

Exporting CSV from ui-grid with cell display rather than the source value

I have a table done with ui-grid and this table has a column with cellFilter definition like this:
{ field: 'company', cellFilter: 'mapCompany:row.grid.appScope.companyCatalog' }
My gridMenu custom item is configured like this:
gridMenuCustomItems: [
{
title:'Custom Export',
action: function ($event) {
var exportData = uiGridExporterService.getData(this.grid, uiGridExporterConstants.ALL, uiGridExporterConstants.ALL, true);
var csvContent = uiGridExporterService.formatAsCsv([], exportData, this.grid.options.exporterCsvColumnSeparator);
uiGridExporterService.downloadFile (this.grid.options.exporterCsvFilename, csvContent, this.grid.options.exporterOlderExcelCompatibility);
},
order:0
}
]
The table is displayed correctly, but when I try to export to CSV, the Company column is exported with empty value. Here is my Plunkr.
Any suggestion will be appretiated
References
I did some research and according to ui-grid Issue #4948 it works good when the Company column is filled with an static catalog. Here is a Plunkr demostrating that.
As you mentioned, there is an export issue when the values in the column are not static, so I forked your plunker with a solution that creates the company mapping for each data object and adds it as a key-value once you get the company catalog back:
$http.get('https://api.github.com/users/hadley/orgs')
.success(function(data) {
$scope.companyCatalog = data;
angular.forEach($scope.gridOptions.data, function(item) {
var compMap = uiGridFactory.getMapCompany(item.company, $scope.companyCatalog);
item.mappedCo = compMap;
});
});
I've kept the original company column but made it invisible (rather than overwriting it), so it exports with the rest of the data in the csv. New column defs:
columnDefs: [
{ field: 'name' },
{ field: 'mappedCo', name: 'Company'},
{ field: 'company', visible: false }
]
Also, in the case that you were getting your data from a server, you would have to ensure that the data and the catalog returned before you run the mapping function. This solution may not work in your particular use case; I don't know.
I found a solution to the CSV export to be able to display the cell display value.
My mistake was using row.grid instead of this.grid at the mapCompany cell filter:
columnDefs: [
{ field: 'name' },
{ field: 'company', cellFilter: 'mapCompany:row.grid.appScope.companyCatalog' }
],
The right way to use it is using this:
columnDefs: [
{ field: 'name' },
{ field: 'company', cellFilter: 'mapCompany:this.grid.appScope.companyCatalog' }
],
Here is my Plunkr.

jqgrid column linq with ASP.NET MVC

I have a class (Person) with 4 properties : Id, FirstName, LastName, Code.
I show a person list in a jqgrid. I'd like a link column with this format (the code has this format 2011.0001)
/Person/Detail/Code => /Person/Code/2011.0001
But I have this with the code below :
/Customer/Detail?Code=2
I tried this :
colModel: [
{ name: 'Code', index: 'Code', formatter: 'showlink', formatoptions: { baseLinkUrl: '/Customer/Detail', idName: 'Code' }},
{ name: 'LastName', index: 'LastName', align: 'left' },
{ name: 'FirstName', index: 'FirstName', align: 'left' }
],
How can I correct this ?
Thanks,
Update1, Data format
[
{"Id":1,"FirstName":"AAAA","LastName":"AA","Code":"2011.0001"},
{"Id":3,"FirstName":"BBBB","LastName":"BB","Code":"2011.0003"}
]
You can try to use the custom formatter in the form
formatter: function (cellvalue, options, rowObject) {
return '' + cellvalue + '';
}
instead of predefined formatter 'showlink':
formatter: 'showlink', formatoptions: {baseLinkUrl:'/Customer/Detail', idName:'Code'}
You can easy receive /Customer/Detail?Code=2011.0001 if you have unique data in the 'Code' column and if you would add key: true to the column definition. In the case the Id value from the JSON input will be ignored and the value from the 'Code' column will be used as the rowid. If you do need to have the href value in the form /Customer/Detail/Code/2011.0001 or instead of /Customer/Detail?Code=2011.0001 you will need use custom formatter as I described before.

jqGrid boolean or enumeration dropdown filtering for columns

I'm using jqGrid to display tabular data on my first ASP.NET MVC 3 and find it really useful, particularly filtering down data. For string-type I use the column-filtering with "contains" and that works wonderfully for culling out the strings. For the date data I use the date picker. Great.
Now I've got a few columns (e.g., "Contains nuts") which are essentially boolean values. I want to provide a way to filter these. Right now they are displayed as "true" and "false" and use the same string-based filtering that my string-type columns use. That's a bit clunky. I think what I'd like to do instead is have a way to choose one of three values (true/false/both) via a dropdown mechanism.
My current colModel has an entry like so for my 'boolean' field:
{ name: 'ContainsNuts',
index: 'ContainsNuts',
align: 'left',
searchoptions: { sopt: ['eq, 'ne']}
}
which only works when the user types in 'false' or 'true' - again, clunky.
For a few other columns, I wanted to use dropdowns for enumerations, e.g., I have a 'Cones' column, since there are quite a few rows and I page the results - using the auto complete text filtering is a bit hit-or-miss for the user to find all the possible values. Hope that makes sense.
So what I've tried is this - I created a controller action that looks like so:
public JsonResult AvailableCones()
{
var context = new IceCreamEntities();
var query = context.Cones.AsQueryable().Distinct();
List<string> all = query.Select(m => m.Name).ToList();
return Json(all, JsonRequestBehavior.AllowGet);
}
And I did something like this [perhaps convoluted approach] to create a dropdown selection in the filtering dialog for Cones in my document ready:
...
createSearchSelection = function (someValues) {
var outputValues = "";
if (someValues && someValues.length) {
for (var i = 0, j = someValues.length; i < j; ++i) {
var entry = someValues[i];
if (outputValues.length > 0) {
outputValues += ";";
}
outputValues += entry + ":" + entry;
}
}
return outputValues;
}
setTheSearchSelections = function (colName, url){
$('#icecreamgrid').jqGrid('setColProp', colName,
{
stype: 'select',
searchoptions: {
value: createSearchSelection(url),
sopt: ['eq']
}
});
}
gotData = function(data) {
setTheSearchSelections('ConeType', data);
}
var url = "/IceCream/AvailableConeTypes";
$.get(url, null, gotData);
The result is that I get a drop-down for the ConeType column in the search dialog and the correct rows shows up in the column. Great. That's pretty cool that it works.
What I don't know how to do, however, is to get a dropdown to show up in my column header filter just like the one that now shows up in the filter dialog. How can I augment what I have to make this happen? Secondly, how can I make what I've got work for boolean values?
First part of your question is the displaying and filtering of the boolean values. I use checkboxes to display such values. In difference on your case I have typically many such columns. To reduce the size of the JSON data I use "1" and "0" instead of "true" and "false". Next I use the following column settings
formatter: 'checkbox', align: 'center', width: 20,
edittype: 'checkbox', editoptions: { value: "1:0" },
stype: "select", searchoptions: { sopt: ['eq', 'ne'], value: "1:Yes;0:No"
So for the searching the user have to choose "Yes" or "No" in the select box. Because I have many of such columns I defined templateCeckbox object in one JavaScript file which I include on every page of the project:
my.templateCeckbox = {
formatter: 'checkbox', align: 'center', width: 20,
edittype: 'checkbox', editoptions: { value: "1:0" },
stype: "select", searchoptions: { sopt: ['eq', 'ne'], value: "1:Ja;0:Nein" }
};
Then the typical column definition is
{
name: 'IsInBasis', index: 'InBasis', template: my.templateCeckbox,
cellattr: function () { return ' title="TS-Basis"'; }
},
(see the answer for details about the column templates). I find also practical if the tooltip shown if one hover the checkbox will be the text close to the column header. So I use cellattr attribute. In case of having many columns with the checkboxes it improves the usability a little.
To be able to display many columns with chechboxes I use personally vertical column headers. I recommend you to read the old answer which could be additionally interesting because it describes how to implement quick filtering of the data with respect of external checkbox panel.
Now about the building of the selects for the 'Cones' column. If you has AvailableCones action which provide the list of possible options like array (list) of strings you should use dataUrl:'/IceCream/AvailableConeTypes' instead of value: createSearchSelection(url) as the searchoptions. You well add only the buildSelect function which I described in "UPDATED" part of the answer.
{
name: 'ConeType', width: 117, index: 'ConeType', editable: true, align: 'center',
edittype: 'select', stype: 'select',
editoptions: {
dataUrl: urlBase + '/AvailableConeTypes',
buildSelect: my.buildSelect
},
searchoptions: {
dataUrl: urlBase + '/AvailableConeTypes',
buildSelect: my.buildSelect
}
}
where
my.buildSelect = function(data) {
var response = jQuery.parseJSON(data.responseText),
s = '<select>', i, l, ri;
if (response && response.length) {
for (i=0, l=response.length; i<l; i += 1) {
ri = response[i];
s += '<option value="' + ri + '">' + ri + '</option>';
}
}
return s + '</select>';
};
This line of code shows a True,False dropdownlist for a column that has true, false values:
{
name: 'SReqdFlag', index: 'SReqdFlag', editable: true, edittype: 'select', editoptions: { value: '"":Select;true:True;false:False' }
}
Hope that helps!

Resources