React: Render column component as a row component in a Table - javascript

I'm creating a Table component in React. I'm looking in some Table components and they create an array of columns to pass to the Table. In this columns array you can put a function to render a component inside each row in tbody.
First Example of Ant Design (https://ant.design/components/table/):
const columns = [{
title: 'Name',
dataIndex: 'name',
key: 'name'
}, {
title: 'Action',
key: 'action',
render: (text, record) => ( <<-- THIS FUNCTION. IT RECEIVES THE ROW RECORD AS A PARAM TOO
<span>
This gonna be rendered in each row of the table
</span>
),
}];
I'm trying to figure it out a good way to create this mechanism to render a column in each row of the table body.
Is there a good example to study? I'm trying to read the source code in some components in NPM.. but it's hard to understand.
Thanks devs!

This is a basic example, Usually your Table component would receive 2 props:
Data sorce, can be array of objects
The column configuration, which contains the attribute name, the trick of the function is just the functional programming of javascript, you can receive render function so user can implement their own render logic.
eg.
const dataSource = [
{
id: 1,
name: 'aaaa',
age: 10
},
{
id: 2,
name: 'bbbb',
age: 11
},
{
id: 3,
name: 'ccc',
age: 12
},
];
so a column config would be like:
const column = [
{
key: 'id',
label: 'ID'
},
{
key: 'name',
label: 'Student Name'
},
{
key: 'age',
label: 'Student Age',
render: (text, record) => {
return `** ${text} **`; // just for decoration
}
}
]
The table component would iterate around the datasource and with the help of column configuration to build the Table tags.
however you can always add something like this inside of your loop logic:
if (typeof render === 'function') {
cell = <td key={key}>{render(item[key], item)}</td> // call the render function and pass the data
} else {
cell = <td key={key}>{item[key]}</td> // else will just render it
}

Related

How to set custom CoreUI column names in Vue?

I have an array of item objects for the table. e.g.:
[{ name: 'Sam', age: 24 }]
I want to set custom field names like instead of column to be named as age, I want it to display column name as Id instead of age. So, basically how can I set custom column names?
Here is their documentation if that helps: https://coreui.io/vue/docs/components/table.html
Check fields props.
Using the fields attribute of the <CDataTable>, you can specify an array of fields to use for column names. That can be an array of strings or objects. When using the object syntax, you can specify various properties, such as the label of the column. See in the <CDataTable> docs:
key (required)(String) - define column name equal to item key.
label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting
This lets you name the column differently from the key. Here is an example where the table has column keys "id" and "name", but the label is "ID" and "Surname":
<div id="app">
<cdatatable
:items="items"
:fields="fields"
>
</cdatatable>
</div>
new Vue({
el: "#app",
data() {
return {
items: [
{ id: 1, name: 'Mary' },
{ id: 2, name: 'Bob' }
],
fields: [ // Array of column object data
{ key: 'id', label: 'ID' },
{ key: 'name', label: 'Surname' }
]
}
}
});

How to create tree view inside the dropdown using angular material?

Can anyone tell me, how to create a tree view inside the drop down. The drop down values will be getting from rest api call as json as follows. And subchild may contains one more level of child as well.
I have to do auto suggestion here to perform the filter from parent as well as the child level too.
VehicleList = [
{
parent: "audi",
child: [{
type: 'G-audiA',
subchild: [{
id: 1,
name: 'type audi A1'
}, {
id: 2,
name: 'type audi A2'
}]
}, {
type: 'G-audiB',
subchild: [{
id: 1,
name: 'type audi B1'
}, {
id: 2,
name: 'type audi B2'
}]
}]
}, {
parent: "bmw",
child: [{
type: 'G-bmwA',
subchild: [{
id: 1,
name: 'type bmw A1'
}, {
id: 2,
name: 'type bmw A2'
}]
}, {
type: 'G-bmwB',
subchild: [{
id: 1,
name: 'type bmw B1'
}, {
id: 2,
name: 'type bmw B2'
}]
}]
}]
Anyone help will be appreciated!!!
Based on the first example from the Angular Material Tree docs I managed to build up a drop-down with a tree structure inside like so:
The trick for displaying the tree is to add a disabled/empty option. I used it as a label. The tree is taken from their examples so I did not modify it at all, you can modify the node structure to match your own.
In order to display the selected items in the label of the drop-down, you can create a method that will return the selected items a string as their SelectionModel object has the selected property which would return all selected nodes.
/** The selection for checklist */
checklistSelection = new SelectionModel<TodoItemFlatNode>(
true /* multiple */
);
And in order to get the selected items from the tree:
return this.checklistSelection.selected.map(s => s.item).join(",");
For the filtering part I think you can look over this answer.
Hope this is helpful!
Stackblitz
Edit: If you select a child the parent gets selected too and added in the SelectionModel even if all its children are not selected. If you don't want this behaviour comment on the function descendantsPartiallySelected. This will not check the checkbox and so parents will not be added in SelectionModel unless all children are selected

Object.keys() return not working in Ant Design table column rendering

I'm trying to render an Ant Design table featuring a people column which should look like this:
Adults: 2 Children: 3
Here's a sample dataSource object:
{
id: 'KRO066',
key: 'KRO066',
date: '01/01/2020',
people: { adults: 2, children: 3 },
status: 'Confirmed',
total: '563.25',
}
Here's the people column render function in my column object:
{
title: 'People',
dataIndex: 'people',
key: 'people',
render: people => Object.keys(people).forEach(function (type, i) {
return <span key={i}><strong>{type}:</strong>{people[type]}</span>;
})
}
The column does not return anything, instead, I get an empty cell.
What's wrong with the render function?
Use Object.keys(people).map instead of Object.keys(people).forEach
Credit #Hamms in the question comments

Filtering column's collection

In my Webix datatable one column fetches the data from the DataColletion. The problem is in the column's filtering: seems like it works with the original data (that contains the ID) and ignores the value of the data collection. How can I change this behavior and filter datatable by the collection's value?
Data:
var mycollection = new webix.DataCollection({
data:[{
id: '12',
value: 'CollItem 1'
}]
});
var mydata = [{
id: 1,
name: 'Item 1',
troublesomeColumn: '12' // id of the CollItem 1
}];
Config:
columns:[{
id: 'troublesomeColumn',
collection: mycollection,
header:{
content:"textFilter"
}
}],
data:mydata
Code snippet. Thanks in advance.
Filters work with the dataset, not with the templates or values from the linked collections. Therefore, you need to create a custom filtering rule as described in the Webix Docs, i.e. define the needed pattern in the compareproperty of the filter:
{
content:"textFilter",
compare:function(value, filter, obj){
var colValue = mycollection.getItem(value).value;
toFilter = colValue.toString().toLowerCase();
filter = filter.toString().toLowerCase();
return toFilter.indexOf(filter) !== -1;
}
}
Updated snippet

is there a way in Slick.Grid to render all data to an array so it can be exported?

Is there a way in Slick.Grid to render all data to an array so it can be exported?
I am able to get the data from my Slick.Grid instance "mygrid.getData().getItems()" but it is just the raw data not the formated data.
Is there a function I can use to iterate though the collection and return the formated data?
As of now I am having to implement my formatters twice.
Example:
UnixToDate: (row, cell, value, columnDef, dataContext) ->
moment.unix(value).format("MMM Do YY")
items: [
{id: 1, activity_at: 915148798 },
{id: 2, activity_at: 999148800 }
]
columns: [
{field: 'id', id: 'id', name: 'Id'},
{field: 'activity_at', id: 'activity_at', name: 'Activity', formatter: UnixToDate}
]
#data = new Slick.Data.DataView()
#grid = new Slick.Grid( $('#table'), #data, columns )
#data.setItems(items)
I am wondering if there is a way to return the data with the formatted values.
I thought #grid.getData().getItems() would do it but it returns the raw data array.
The data returned should look like:
data: [
{id: 1, activity_at: "Dec 31st 98" },
{id: 2, activity_at: "Aug 29th 01" }
]
I would like the end user to be able to filter and arrange the grid and then export the results in csv format, I have all this working except the formatting part.
Ok I wrote a method to do the export (written in coffeescript and using underscore.js). I also had to expose the getFormatter method in slick.grid.js
getFormattedData: (grid) ->
columns = grid.getColumns()
rows = grid.getData().getItems()
_(rows).map (row) ->
h = {}
i = 0
_(columns).each (column) ->
f = grid.getFormatter(row, column)
h[column.id] = f(row, i, row[column.id], column, row)
i += 1
h
add line to slick.grid.js in the // Public API section
"getFormatter": getFormatter,
When you set autoHeight: true the complete grid is rendered and the html could be exported.
http://mleibman.github.com/SlickGrid/examples/example11-autoheight.html
Answer to updated question:
The formatter is only called when a row is rendered/visible, so an array with the formatted data never exists. At the source: https://github.com/mleibman/SlickGrid/blob/master/slick.grid.js#L1291

Categories

Resources