Angularjs UI Grid Totals per Row inside the row - angularjs

{{ HelloWorld }}
I'm trying to access the values from other columns in the same row in angular-ui-grid. I have two question that are related.
How can I add the values from several columns in the same row to get a Total?
How can I use the row index to pass it as a parameter and remove the current row?
As you can see in the above image, the Totals that I'm looking for are only related to the integer values and not the initial string.
Also the Button with an X should delete the row when clicked. The rows are included in the grid dynamically.
I've gone through the UI Grid Tutorial but the examples don't show how to accomplish either of my questions.
My footer is working fine. It's configure to give a total but by column in the entire set of rows:
Here's a little bit of my code with what I've found so far:
var removeTemplate = '<button type="button" class="grid-remove btn btn-default btn-sm"><span class="glyphicon glyphicon-remove" aria-hidden="true" ng-click="removeRow($event, row.entity)"></span></button>';
$scope.gridAccountableHours = {
enableCellEditOnFocus: true,
showColumnFooter: true
};
$scope.gridAccountableHours.columnDefs = [
{ name: "contractCode", displayName: ""},
{ name: "hours1", displayName: "1", type: "number" },
{ name: "hours2", displayName: "2", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours3", displayName: "3", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours4", displayName: "4", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours5", displayName: "5", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours6", displayName: "6", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours7", displayName: "7", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours8", displayName: "8", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours9", displayName: "9", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours10", displayName: "10", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours11", displayName: "11", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours12", displayName: "12", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours13", displayName: "13", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours14", displayName: "14", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "hours15", displayName: "15", type: "number", aggregationType: uiGridConstants.aggregationTypes.sum },
{ name: "total", displayName: "Total" },
{ name: "remove", displayName: "", cellTemplate: removeTemplate }
];
$scope.removeRow = function ($event, entity) {
$event.stopPropagation();
$scope.gridAccountableHours.data.splice($scope.gridAccountableHours.data.indexOf(entity), 1);
};
I appreciate your time.

Totalling across the grid you could do with a function on the gridRow.
$scope.gridAccountableHours.forEach(function(rowEntity) {
rowEntity.total = function() {
var total = 0;
for( var 1 = 1; i++; i<=15 ){
total += this['hours'+i];
}
};
});
Your total column def should automatically bind to this total function. Refer http://ui-grid.info/docs/#/tutorial/106_binding
For the delete button, you're missing the appScope, refer http://ui-grid.info/docs/#/tutorial/305_appScope
Your template ng-click should be:
ng-click="grid.appScope.removeRow($event, row.entity)"

Related

Set minimum height or width for column FusionCharts

If data is very lower than others, it's almost like zero, and the user can't click or hover because it's too small.
How can I set a minimum height or width for very small numbers?
I have this problem with ApexCharts too.
const chartConfigs = {
type: "column2d",
width: "100%",
height: 500,
dataFormat: "json",
dataSource: {
chart: {
caption: "Countries With Most Oil Reserves [2017-18]",
subCaption: "In MMbbl = One Million barrels",
xAxisName: "Country",
yAxisName: "Reserves (MMbbl)",
numberSuffix: "K",
theme: "fusion",
},
data: [
{
label: "Venezuela",
value: "290",
},
{
label: "Saudi",
value: "260",
},
{
label: "Canada",
value: "180",
},
{
label: "Iran",
value: "140",
},
{
label: "Russia",
value: "115",
},
{
label: "UAE",
value: "100",
},
{
label: "US",
value: "3000000",
},
{
label: "China",
value: "30",
},
],
},
};
This is normal since your y-axis scale is linear if one of your plots has a very large value & the other plot values are very low compared to the large plot value then the plot area of the smaller value plot will be very minimum.
To overcome this you can use logarithmic y-axis, here is an example -
FusionCharts.ready(function() {
var footfallChart = new FusionCharts({
type: 'logmscolumn2d',
renderAt: 'chart-container',
width: '500',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"theme": "fusion",
"caption": "Store footfall vs Online visitors ",
"subCaption": "Last Year",
"xAxisName": "Quarter",
"yAxisName": "No of visitors",
"showXAxisLine": "1",
"axisLineAlpha": "10"
},
"categories": [{
"category": [{
"label": "Q1"
},
{
"label": "Q2"
},
{
"label": "Q3"
},
{
"label": "Q4"
}
]
}],
"dataset": [{
"seriesname": "Total footfalls",
"data": [{
"value": "126734"
},
{
"value": "64"
},
{
"value": "34"
},
{
"value": "56"
},
{
"value": "78"
}
]
}]
}
}).render();
});
<script src="https://cdn.fusioncharts.com/fusioncharts/latest/fusioncharts.js"></script>
<script src="https://cdn.fusioncharts.com/fusioncharts/latest/themes/fusioncharts.theme.fusion.js"></script>
<div id="chart-container">FusionCharts will render here</div>

React ant design table cell collapse issue

Im using my react type script project for ant design table
i want to know how to do that following image like as table, im search any tutorial but not seen anything, any one know how to do that correctly.
code sand box here
Thanks
image here
code here
class App extends React.Component {
columns: any = [
{
title: "Name",
dataIndex: "name",
key: "name"
},
{
title: "Age",
dataIndex: "age",
key: "age"
},
{
title: "Address",
dataIndex: "address",
key: "address"
},
{
title: "Tags",
key: "tags",
dataIndex: "tags"
},
{
title: "Action",
key: "action"
}
];
data: any = [
{
key: "1",
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"]
},
{
key: "2",
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park",
tags: ["loser"]
},
{
key: "3",
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park",
tags: ["cool", "teacher"]
}
];
render() {
return <Table columns={this.columns} dataSource={this.data} />;
}
}
You want to create 2 sub rows in each row, but only for some columns. you can use rowspan for this.
you can duplicate your rows (row1-row1-row2-row2-row3-row3-...), and put the subrow values in them (row1_subrow1-row1_subrow2-row2_subrow1-row2_subrow2-...), then use rowspan for the columns you want to expand (like Section and Name in your image), and expand the odd rows and collapse the even rows for this columns.
the full code : (Codesandbox Demo)
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table } from "antd";
let multiRowRender = (value, row, index) => {
const obj = {
children: value,
props: {}
};
if (index % 2 === 0) {
obj.props.rowSpan = 2;
}
if (index % 2 === 1) {
obj.props.rowSpan = 0;
}
return obj;
};
const columns = [
{
title: "Number",
dataIndex: "number"
},
{
title: "Issue",
dataIndex: "issue"
},
{
title: "Name",
dataIndex: "name",
render: multiRowRender
},
{
title: "Section",
dataIndex: "section",
render: multiRowRender
}
];
let data = [
{
key: "1",
name: "John Brown",
issues: [32, 100],
numbers: [18889898989, 545054],
section: "sec 1"
},
{
key: "2",
name: "Jim Green",
issues: [42, 50],
numbers: [18889898888, 1420054],
section: "sec 2"
}
];
let data2 = [];
data.forEach(d => {
data2.push({ ...d, issue: d.issues[0], number: d.numbers[0] });
data2.push({
...d,
issue: d.issues[1],
number: d.numbers[1],
key: d.key + "-row2"
});
});
data = data2;
ReactDOM.render(
<Table columns={columns} dataSource={data} bordered />,
document.getElementById("container")
);
Codesandbox Demo

Antd tree table grouped by column value

I need to implement tree table in my react application. that has grouped by an object property value.
The object is as follows
{
"SP": [
{
"DisplayName": "audi",
"Name": "r8",
"Type": "2012"
},
{
"DisplayName": "audi",
"Name": "rs5",
"Type": "2013"
}
],
"Code": [
{
"DisplayName": "ford",
"Name": "mustang",
"Type": "2012"
},
{
"DisplayName": "ford",
"Name": "fusion",
"Type": "2015"
}
],
"Message": [
{
"DisplayName": "kia",
"Name": "optima",
"Type": "2012"
}
]
}
And my table should be as the following image
I have used antd in my project and I tried to implement this functionality with antd table and could not implement as I want. I need the filter functionality too.
Can anyone suggest a solution
You need to restructure your dataSource witch children prop:
function NestedTables() {
return (
<Flexbox>
<Table
size="small"
indentSize={0}
columns={columns}
dataSource={source}
/>
</Flexbox>
);
}
When your source is:
const source = [
{
key: '1',
Code: 'SP',
children: [
{
key: '11',
Code: '5001',
DisplayName: 'audi',
Name: 'r8',
Type: '2012'
},
{
key: '12',
Code: '313',
DisplayName: 'audi',
Name: 'rs5',
Type: '2013'
}
]
},
{
key: '2',
Code: 'Code',
children: [
{
key: '21',
Code: '243',
DisplayName: 'ford',
Name: 'mustang',
Type: '2012'
},
{
key: '22',
Code: '503431',
DisplayName: 'ford',
Name: 'fusion',
Type: '2015'
}
]
},
{
key: '3',
Code: 'Message',
children: [
{
key: '31',
Code: '4311',
DisplayName: 'kia',
Name: 'optima',
Type: '2012'
}
]
}
];
And defined columns filters:
const columns = [
{
title: 'Code',
dataIndex: 'Code',
key: 'Code',
filters: [
{ text: 'SP', value: 'SP' },
{ text: 'Code', value: 'Code' },
{ text: 'Message', value: 'Message' }
],
onFilter: (value, record) => record.Code.indexOf(value) === 0
},
{
title: 'Display Name',
dataIndex: 'DisplayName',
key: 'DisplayName',
filters: [
{ text: 'audi', value: 'audi' },
{ text: 'ford', value: 'ford' },
{ text: 'kia', value: 'kia' }
],
onFilter: (value, record) =>
record.children.filter(child => child.DisplayName === value).length > 0
},
{ title: 'Name', dataIndex: 'Name', key: 'Name' },
{ title: 'Type', dataIndex: 'Type', key: 'Type' }
];
Demo:

Filter Array of Object from another Array of Object

Currently I'm filtering data based from questions that have checked property value equals to true..
const data = [
{Name: "foo", X1: "1", X2: "1", Other: "Test1"},
{Name: "bar", X1: "2",X2: "2",Other: "Test2"},
{Name: "test",X1: "2",X2: "3",Other: "Test3"}
];
const questions = [{rows: {text: "Text 1", checked: true,fields: "1",column: "X1"}
}, {rows: {text: "Text 2", checked: true,fields: "2",column: "X1"}
}, {rows: {text: "Text 3", checked: false,fields: "1",column: "X2"}
}, {rows: {text: "Text 4", checked: false,fields: "2",column: "X2"}
}, {rows: {text: "Text 5", checked: false,fields: "3",column: "X2"}
}];
console.log(questionArr);
// console.log(dataArr);
const res = data.filter(d => questions.find(f => d[f.rows.column] === f.rows.fields && f.rows.checked));
which works but does not work when filtering the actual data below. I think there's a slight difference between the question object and the actual question object below.. What should be my filter code when accessing these kind of structure ?
I think this is what you're looking for. I matched the data structure to the image in your question. Let me know if I missed something.
const data = [
{ Name: "foo", X1: "1", X2: "1", Other: "Test1" },
{ Name: "bar", X1: "2", X2: "2", Other: "Test2" },
{ Name: "test", X1: "2", X2: "3", Other: "Test3" }
];
const questions = [
{ rows: [{ text: "Text 1", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 2", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 3", checked: false, fields: "1", column: "X2" }] },
{ rows: [{ text: "Text 4", checked: false, fields: "2", column: "X2" }] },
{ rows: [{ text: "Text 5", checked: false, fields: "3", column: "X2" }] }
];
const result = data.filter(function(item){
return questions.some(function(question){
return question.rows.some(function(row){
return (row.checked && item[row.column] === row.fields);
});
});
});
console.log(result);
The compact version
const result = data.filter((item) => questions.some((question) => question.rows.some((row) => (row.checked && item[row.column] === row.fields))));
With perf in mind
const data = [
{ Name: "foo", X1: "1", X2: "1", Other: "Test1" },
{ Name: "bar", X1: "2", X2: "2", Other: "Test2" },
{ Name: "test", X1: "2", X2: "3", Other: "Test3" }
];
const questions = [
{ rows: [{ text: "Text 1", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 2", checked: true, fields: "2", column: "X1" }] },
{ rows: [{ text: "Text 3", checked: false, fields: "1", column: "X2" }] },
{ rows: [{ text: "Text 4", checked: false, fields: "2", column: "X2" }] },
{ rows: [{ text: "Text 5", checked: false, fields: "3", column: "X2" }] }
];
const result = {};
for(let a = 0, b = data.length; a < b; a++){
const item = data[a];
for(let c = 0, d = questions.length; c < d; c++){
const rows = questions[c].rows;
for(let e = 0, f = rows.length; e < f; e++){
const row = rows[e];
if(row.checked && item[row.column] === row.fields){
result[item.Name] = item;
break;
}
}
}
}
// this could be replaced with Object.values(result);
const matches = [];
for(let match in result){
matches.push(result[match]);
}
// not supported by IE yet
// Object.values(result);
console.log(matches);

How to hide backgrid column?

Hi friends. I'm using backgrid in my project. I want to hide Id column from backgrid. Here is my code.
var columns = [
{ name: "id", label: "Id", cell: "integer", editable: false },
{ name: "payment_date", label: "Payment Date", cell: "date" ,editable: false },
{ name: "number_of_task", label: "Total Task", cell: "integer" ,editable: false },
{ name: "amount", label: "Amount", cell: "integer" ,editable: false }
];
add a renderable: false attribute. See renderable here http://wyuenho.github.io/backgrid/api/index.html#!/api/Backgrid.Column
Simply remove the column definition. You don't need a column definition for each addribute in your data; you only need the column definition of attributes you want visible in the table.
var columns = [
{ name: "payment_date", label: "Payment Date", cell: "date" ,editable: false },
{ name: "number_of_task", label: "Total Task", cell: "integer" ,editable: false },
{ name: "amount", label: "Amount", cell: "integer" ,editable: false }];
The attribute renderable:false didn't work for me hence used below as workaround
var HideCell = Backgrid.HideCell = Backgrid.Cell.extend({
/** #property */
className: "hide-cell",
initialize: function () {
Backgrid.Cell.prototype.initialize.apply(this, arguments);
},
render: function () {
this.$el.hide();
return this;
}
});
use in column as cell "hide"
var columns = [
{ name: "id", label: "Id", cell: HideCell, editable: false }
];

Resources