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

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.

Related

Angular Material Table - Only include "selected" rows in Submit()

I am using a matTable with a matTableDataSource to generate a data table that allows each row to be selected or deselected by checkbox in the first column of each row.
When a form containing the table is submitted, currently all rows are being submitted regardless if selected or not.
Is it possible to limit the data submitted to only those rows that are selected? Here is an example of the current data on submit:
myTableData: [
{
"selected": true,
"dataCell1": "9279694138",
"dataCell2": "Some value",
"dataCell3": "00010-00/8.1"
},
{
"selected": false,
"dataCell1": "5730371160",
"dataCell2": "Some value",
"dataCell3": "00010-00/8.2",
},
{
"selected": true,
"dataCell1": "1234567890",
"dataCell2": "Some value",
"dataCell3": "00010-00/8.4"
},
etc...
]
In the example above, since the second record was not selected by the end user ("selected": false), I would like it to be removed from the table's submitted data object.
Does the mat-table have a method to accomplish this?
I don't think there is anything built in to the mat-table to achieve this. You would need to filter the data manually before submission. They do document a case for adding selection to a mat-table: https://material.angular.io/components/table/overview#selection
Even with this, you would need to add manual filtering before submitting.
This is easily achieved by something like this:
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-component',
templateUrl: './app.component.html'
})
export class AppComponent {
myTableData: any[] = [...];
constructor(
private http: HttpClient
) { }
submit() {
const data = this.myTableData.filter((item) => item.selected);
if (data && data.length) {
this.http.post("/my/api/endpoint", data).subscribe()
}
}
}

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);

Get reference from ext component

I'm having difficulties retrieving my input values through Extjs6's references. There doesn't seem to be a clear cut answer and google is polluted with answers that seem distinct to many different Extjs versions.
I have a window which contains a textfield and a save button, from the textfield I need to retrieve the user's input and pass it along to my ajax call.
My code:
window.updatePassword = function(button) {
var win = new Ext.Window({
referenceHolder: true,
items: [{
xtype: 'form',
items: [{
xtype: 'textfield',
fieldLabel: "newPassword",
reference: 'newPassword',
inputType: 'password'
}],
}],
buttons: [{
text: 'save',
handler: function (btn) {
Ext.Ajax.request({
url: '../../Password_updatePassword.action',
params : {
newPassword: win.newPassword
},
scope: this,
disableCaching: true
});
},
scope: this
}]
});
win.show(this);
};
The things I've tried so far:
this.lookupReference('newPassword')
win.values
win.getValues()
win.newPassword
Ext.getCmp('newPassword')
Any advice would be appreciated.
this.lookupReference('newPassword') - This refers to current object
and handler dont have any component to lookup.
win.values - doesnt make any sense unless you have created a config
in win.
win.getValues() - again doesnt make any sense unless you have create a method in win.
win.newPassword - again same.
Ext.getCmp('newPassword') - getCmp works with id, not with reference.
To get the reference of password field you can lookup on win object,
win.lookupReference('newPassword');
To get the value you have to use getValue() method.
win.lookupReference('newPassword').getValue();

Angularjs: UI-Grid dynamic dropdown for each row

I am using 'ui-grid/dropdownEditor' for one of my column and I want to dynamically load the drop down options which is unique for each row. I want to load the drop down options dynamically on demand via async http call.
I tried the following without success,
$scope.gridOptions = {
columnDefs: [
{ field: 'priority',
displayName: 'Priority',
editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownIdLabel: 'id',
editDropdownValueLabel: 'name',
},
]}
onRegisterApi: function(gridApi) {
gridApi.edit.on.beginCellEdit($scope, function(rowEntity, colDef) {
if (colDef.field === "priority") {
localServices.getPriorityById(rowEntity.id).then(function(data) {
colDef.editDropdownOptionsArray = data;
});
}
});
Any suggestion or help to achieve this is appreciated.
You should look into the usage of editDropdownRowEntityOptionsArrayPath instead of editDropdownOptionsArray
editDropdownRowEntityOptionsArrayPath can be used as an alternative to
editDropdownOptionsArray when the contents of the dropdown depend on
the entity backing the row.
Here is a link to tutorial

KendoUI datasource: parseInt of filter value

I need to filter a Kendo datasource through the following filter item object:
filters: [
{
field: "FIELD",
operator: "lt",
value: "080"
}
]
That means, because of the way data are transmitted, I am trying to test a case like: "013" < "080".
But it does not work out of the box.
Is there a way to define a filter with something like a "parseInt" on the tested values?
Thank you!
Try defining FIELD as a number in model:
schema : {
model: {
fields: {
FIELD : { type: "number" }
}
}
},
If you do so, then FIELD is displayed as 13, 80,... If you want to display FIELD with leading 0, use the following in the column definition of the grid.
{ field: "FIELD", title: "Field", format: "{0:000}" }
Doing this FIELD is considered as a number even that it is displayed as 013, 080...
You should have something like:
var dataSource = new kendo.data.DataSource({
data : entries,
batch : true,
schema : {
model: {
fields: {
FIELD: { type: "number" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
columns : [
{ field: "FIELD", title: "Field", format: "{0:000}" }
],
filterable: true
}).data("kendoGrid");
If you want to try it, see it in JSFiddle here
EDIT: Updated code for using format instead of template as Mateo Piazza suggested

Resources