Add row number column to table - react-bootstrap-table

I'm trying to do something simple: display the row number on a react-bootstrap-table column. Problem is that the only way it seems possible is by adding a data field with indexes, which get scrambled if sorting is turned on.
Ideally there would be a method that allows for this but I can't seem to find any.

I had the same issue.
add
TableHeaderColumn
like this:
<BootstrapTable data={data}>
...
<TableHeaderColumn dataField="any" dataFormat={indexN}>#</TableHeaderColumn>
...
</BootstrapTable>
and function:
function indexN(cell, row, enumObject, index) {
return (<div>{index+1}</div>)
}

For now there is a big change in the react-bootstrap-table2, that there's no TableHeaderColumn, instead you are supposed to be define the "columns" prop on BootstrapTable. I solve this issue by using columns formatter and data mapping like so:
In the Backend:
const ret = data.map((d, i) => {
return { num: i + 1, id: d.id, name: d.name, age: d.age}
});
return ret;
In the Frontend:
const columns = [{
dataField: 'id',
text: '#',
sort: true,
headerStyle: () => {
return { width: '10%', textAlign: 'center' }
},
formatter: (rowContent: any, row: any) => {
return (
<div>
{row.num}
</div>
)
}
}
Ref: https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/migration.html

Related

Trying to update a my Express Data base using postman

How do I update my database using Postman?
I'm trying to learn Express using Postman to test different types of requests, but I can't figure out how to update my data set. This is the structure of the data set I'm using.
var DB = [
{ category: 'Pets',
products: [
{ name: 'banjo',
color: 'grey',
mean: true,
description: "meows"
},
{ name: 'rigby',
color: 'black and white',
mean: false,
description: 'barks'
}]}]
Lets say I want to add another pet into the pets category so in products
{name: frank, color: orange, : mean: false: description: glubs}
I cant figure out how to add it correctly in Postman so that itll update. My code for the update is as follow:
app.post("/product/add", (req, res) => {
var category = req.body.category;
const { name, color, mean, description } = req.body;
var product = { name:name, color:color, mean:mean, description:description }; console.log(product);
var index = DB.findIndex(x => x.category == category);
if(index !== -1){
var indexProduct = DB[index].products.findIndex(x => x.name == product.name); if(indexProduct !== -1){
DB[index].products.push(product);
res.status(200).send(DB);
} else {
res.status(200).send(`Product already added to category.`);
};
} else {
res.status(200).send(`Category not found.`);
} });
Thanks in advance! Also sorry for the format.
There are a lot of repetitions, destructured variables that are not needed and syntactic errors in your code. Start by breaking down your problem into smaller chunks that are more manageable and then, test your endpoint with postman.
Let's start with your data and how it is structured:
var DB = [{
category: 'Pets',
products: [{
name: 'banjo',
color: 'grey',
mean: true,
description: "meows"
},
{
name: 'rigby',
color: 'black and white',
mean: false,
description: 'barks'
}
]
}]
// Lets say you want to add another pet into the pets category so in products
const obj = {
name: "frank",
color: "orange",
mean: false,
description: "glubs"
}
This is one of the things you could do to check if the object is not found and if not, you add it to your db.
DB.forEach((val) => {
if (val.products.name !== obj.name) {
DB[0].products.push(obj);
}
})
console.log(DB[0].products)
/**
*[{
name: 'banjo',
color: 'grey',
mean: true,
description: 'meows'
},
{
name: 'rigby',
color: 'black and white',
mean: false,
description: 'barks'
},
{
name: 'frank',
color: 'orange',
mean: false,
description: 'glubs'
}
]
*/
You postman request could look like this:
app.post("/product/add", (req, res) => {
// extract just what you need e.g name or ID if you have one...
const { name } = req.body;
// NOT efficient, best if you use a unique ID to look up
DB.forEach(value => {
if (value.products.name !== name) {
DB[0].products.push(req.body);
return res.status(200).send(JSON.stringify(DB));
}
else
return res.status(404).send("Not found or whatever");
});
});
OR using Array.prototype.findIndex you could do:
app.post("/product/add", (req, res) => {
const { name } = req.body;
const index = DB.forIndex(value => value === name);
if (index === -1) {
DB[0].products.push(req.body);
return res.status(200).send(JSON.stringify(DB));
}
else
return res.status(404).send("Not found or whatever");
}
});
Note: if your object name is the same than another one, your new object won't be pushed to the DB array. This would suggest you need to index your object with a unique identifier.

How to change the columns collection set of a kendo TreeList dynamically?

Try to change the columns list dynamically via a query ...
When I construct the TreeList, I call for columns :
$("#treelist").kendoTreeList({
columns: AnalyseCenterSKUService.getKPIColumnList($scope)
If I return a simple array with the fields, it's working ..
If I call a $http.get (inside my getKPIColumnList(..) function) which add some columns to the existing array of columns, the TreeList is not constructed correctly.
Any suggestion will be really appreciated ! :)
EDIT 22-10-2019 09:00
Treelist init
$("#treelist").kendoTreeList({
columns: AnalyseCenterSKUService.getKPIColumnList($scope),
scrollable: true,
columnMenu : {
columns : true
},
height: "100%",
dataBound: function (e) {
ExpandAll();
},
dataSource: {
schema: {
model: {
id: "id",
parentId: "parentId",
fields: {
id: { type: "number" },
parentId: { type: "number", nullable: true },
fields: {
id: { type: "number" },
parentId: { type: "number", nullable: false }
}
}
}
},
transport: {
read: {
url: "/api/AnalyseCenter/GetWorkOrderTree/0",
dataType: "json"
}
}
}
The getKPIColumnList return an static array + some push with dynamic columns (from DB)
angular.module('AnalyseCenterDirectives')
.service ('AnalyseCenterSKUService', function ($http) {
var toReturn = [ {field: "Name", title: "Hiérachie SKU", width: "30%" }, ..., ..., .... ];
I try in this function to push DB result
return $http.get("/api/AnalyseCenter/GetWorkOrderHistorianAdditonalColumns?equipmentName=" + equipmentName)
.then(function (result) {
var data = result.data;
if (data && data !== 'undefined') {
var fromDB = data;
angular.forEach(fromDB, function (tag) {
var tagName = tag.replace(".","_");
toReturn.push({
field: tagName, title: tag, width: '10%',
attributes: { style: "text-align:right;"} })
})
The stored procedure GetWorkOrderHistorianAdditonalColumns returns a list of string (future column)
That is because ajax is async, that means your tree list is being initialized before the request finishes. A classic question for JavaScript newcomers. I suggest you take a while to read about ajax, like How does AJAX works for instance.
Back to your problem. You need to create your tree list inside the success callback(I can't give you a more complete solution since I don't know what you're doing inside your function or which framework you're using to open that ajax request) with the result data, which is probably your columns. Then it would work as if you're initializing it with arrays.

Getting documents with ID from firstore collection

While using Firestore, vuefire, vue-tables-2, I stuck getting document's id.
My data structure is as below.
Here is my code.
<v-client-table :columns="columns" :data="devices" :options="options" :theme="theme" id="dataTable">
import { ClientTable, Event } from 'vue-tables-2'
import { firebase, db } from '../../firebase-configured'
export default {
name: 'Devices',
components: {
ClientTable,
Event
},
data: function() {
return {
devices: [],
columns: ['model', 'id', 'scanTime', 'isStolen'],
options: {
headings: {
model: 'Model',
id: 'Serial No',
scanTime: 'Scan Time',
isStolen: 'Stolen YN'
},
templates: {
id: function(h, row, index) {
return index + ':' + row.id // <<- row.id is undefined
},
isStolen: (h, row, index) => {
return row.isStolen ? 'Y': ''
}
},
pagination: {
chunk: 5,
edge: false,
nav: 'scroll'
}
},
useVuex: false,
theme: 'bootstrap4',
template: 'default'
}
},
firestore: {
devices: db.collection('devices')
},
};
My expectation is devices should id property as vuefire docs.
But array this.devices didn't have id field even if I check it exist it console.
Basically, every document already has id attribute, but it's non-enumerable
Any document bound by Vuexfire will retain it's id in the database as
a non-enumerable, read-only property. This makes it easier to write
changes and allows you to only copy the data using the spread operator
or Object.assign.
You can access id directly using device.id. But when passing to vue-tables-2、devices is copied and lost id non-enumerable attribute.
I think you can workaround using computed property
computed: {
devicesWithId() {
if (!this.devices) {
return []
}
return this.devices.map(device => {
...device,
id: device.id
})
}
}
Then, please try using devicesWithId in vue-tables-2 instead.

How to get filtered rows from GridX?

I'm using Dojo GridX with many modules, including filter:
grid = new Grid({
cacheClass : Cache,
structure: structure,
store: store,
modules : [ Sort, ColumnResizer, Pagination, PaginationBar, CellWidget, GridEdit,
Filter, FilterBar, QuickFilter, HiddenColumns, HScroller ],
autoHeight : true, autoWidth: false,
paginationBarSizes: [25, 50, 100],
paginationBarPosition: 'top,bottom',
}, gridNode);
grid.filterBar.applyFilter({type: 'all', conditions: [
{colId: 'type', condition: 'equal', type: 'Text', value: 'car'}
]})
I've wanted to access the items, that are matching the filter that was set. I've travelled through grid property in DOM explorer, I've found many store references in many modules, but all of them contained all items.
Is it possible to find out what items are visible in grid because they are matching filter, or at least those that are visible on current page? If so, how to do that?
My solution is:
try {
var filterData = [];
var ids = grid.model._exts.clientFilter._ids;
for ( var i = 0; i < ids.length; ++i) {
var id = ids[i];
var item = grid.model.store.get(id);
filterData.push(item);
}
var store = new MemoryStore({
data : filterData
});
} catch (error) {
console.log("Filter is not set.");
}
I was able to obtain filtered gridX data rows using gridX Exporter. Add this Exporter module to your grid. This module does exports the filtered data. Then, convert CSV to Json. There are many CSV to Json conversion javasripts out there.
this.navResult.grid.exporter.toCSV(args).then(this.showResult, this.onError, null)
Based on AirG answer I have designed the following solution. Take into account that there are two cases, with or without filter and that you must be aware of the order of rows if you have applied some sort. At least this works for me.
var store = new Store({
idProperty: "idPeople", data: [
{ idPeople: 1, name: 'John', score: 130, city: 'New York', birthday: '31/02/1980' },
{ idPeople: 2, name: 'Alice', score: 123, city: 'Wáshington', birthday: '07/12/1984' },
{ idPeople: 3, name: 'Lee', score: 149, city: 'Shanghai', birthday: '8/10/1986' },
...
]
});
gridx = new GridX({
id: 'mygridx',
cacheClass: Cache,
store: store,
...
modules: [
...
{
moduleClass: Dod,
defaultShow: false,
useAnimation: true,
showExpando: true,
detailProvider: gridXDetailProvider
},
...
],
...
}, 'gridNode');
function gridXDetailProvider (grid, rowId, detailNode, rendered) {
gridXGetDetailContent(grid, rowId, detailNode);
rendered.callback();
return rendered;
}
function gridXGetDetailContent(grid, rowId, detailNode) {
if (grid.model._exts.clientFilter._ids === undefined || grid.model._exts.clientFilter._ids === 0) {
// No filter, with or without sort
detailNode.innerHTML = 'Hello ' + grid.row(grid.model._cache._priority.indexOf(rowId)).item().name + " with id " +
grid.row(grid.model._cache._priority.indexOf(rowId)).item().idPeople;
} else {
// With filter, with or without sort
detailNode.innerHTML = 'Hello ' + grid.row(grid.model._exts.clientFilter._ids.indexOf(rowId)).item().name + " with id " +
grid.row(grid.model._exts.clientFilter._ids.indexOf(rowId)).item().idPeople;
}
}
Hope that helps,
Santiago Horcajo
function getFilteredData() {
var filteredIds = grid.model._exts.clientFilter._ids;
return grid.store.data.filter(function(item) {
return filteredIds.indexOf(item.id) > -1;
});
}

NumberSpinner constraints not working in DataGrid

I am using inline editing of enhancedgrid cells and have a NumberSpinner element. The constraints of this numberspinner don't work when editing inline. The required property works fine though.
My code:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, editorParams:{constraints:{ min:-1000, max:1000, places:0 }} }}
I have also tried:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, constraints:{ min:-1000, max:1000, places:0 } }}
There is an easier solution, guys:
constraint:{min:0,max:24}
{field: "hours", name: "Stunden",type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, constraint:{min:0,max:24}, widgetProps: {smallDelta:0.25, intermediateChanges:true,}},
It has to be outside of widgetProps and in singular...
I don't know what version of Dojo you use, but there is known bug in 1.6 that constraints are ignored in grid widgets. However, I solve that problem doing a little overwriting standard NumberSpinner.
dojo.require("dijit.form.NumberSpinner");
dojo.addOnLoad(function() {
dojo.declare("mySpinner", [ dijit.form.NumberSpinner], {
validator: function(v, c){
var MIN= -1000;
var MAX = 1000;
c.min= MIN;
c.max = MAX ;
return ((v < MAX ) && (v > MIN));
},
});
var dateBox = new mySpinner({}).placeAt('foo');
dateBox.set("value", 1000);
});
(Now, in your grid structure you should use mySpinner of course, and it should do the trick).
Demo: http://jsfiddle.net/tvUaK/135/
I used another way to solve that problem. I define the type of cell as Widget and then I create the widget on get method.
{
field: 'msorder',
width: '10%',
name: 'Milestone Order',
editable: true,
type: dojox.grid.cells._Widget,
get: function(rowIndex, item) {
var store = this.grid.store,
value = store.getValue(item, 'value');
this.widget = new dijit.form.NumberSpinner({ value:0,
constraints:{ min:-1000, max:1000 }
});
return value;
}
}
With this implementation I was able to set different constraints for each cell on the grid.