How to fetch data from given format on datatable? - javascript

I am trying to write logic to display data in datatable. Below is the table I need to display.
There will be only 5 columns Day1 to Day5.
In rows, if dayName='DAY 1' then data present in weekDay arrayList needs to be fetch like Music Theme(which is value to theme key in weekDay arrayList). 10 mins is themeTime and singing practice is title and so on.
Below is format of data -
[
{
"id": "7658dc9e-5720-4544-8780-761e1993a8a3",
"folderMapID": "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
"themeName": "test",
"classTime": 45,
"dayName": "DAY 2",
"isActive": true,
"weekDay": [
{
"id": "2cebd6c7-339d-4d99-a199-b1c145211272",
"position": 1,
"theme": "QA Theme One",
"themeTime": 14,
"title": "test title",
"isActive": true
}
]
},
{
"id": "8f638849-6e54-4949-b404-300aa2c8a0c0",
"folderMapID": "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
"themeName": "Butterfly Theme",
"classTime": 60,
"dayName": "DAY 1",
"isActive": true,
"weekDay": [
{
"id": "3796dac9-18b0-4dd4-912f-8aeeede84e6b",
"position": 1,
"theme": "Music Theme",
"themeTime": 10,
"title": "singing practice",
"isActive": true
},
{
"id": "57b8f608-d2ad-4f7b-807b-db75aa0d10a9",
"position": 2,
"theme": "Dance Theme",
"themeTime": 15,
"title": "learn dance steps",
"isActive": true
},
{
"id": "d395b047-2847-474a-a553-afbd93782092",
"position": 3,
"theme": "QA Theme One",
"themeTime": 20,
"title": "QA testing",
"isActive": true
}
]
}
]
HTML template -
<v-data-table :headers="headers" :items="weekScheduleList" disable-pagination
hide-default-footer>
<template v-slot:no-data>
<v-card-subtitle class="d-flex justify-center">No Data Available</v-card-subtitle>
</template>
</v-data-table>
export default {
data () {
return {
weekScheduleList: [],
theme: '',
headers: [
{ text: 'DAY 1', value: 'theme', align: 'center', sortable: true },
{ text: 'DAY 2', value: '0', align: 'center', sortable: true },
{ text: 'DAY 3', value: '0', align: 'center', sortable: true },
{ text: 'DAY 4', value: '0', align: 'center', sortable: true },
{ text: 'DAY 5', value: '0', align: 'center', sortable: true }
],
}
},
methods: {
getWeekScheduleList: async function () {
try {
this.isLoading = true
let res = await http.get(`${CONSTANTS.API_URL}/api/get-week/${this.folderId}`)
const days = res.data
const newData = []
days.forEach(day => {
const row = {
day: day.dayName
}
day.weekDay.forEach(weekDay => {
row[weekDay.theme] = `${weekDay.theme} - ${weekDay.themeTime} mins - ${weekDay.title}`
})
newData.push(row)
})
this.weekScheduleList = newData
console.log('this.weekScheduleList :', this.weekScheduleList)
} catch (e) {
const errorMessage = (e && e.response && e.response.data.message) || e.message
this.errMsg(errorMessage)
}
},
}

As per looking at your tabular UI, you need to convert your API data in the below format where each row would have all 5 days' data.
[
{
// Day 1,
// Day 2,
// Day 3,
// Day 4,
// Day 5
},
{
// Day 1,
// Day 2,
// Day 3,
// Day 4,
// Day 5
}
]
Try the below logic in your getWeekScheduleList function. I added the respective comments to explain the code.
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
</head>
<body>
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="weekScheduleList"
disable-pagination
hide-default-footer
>
</v-data-table>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
weekScheduleList: [],
theme: "",
headers: [{
text: "DAY 1",
value: "DAY 1",
align: 'center',
sortable: true
},
{
text: "DAY 2",
value: "DAY 2",
align: 'center',
sortable: true
},
{
text: "DAY 3",
value: "DAY 3",
align: 'center',
sortable: true
},
{
text: "DAY 4",
value: "DAY 4",
align: 'center',
sortable: true
},
{
text: "DAY 5",
value: "DAY 5",
align: 'center',
sortable: true
},
],
api_data: [{
id: "7658dc9e-5720-4544-8780-761e1993a8a3",
folderMapID: "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
themeName: "test",
classTime: 45,
dayName: "DAY 2",
isActive: true,
weekDay: [{
id: "2cebd6c7-339d-4d99-a199-b1c145211272",
position: 1,
theme: "QA Theme One",
themeTime: 14,
title: "test title",
isActive: true,
}, ],
},
{
id: "8f638849-6e54-4949-b404-300aa2c8a0c0",
folderMapID: "d56eb3ff-dc9f-477e-82b2-ffc29a12b9f1",
themeName: "Butterfly Theme",
classTime: 60,
dayName: "DAY 1",
isActive: true,
weekDay: [{
id: "3796dac9-18b0-4dd4-912f-8aeeede84e6b",
position: 1,
theme: "Music Theme",
themeTime: 10,
title: "singing practice",
isActive: true,
},
{
id: "57b8f608-d2ad-4f7b-807b-db75aa0d10a9",
position: 2,
theme: "Dance Theme",
themeTime: 15,
title: "learn dance steps",
isActive: true,
},
{
id: "d395b047-2847-474a-a553-afbd93782092",
position: 3,
theme: "QA Theme One",
themeTime: 20,
title: "QA testing",
isActive: true,
},
],
},
],
};
},
mounted() {
this.getWeekScheduleList();
},
methods: {
getWeekScheduleList: async function() {
try {
var api_data = this.api_data;
var total_days = 5;
// Sort the api data by day's name first
api_data.sort(function(a, b) {
return a.dayName.localeCompare(b.dayName);
});
// Find the item which has maximum weedays
let max_weekday_item = this.api_data.find((item) =>
Math.max(item.weekDay.length)
);
// Outer loop for row - API data
for (
let rowIndex = 0; rowIndex < max_weekday_item.weekDay.length; rowIndex++
) {
const row = {};
// Inner loop for column
for (let colIndex = 1; colIndex <= total_days; colIndex++) {
// Find the item of respective day number
let day_item = this.api_data.find((item) => {
return item.dayName === `DAY ${colIndex}`;
});
/**
* If found then assign like this-
* row['DAY 1'] = Day 1's weekday data
* row['DAY 2'] = Day 2's weekday data
*/
if (day_item) {
row[`DAY ${colIndex}`] = day_item.weekDay[rowIndex] ?
`${day_item.weekDay[rowIndex].theme} - ${day_item.weekDay[rowIndex].themeTime} mins - ${day_item.weekDay[rowIndex].title}` :
"";
}
// Else leave it empty
else {
row[`DAY ${colIndex}`] = "";
}
}
// Push this row's data in the array
this.weekScheduleList.push(row);
}
} catch (e) {
console.error(e);
}
},
},
})
</script>
</body>
</html>

Related

SAPUI5 line chart returning weird output

I am using northwind oData model and using the "SummaryByYear" model to create a line chart. The data looks as follows (for easier representation, only 4 entries are shown):
{
"results": [
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10248)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-16T00:00:00.000Z",
"OrderID": 10248,
"Subtotal": "440.00"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10249)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-10T00:00:00.000Z",
"OrderID": 10249,
"Subtotal": "1863.40"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10250)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-12T00:00:00.000Z",
"OrderID": 10250,
"Subtotal": "1552.60"
},
{
"__metadata": {
"uri": "https://services.odata.org/V2/Northwind/Northwind.svc/Summary_of_Sales_by_Years(10251)",
"type": "NorthwindModel.Summary_of_Sales_by_Year"
},
"ShippedDate": "1996-07-15T00:00:00.000Z",
"OrderID": 10251,
"Subtotal": "654.06"
}
]
}
following is the XML view for Chart:
<chart:ChartContainer id="chartContainer" showFullScreen="true" showZoom="false" title="Sales Summary (by Year)">
<chart:ChartContainerContent>
<chart:content>
<viz:VizFrame id="lineChart" width="auto" uiConfig="{applicationSet:'fiori'}">
</viz:VizFrame>
</chart:content>
</chart:ChartContainerContent>
</chart:ChartContainer>
and this is the controlles onInit function:
onInit: function () {
var northwind = this.getOwnerComponent().getModel("northwind");
var that = this;
northwind.read("/Summary_of_Sales_by_Years", {
method: "GET",
success: function (resp) {
resp["results"].forEach(item => {
item.Subtotal = item.Subtotal.toString().slice(0, -2)
});
var summaryByYear = new JSONModel({
"results": resp["results"]
})
var lineChart = that.getView().byId("lineChart");
lineChart.setVizType('line');
lineChart.setUiConfig({
applicationSet: 'fiori',
});
var oDataset = new FlattenedDataset({
dimensions: [{
axis: 1,
name: 'Year',
value: '{ShippedDate}',
datatype: "date"
}, ],
measures: [{
name: 'Subtotal',
value: '{Subtotal}',
}],
data: {
path: '/results',
},
});
lineChart.setDataset(oDataset);
lineChart.setModel(summaryByYear);
var feedValueAxis = new FeedItem({
uid: 'valueAxis',
type: 'Measure',
values: ['Subtotal'],
}),
feedCategoryAxis = new FeedItem({
uid: 'categoryAxis',
type: 'Dimension',
values: ['Year'],
});
lineChart.addFeed(feedValueAxis);
lineChart.addFeed(feedCategoryAxis);
lineChart.setVizProperties({
general: {
layout: {
padding: 0.04,
},
},
plotArea: {
window: {
start: 'firstDataPoint',
end: 'lastDataPoint'
}
},
valueAxis: {
label: {
formatString: 'axisFormat',
},
title: {
visible: false,
},
},
categoryAxis: {
title: {
visible: false,
},
},
plotArea: {
dataLabel: {
visible: true,
formatString: 'datalabelFormat',
style: {
color: null,
},
},
},
legend: {
title: {
visible: false,
},
},
title: {
visible: false,
text: 'Summary of Sales (by year)',
},
levels: ['month', 'day', 'year'],
interval: {
unit: ''
}
});
}
});
}
following is the result:
I am getting the date in raw timestamp format instead of year and month and also there are weird texts such as "5atalabelfor9at". What am I doing wrong here and please point me to the correct docs if I am missing some kind of config, thanks.

Onclick event on q-table stop working after passing props to template

I got this table I want to color each row in a color depending on my data.
This works but seems to disable my onclick event in q-table for some reason.
#row-click="onRowClick"
I cannot figure out why this is happening. Im new to quasar and to be honest Im not 100% sure how this referens works
v-slot:body="props"
Eventually I want this to be a router event taking me to a different page on click.
<div id="q-app">
<div class="q-pa-md">
<q-table
:data="data"
:columns="columns"
row-key="id"
:filter="filter"
:loading="loading"
:rows-per-page-options="[5]"
#row-click="onRowClick"
>
<!-- If I remove the template here the onRowClick works -->
<template v-slot:body="props">
<q-tr :props="props" :class="tableFormat(props.row)">
<q-td v-for="col in props.cols" :key="col.name" :props="props">{{
col.value
}}</q-td>
</q-tr>
</template>
</q-table>
</div>
</div>
CSS:
.marked-row {
background-color: green;
}
.unmarked-row {
background-color: blue;
}
new Vue({
el: '#q-app',
data () {
return {
loading: false,
filter: "",
rowCount: 10,
columns: [
{
name: "name",
required: true,
label: "Name",
align: "left",
field: "name",
// format: val => `${val}`,
sortable: true
// style: 'width: 500px'
},
{
name: "age",
required: true,
label: "Age",
align: "left",
field: "age",
format: val => `${val}`,
sortable: true
},
{
name: "location",
required: true,
label: "Location",
align: "left",
field: "location",
format: val => `${val}`,
sortable: true
}
],
data: [
{
id: 1,
name: "Diana",
age: 5,
location: "Mumbai",
color: "blue"
},
{
id: 2,
name: "Billy",
age: 4,
location: "Detroit",
color: "green"
},
{
id: 3,
name: "Mimmi",
age: 3,
location: "New York",
color: "green"
},
{
id: 4,
name: "Bengan",
age: 4,
location: "Dubai",
color: "blue"
},
{
id: 5,
name: "Chloe",
age: 7,
location: "Paris",
color: "green"
},
{
id: 6,
name: "Ben",
age: 6,
location: "Los Angeles",
color: "blue"
}
]
}
},
methods: {
tableFormat(val) {
console.log(val)
if (val.color === "blue") {
return "marked-row";
} else {
return "unmarked-row";
}
},
onRowClick(evt, row) {
console.log("clicked on ", row );
}
}
})
Here is my pen:
https://codepen.io/haangglide/pen/MWeRaJW
Doc says
Emitted when user clicks/taps on a row; Is not emitted when using body/row/item scoped slots
So you can use #click event on q-tr
codepen - https://codepen.io/Pratik__007/pen/oNLOogY

How to add HTML to the panel title in amchart

How to add HTML to the panel title in amchart. I tried adding HTML for title but its rendering as HTML code only.
Here is the DEMO.
Here is the JavaScript code:
var chartData1 = [];
var chartData2 = [];
generateChartData();
function generateChartData() {
var firstDate = new Date();
firstDate.setDate(firstDate.getDate() - 500);
firstDate.setHours(0, 0, 0, 0);
for (var i = 0; i < 500; i++) {
var newDate = new Date(firstDate);
newDate.setDate(newDate.getDate() + i);
var a1 = Math.round(Math.random() * (40 + i)) + 100 + i;
var a2 = -1 * Math.round(Math.random() * (100 + i)) + 200 + i;
chartData1.push({
date: newDate,
value: a1
});
chartData2.push({
date: newDate,
value: a2
});
}
}
AmCharts.makeChart("chartdiv", {
type: "stock",
dataSets: [{
title: "first data set",
fieldMappings: [{
fromField: "value",
toField: "value"
}],
dataProvider: chartData1,
categoryField: "date"
},
{
title: "second data set",
fieldMappings: [{
fromField: "value",
toField: "value2"
}],
dataProvider: chartData2,
categoryField: "date",
compared: true
}
],
panels: [{
showCategoryAxis: false,
title: "<span>Hello</span>",
recalculateToPercents: "never",
stockGraphs: [{
id: "g1",
valueField: "value",
comparable: true
}],
stockLegend: {
}
}, {
showCategoryAxis: true,
title: "Data set #2",
recalculateToPercents: "never",
stockGraphs: [{
id: "g2",
valueField: "value2",
compareField: "value2",
comparable: true,
visibleInLegend: false
}],
stockLegend: {
}
}
],
chartScrollbarSettings: {
graph: "g1"
},
chartCursorSettings: {
valueBalloonsEnabled: true,
cursorColor: '#000000',
cursorAlpha:0.1
},
periodSelector: {
periods: [{
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}]
}
});
It only supports text. Depending on what you need, you can try styling it directly using css by setting addClassNames to true in your chart using the generated CSS classes. For example, to change the color of the first panel's legend title:
.amcharts-stock-panel-div-stockPanel0 .amcharts-legend-title {
fill: #ee0000;
}
Demo

Kendo grid datasource

I know what i am asking about is weird but, I have a grid that contains 8 rows. And one of its column has dropDownListEditor. I wanna ask, Is there any possiblity to set a unique datasource in each row for the drop down list editor.
Below is my case, e.g.
Row 1 contains
[{ "ID": 1, "Fruit": "Banana" },
{ "ID": 2, "Fruit": "Mango" },
{ "ID": 3, "Fruit": "Apple" }]
as datasource
Now i want the 2nd row to contain the following datasource for dropdown
[{ "ID": 1, "Fruit": "Guava" },
{ "ID": 2, "Fruit": "Lichi" }]
Is it possible?
Hello #Nathan i have created a grid as follows,
<div id="example" ng-app="KendoDemos">
<div ng-controller="MyCtrl">
<kendo-grid options="mainGridOptions"></kendo-grid>
</div>
</div>
Now written the following code in controller
angular.module("KendoDemos", ["kendo.directives"]).controller("MyCtrl", function ($scope, $compile) {
var source = [
{CategoryID: 1, CategoryName: "Beverages"},
{CategoryID: 2, CategoryName: "Condiments"},
{CategoryID: 3, CategoryName: "Coffee"},
{CategoryID: 4, CategoryName: "Bread"},
{CategoryID: 5, CategoryName: "Green Tea"},
{CategoryID: 6, CategoryName: "Expresso"}
];
$scope.dataSource = new kendo.data.DataSource({
pageSize: 20,
data: products,
autoSync: true,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: {editable: false, nullable: true},
ProductName: {validation: {required: true}},
UnitPrice: {type: "number", validation: {required: true, min: 1}}
}
}
}
});
$scope.ddlDataSource = new kendo.data.DataSource({type: "odata", data: source});
$scope.categoryDropDownEditor = function (container, options) {
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'CategoryName\'" k-data-value-field="\'CategoryID\'" k-data-source="ddlDataSource" data-bind="value:' + options.field + '"/>').appendTo(container);
};
$scope.mainGridOptions = {
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [{field: "ProductName", title: "Product Name"}, {
field: "Category",
title: "Category",
width: "180px",
editor: $scope.categoryDropDownEditor,
template: "#=Category.CategoryName#"
}, {field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px"}, {
command: "destroy",
title: " ",
width: "150px"
}],
editable: true
};
});
Now you can see in the link [dojo.telerik.com/erImu/2], the list contains Beverages, Condiments etc in all the rows. I want it to contain in only first row, otherwise it must contain TEA only.

Kendo Grid filter to use combo box with column.values rather than drop down list

I'm trying to get Kendo's Grid to show a filter using a combo box rather than a drop down list when used with values. What I mean is, on the grid columns array, each column can be given a list of values (objects with text and value properties) for each possible entry in the database, thereby rather than showing a code, it shows a recognisable name or text instead of the code. The problem is that whenever I specify values against the column, the filter reverts to a fixed list of criteria and a drop-down list, which I don't want.
See an example of what I mean here. What I'd like to see is the filter (on the Category column) to show a combo-box rather than a drop down list, but still use the values against the codes in the table to show in the data in the grid, but it doesn't seem to work.
As you say it doesn't work with the values property, so one approach would be to set up a custom row template and use a lookup function on category ID and replace it with the corresponding text:
var categories = [{
"value": 1,
"text": "Beverages"
}, {
"value": 2,
"text": "Condiments"
}, {
"value": 3,
"text": "Confections"
}, {
"value": 4,
"text": "Dairy Products"
}, {
"value": 5,
"text": "Grains/Cereals"
}, {
"value": 6,
"text": "Meat/Poultry"
}, {
"value": 7,
"text": "Produce"
}, {
"value": 8,
"text": "Seafood"
}];
function getCategory(catID) {
return $.grep(categories, function(n, i) {
return n.value === catID;
})[0].text;
}
$(document).ready(function() {
var dataSource = new kendo.data.DataSource({
pageSize: 20,
data: products,
autoSync: true,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: {
editable: false,
nullable: true
},
ProductName: {
validation: {
required: true
}
},
CategoryID: {
field: "CategoryID",
type: "number",
defaultValue: 1
},
UnitPrice: {
type: "number",
validation: {
required: true,
min: 1
}
}
}
}
}
});
var rowTemplateString = '<tr data-uid="#: uid #">' +
'<td>#: ProductName #</td>' +
'<td>#: getCategory(CategoryID) #</td>' +
'<td>#: UnitPrice #</td>' + '<td></td>' +
'</tr>';
var altRowTemplateString = rowTemplateString.replace('tr class="', 'tr class="k-alt ');
var commonSettings = {
dataSource: dataSource,
filterable: true,
groupable: true,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [{
field: "ProductName",
title: "Product Name"
},
{
field: "CategoryID",
width: "150px",
//values: categories,
dataTextField: "text",
dataValueField: "value",
dataSource: categories,
filterable: {
ui: function(element) {
element.kendoComboBox({
dataTextField: "text",
dataValueField: "value",
dataSource: categories
});
}
},
title: "Category"
},
{
field: "UnitPrice",
title: "Unit Price",
format: "{0:c}",
width: "150px"
},
{
command: "destroy",
title: " ",
width: "110px"
}
],
editable: true
};
$("#grid").kendoGrid($.extend({
rowTemplate: rowTemplateString,
altRowTemplate: altRowTemplateString
}, commonSettings));
});
Note: In this demo I haven't tried to handle the template for the Delete column. I just left it blank.
Here's the Dojo http://dojo.telerik.com/oFulu
Try this One,According to your demo here
</script>
<div id="example" class="k-content">
<div id="grid"></div>
<script>
var categories = [{
"value": 1,
"text": "Beverages"
},{
"value": 2,
"text": "Condiments"
},{
"value": 3,
"text": "Confections"
},{
"value": 4,
"text": "Dairy Products"
},{
"value": 5,
"text": "Grains/Cereals"
},{
"value": 6,
"text": "Meat/Poultry"
},{
"value": 7,
"text": "Produce"
},{
"value": 8,
"text": "Seafood"
}];
$(document).ready(function () {
var dataSource = new kendo.data.DataSource({
pageSize: 20,
data: products,
autoSync: true,
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true} },
CategoryID: { field: "CategoryID", type: "number", defaultValue: 1 },
UnitPrice: { type: "number", validation: { required: true, min: 1} }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
filterable: true,
groupable: true,
pageable: true,
height: 430,
toolbar: ["create"],
columns: [
{ field: "ProductName", title: "Product Name" },
{
field: "CategoryID",
width: "150px",
values: categories,
editor:function(container,options)
{
$('<input name-"' + options.fields +'"/>').
appendTo(container).kendoComboBox({
autoBind:false,
dataTextField:"text",
dataValueFiled:"value",
dataSource:new kendo.data.DataSource({
schema:{
model:{
id:"value",
fields:{
text:{},
value:{}
}
}
},
data:categories
})
})
},
title: "Category"
},
{ field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "150px" },
{ command: "destroy", title: " ", width: "110px"}],
editable: true
});
});
</script>

Categories