This is my first question on stackoverflow and i'm totally newbie to dartlang.
I have 8 input fields which i created using this:
InputElement in1 = new InputElement();
in1.placeholder = "№";
InputElement in2 = new InputElement();
in2.placeholder = "Name";
...
InputElement in8 = new InputElement();
in8.placeholder = "Date";
And i couldn't figure out how to automatically generate row with tds containing those input fields. If i create it manually my code would look like this:
InputElement in1 = new InputElement();
in1.placeholder = "№";
TableCellElement cell1 = new Element.td();
cell1.nodes.add(in1);
InputElement in2 = new InputElement();
in2.placeholder = "Name";
TableCellElement cell2 = new Element.td();
cell2.nodes.add(in2);
InputElement in3 = new InputElement();
in3.placeholder = "LastName";
TableCellElement cell3 = new Element.td();
cell3.nodes.add(in3);
InputElement in4 = new InputElement();
in4.placeholder = "Register No";
TableCellElement cell4 = new Element.td();
cell4.nodes.add(in4);
InputElement in5 = new InputElement();
in5.placeholder = "University";
TableCellElement cell5 = new Element.td();
cell5.nodes.add(in5);
InputElement in6 = new InputElement();
in6.placeholder = "Occupation";
TableCellElement cell6 = new Element.td();
cell6.nodes.add(in6);
InputElement in7 = new InputElement();
in7.placeholder = "Grade";
TableCellElement cell7 = new Element.td();
cell7.nodes.add(in7);
InputElement in8 = new InputElement();
in8.placeholder = "Date";
TableCellElement cell8 = new Element.td();
cell8.nodes.add(in8);
TableRowElement tr1 = new Element.tr();
tr1.classes.add("table-header-student");
tr1.nodes.add(cell1);
tr1.nodes.add(cell2);
tr1.nodes.add(cell3);
tr1.nodes.add(cell4);
tr1.nodes.add(cell5);
tr1.nodes.add(cell6);
tr1.nodes.add(cell7);
tr1.nodes.add(cell8);
I don't wanna create it manually cuz i need to do it on other tables with different columns. And the reason i'm creating these input field is to create filtering.
Pls don't suggest innerHtml, appendHtml cuz i have to create it with purely dart code.
I think it's possible to do by making list and using loop but i don't know how. Pls help me!
I'm not sure if I understand your question correctly but I assume this is what you want.
List<String> placeholders = ['№', 'Name', 'LastName', 'Register No', 'University', 'Occupation', 'Grade', 'Date'];
TableRowElement tr = new Element.tr()
..classes.add("table-header-student");
placeholders.forEach((ph) {
tr.append(new TableCellElement()..append(new InputElement()..placeholder = ph));
});
querySelector('table').append(tr);
example with more attributes (not tested)
List<String> fields = [
{'placeholder': '№', 'id': 'id1', 'name': 'name1'},
{'placeholder': 'Name', 'id': 'id2', 'name': 'name2'},
{'placeholder': 'LastName', 'id': 'id3', 'name': 'name3'},
{'placeholder': 'Register No', 'id': 'id4', 'name': 'name4'},
{'placeholder': 'University', 'id': 'id5', 'name': 'name5'},
{'placeholder': 'Occupation', 'id': 'id6', 'name': 'name6'},
{'placeholder': 'Grade', 'id': 'id7', 'name': 'name7'},
{'placeholder': 'Date', 'id': 'id8', 'name': 'name8'}];
TableRowElement tr = new Element.tr()
..classes.add("table-header-student");
fields.forEach((f) {
tr.append(new TableCellElement()..append(
new InputElement()
..placeholder = f['placeholder']
..id = f['id']
..name = f['name']
));
});
querySelector('table').append(tr);
If your element creation logic becomes more complicated I would create a function/method for this
main() {
List<String> fields = [
{'placeholder': '№', 'id': 'id1', 'name': 'name1'},
{'placeholder': 'Name', 'id': 'id2', 'name': 'name2'},
{'placeholder': 'LastName', 'id': 'id3', 'name': 'name3'},
{'placeholder': 'Register No', 'id': 'id4', 'name': 'name4'},
{'placeholder': 'University', 'id': 'id5', 'name': 'name5'},
{'placeholder': 'Occupation', 'id': 'id6', 'name': 'name6'},
{'placeholder': 'Grade', 'id': 'id7', 'name': 'name7'},
{'placeholder': 'Date', 'id': 'id8', 'name': 'name8'}];
TableRowElement tr = new Element.tr()
..classes.add("table-header-student");
fields.forEach((f) {
tr.append(new TableCellElement()..append(createInputElement(f));
});
querySelector('table').append(tr);
}
InputElement createInputElement(Map metadata) {
var ie = new InputElement();
if(metadata['placeholder'] != null) ie.placeholder = metadata['placeholder'];
if(metadata['id'] != null) ie.id = metadata['id'];
if(metadata['name'] != null) ie.name = metadata['name'];
// ... more element customization
return ie;
}
Related
I have a map like this:
{id2: {quantity: 6, name: NEW NAME}, 1484: {quantity: 1, name: NEW NAME 404}, id: {quantity: 34, name: NEW NAME}}
here I have a key called "quantity" what i need to do is calculate the total quantity , for this example 6+1+34 = 41 , maybe using .reduce method but can't find how to implement it on a map.
I think it make more sense to use fold which you can read about here: https://api.dart.dev/stable/2.10.5/dart-core/Iterable/fold.html
void main() {
final map = {
'id2': {'quantity': 6, 'name': 'NEW NAME'},
1484: {'quantity': 1, 'name': 'NEW NAME 404'},
'id': {'quantity': 34, 'name': 'NEW NAME'}
};
final sum = map.values
.fold(0, (int sum, element) => sum + (element['quantity'] as int));
print(sum); // 41
}
But if you really want to use reduce you can do it like this:
void main() {
final map = {
'id2': {'quantity': 6, 'name': 'NEW NAME'},
1484: {'quantity': 1, 'name': 'NEW NAME 404'},
'id': {'quantity': 34, 'name': 'NEW NAME'}
};
final sum =
map.values.map((e) => e['quantity'] as int).reduce((a, b) => a + b);
print(sum); // 41
}
I have a device that get some telemetry data via REST API. Some of the data that it received is in the following format:
{
...
parameters: [
{
'name': 'parameter1',
'grade': '2',
'info': 'some informtion'
},
{
'name': 'parameter2',
'grade': '1',
'info': 'some informtion'
},
...
]
}
what I want to do is to visualize the data in the following way:
name | grade | info
---------------------------------------
parameter1 | 2 | some information
parameter2 | 1 | some information
... | ... | ...
now if I break down each parameter and send it to the device separately it will override the previous one.
How can I make that?
Figured out a way to do this:
Go to 'Widget Bundle' and create a new widget bundle.
Create a new widget of type 'Latest values'.
Here we have CSS/HTML section and a Javascript section.
HTML section:
<div class="my-data-table">
</div>
Javascript section:
self.defaultList = [
{
'id': 1,
'name': 'name 1',
'grade': 123,
'description': 'This is a description'
},
{
'id': 2,
'name': 'name 2',
'grade': 456,
'description': 'More description'
},
{
'id': 3,
'name': 'name 3',
'grade': 789,
'description': 'Even more description'
}
];
self.createTable = function(data) {
const columnNames = Object.keys(data[0]);
let tableHeadContent = $('<tr></tr>');
columnNames.forEach((columName) => {
tableHeadContent.append('<td>' + columName + '</td>');
});
let tableHead = $('<thead></thead>').append(tableHeadContent);
let tableBody = $('<tbody></tbody>');
data.forEach((currentElement, index) => {
const vals = Object.values(currentElement);
let currentRow = $('<tr></tr>');
vals.forEach((val) => {
currentRow.append('<td>' + val + '</td>');
});
tableBody.append(currentRow);
});
return $('<table></table>').append(tableHead).append(tableBody);
}
self.onInit = function() {
let currentList = [...self.defaultList];
if(self.ctx.defaultSubscription.data[0].data.length !== 0) {
currentList = JSON.parse(self.ctx.defaultSubscription.data[0].data[0][1]);
}
let currentTable = self.createTable(currentList);
$('.my-data-table', self.ctx.$container).append(currentTable);
}
self.onDataUpdated = function() {
self.ctx.detectChanges();
}
What you need to pay attention to and understand is self.ctx.defaultSubscription.data, when you visualize your data with a certain widget you subscribe the data to the widget. self.ctx.defaultSubscription.data give you access to the data, you can console.log() it to see how it is structured.
The self.defaultList is for the preview and when you set this widget to a specific data it will use that data.
There may be other way to do this but this is how I did it.
Im usiing My react typescript project for Ant design 4 table . so when i adding ant design Summary table, got a following error
TS2741: Property 'index' is missing in type '{ children: Element; colSpan: number; }' but required in type 'SummaryCellProps'.
any one know how to fix that issue.
Thanks
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Table, Typography } from 'antd';
const { Text } = Typography;
const columns = [
{
title: 'Name',
dataIndex: 'name',
},
{
title: 'Borrow',
dataIndex: 'borrow',
},
{
title: 'Repayment',
dataIndex: 'repayment',
},
];
const data = [
{
key: '1',
name: 'John Brown',
borrow: 10,
repayment: 33,
},
{
key: '2',
name: 'Jim Green',
borrow: 100,
repayment: 0,
},
{
key: '3',
name: 'Joe Black',
borrow: 10,
repayment: 10,
},
{
key: '4',
name: 'Jim Red',
borrow: 75,
repayment: 45,
},
];
const fixedColumns = [
{
title: 'Name',
dataIndex: 'name',
fixed: true,
width: 100,
},
{
title: 'Description',
dataIndex: 'description',
},
];
const fixedData = [];
for (let i = 0; i < 6; i += 1) {
fixedData.push({
key: i,
name: i % 2 ? 'Light' : 'Bamboo',
description: 'Everything that has a beginning, has an end.',
});
}
ReactDOM.render(
<>
<Table
columns={columns}
dataSource={data}
pagination={false}
bordered
summary={pageData => {
let totalBorrow = 0;
let totalRepayment = 0;
pageData.forEach(({ borrow, repayment }) => {
totalBorrow += borrow;
totalRepayment += repayment;
});
return (
<>
<Table.Summary.Row>
<Table.Summary.Cell>Total</Table.Summary.Cell>
<Table.Summary.Cell>
<Text type="danger">{totalBorrow}</Text>
</Table.Summary.Cell>
<Table.Summary.Cell>
<Text>{totalRepayment}</Text>
</Table.Summary.Cell>
</Table.Summary.Row>
<Table.Summary.Row>
<Table.Summary.Cell>Balance</Table.Summary.Cell>
<Table.Summary.Cell colSpan={2}>
<Text type="danger">{totalBorrow - totalRepayment}</Text>
</Table.Summary.Cell>
</Table.Summary.Row>
</>
);
}}
/>
</>,
document.getElementById('container'),
);
Had this issue yesterday as well, looking at the SummeryCellProps the rc-table team made index required. So I just added <Table.Summary.Row index={1}> you need to iterate through your pagedata to add the index of the that column
I have the following list with phone numbers:
listofnumbers = ['01225','03933']
and a list of map objects as:
List mapofobjects = [
{
'name': 'John Doe',
'phone': {
'numbers': ['03323', '02333'],
'verified': true
},
'uid': '2BDNDD',
'createdat': 'today..'
},
{
'name': 'Mary Doe',
'phone': {
'numbers': ['03933', '39939'], // matches 03933 in listofnumbers
'verified': true
},
'uid': '1BDNDD',
'createdat': 'today..'
},
{
'name': 'Vincin Doe',
'phone': {
'numbers': ['01225', '59939'], // matches 01225 in listofnumbers
'verified': true
},
'uid': 'XBDNDD',
'createdat': 'today..'
}
];
How can I convert the listofnumbers into a list of map objects using each listofnumbers item as join.
I should get something like this for the listofnumbers of two numbers:
finalList = List mapofobjects = [
{
'name': 'John Doe',
'phone': {
'numbers': ['03323', '02333'],
'verified': true
},
'uid': '1BDNDD',
'createdat': 'today..'
},
{
'name': 'Vincin Doe',
'phone': {
'numbers': ['01225', '59939'],
'verified': true
},
'uid': 'XBDNDD',
'createdat': 'today..'
}
];
With each object matching/replacing a listofnumbers of item when phone['numbers'] contains the item.
You can use two forEach to get this result, like this:
List finallist = [];
listofnumbers.forEach((element) {
mapofobjects.forEach((e) => {
if (e['phone']['numbers'].contains(element))
finallist.add(e)
});
});
print(finallist.length.toString());
the result is: 2
You can do something like this:
final finalList = [
...mapofobjects.where((dynamic object) =>
object['phone']['numbers'].any((phone) => listofnumbers.contains(phone)))
];
finalList.forEach(print);
// {name: Mary Doe, phone: {numbers: [03933, 39939], verified: true}, uid: 1BDNDD, createdat: today..}
// {name: Vincin Doe, phone: {numbers: [01225, 59939], verified: true}, uid: XBDNDD, createdat: today..}
I have an angular ui-grid that has a column for a date, which indicates the date an email was sent to a new user:
{
name: "SentOn",
displayName: "Sent On",
cellFilter: "date:\"yyyy-MM-dd HH:mm\""
}
The email is not sent until a number of background processes are complete, so this date can be null. When the date is null, nothing shows in the cell.
Is there a straight forward way to display some default text when the date is null?
There are two ways you can achieve what you want here.
You can provide a custom template for the cell to handle the null date scenario. This is probably easier option too.
{
name: "SentOn",
displayName: "Sent On",
cellTemplate : "<div class=\"ui-grid-cell-contents\">{{COL_FIELD CUSTOM_FILTERS || \"Not Sent\"}}</div>"
}
Or you can create a custom cellFilter which will take care of the null date. You can extend the existing date filter to achieve this.
var app = angular.module('app', ['ngTouch', 'ui.grid','ui.grid.edit']);
var grid;
app.filter('customDate', function($filter){
var standardDateFilterFn = $filter('date');
return function(dateToFormat){
if(!dateToFormat)
return "Not Sent Yet";
return standardDateFilterFn(dateToFormat, 'yyyyMMddhhmmss');
}
});
app.controller('MainCtrl', ['$scope', function ($scope) {
var myData = [
{
id1:new Date(),id2:"2",id3:"3",id4:"4",id5:"5",
}, {
id1:null,id2:"2",id3:"3",id4:"4",id5:"5",
},]
var getTemplate = function()
{
return "<div class=\"ui-grid-cell-contents\">{{COL_FIELD CUSTOM_FILTERS}}</div>";
}
var cellEditable = function($scope){
if($scope.row.entity.oldId4===undefined)
return false;
return $scope.row.entity.oldId4!=$scope.row.entity.id4;
}
$scope.gridOptions = {
enableFiltering: true,
onRegisterApi: function(gridApi){
grid = gridApi;
},
data: myData,
columnDefs:[
{
field: 'id1',
displayName: "id1",
width: 200,
cellTemplate: getTemplate(),
cellFilter : "customDate:\"yyyy-MM-dd HH:mm\""
},
{
field: 'id2',
displayName: "id2",
width: 100
},{
field: 'id3',
displayName: "id3",
width: 100
},{
field: 'id4',
displayName: "id4",
width: 100
},{
field: 'id5',
displayName: "id5",
width: 100
},
],
}
$scope.gridOptions.onRegisterApi = function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope,function(rowEntity, colDef, newValue, oldValue){
rowEntity.oldId4 = oldValue;
$scope.$apply();
});
};
$scope.test = function()
{
window.alert("Cell clicked")
}
}]);
here is a working plnkr. http://plnkr.co/edit/qHaRzkzxGEphuTMQ6oqG?p=preview