All appointments have a different row (sap.m.PlanningCalendar) - sapui5

I am trying to port my old application with "sap.me.OverlapCalendar" to the new "sap.m.PlanningCalendar", I want to show appointments just for one person. I found a difference in the way the appointments display.
The template I use is:
var oTemplateRow = new sap.m.PlanningCalendarRow("RowTemplate", {
appointments:[
new sap.ui.unified.CalendarAppointment({
startDate: {
path: 'CalendarModel>DateFrom',
formatter: util.Formatter.toStartDate
},
endDate: {
path: 'CalendarModel>DateTo',
formatter: util.Formatter.toEndDate
},
title: "{CalendarModel>CardName} - {CalendarModel>ProjectName}",
text: "Gewerkte uren: {CalendarModel>WorkedHours}",
type: "Type04",
tentative: false,
key: "{CalendarModel>ReportID}"
})]
});
Which is bound to the Calendar control with:
bindAggregation("rows", "CalendarModel>/Items/", oTemplateRow);
The data is showing in the calendar but the way it shows is different.
Old calendar: http://imgur.com/3glZRtT
New calendar: http://imgur.com/snnsWVE
What should I do to get the same output?

You have to change the model: for example, at the root of the model you create an array corresponding to rows of the calendar, and each row should contain an array of appointments.
A sample json file can look like this:
{
"items": [{
"title": "Item1",
"appointments": [{
"text": "appointment1",
"start": "2017-02-17T09:30:00",
"end": "2017-02-17T13:00:00"
}, {
"text": "appointment2",
"start": "2017-02-17T09:45:00",
"end": "2017-02-17T13:10:00"
}]
}, {
"title": "Item2",
"appointments": [{
"text": "appointment3",
"start": "2017-02-17T10:30:00",
"end": "2017-02-17T14:00:00"
}, {
"text": "appointment4",
"start": "2017-02-17T10:45:00",
"end": "2017-02-17T14:10:00"
}]
}]
}
"items" is an array of calendar rows, and each item contains array of appointments. The binding of the control should be more complex. I used such a file a base for JSON model and the controller code looks like this:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("QuickStartApplication.controller.View1", {
onInit: function() {
var oCale = this.getView().byId("PC1");
var oModel = this.getOwnerComponent().getModel("CalendarModel");
this.getView().setModel(oModel, "CalendarModel");
var oTemplateRow = new sap.m.PlanningCalendarRow("RowTemplate", { title: "{CalendarModel>title}" });
oTemplateRow.bindAggregation("appointments", {
path: "CalendarModel>appointments",
template: new sap.ui.unified.CalendarAppointment({
title: "{CalendarModel>text}",
startDate: {
path: "CalendarModel>start",
formatter: this.toDate
},
endDate: {
path: "CalendarModel>end",
formatter: this.toDate
}
}),
templateShareable: true
});
oCale.bindAggregation("rows", {
path: "CalendarModel>/items",
template: oTemplateRow,
templateShareable: true
});
},
toDate: function(sValue) {
if (sValue) {
return new Date(sValue); //
}
}
});
});
Note that first you create a row template and then bind its "appointments" aggregation to the "appointments" property of "CalendarModel" model with template for CalendarAppointment creation. Then you create a binding for calendar rows referring to the row template.

Related

Unable to access control, created in JSView, from controller with View byId

I am trying to display a VizFrame and my data are in a simple JSON format.
Both my view and controller are in JS. (I will start writing my view in XML going forward) because I see that is the way to go.
I get a blank page with the error: "setDataset of undefined". What am I missing?
My view code is this.
createContent: function(oController) {
var oSubHeader = new sap.m.Bar({
contentLeft: [
new sap.m.Button({
icon: "sap-icon://nav-back",
press: [oController.onNavBack, oController]
})
],
contentMiddle: [
new sap.m.Label({
text: "{i18n>app_subhead_2}"
})
]
});
var oVizFrame = new sap.viz.ui5.controls.VizFrame("VizFrameId", {
width: "100%",
height: "400px",
vizType: "line"
});
var oPage = new sap.m.Page({
title: "UI5 Assignment App",
showSubHeader: true,
subHeader: oSubHeader,
content: [oVizFrame]
});
return oPage;
}
My corresponding controller is
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/UIComponent",
"sap/ui/core/routing/History",
"sap/viz/ui5/controls/VizFrame",
"sap/viz/ui5/data/FlattenedDataset"
], function (Controller, UIComponent, History, VizFrame, FlattenedDataset) {
"use strict";
return Controller.extend("Project_Tile_learning.Divya_tile_Project.controller.ProductDetailPage", {
onNavBack: function () {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("homepage", true);
}
},
onInit: function () {
var sampleDatajson = new sap.ui.model.json.JSONModel("json/PA.json");
var oVizFrame = this.getView().byId("VizFrameId");
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
name: "Year",
value: "{Year}"
}],
measures: [{
name: "Supplier",
value: "{Supplier}"
}, {
name: "Liquor",
value: "{Liquor}"
}, {
name: "Quantity",
value: "{Quantity}"
}],
data: {
path: "/items"
}
});
oVizFrame.setDataset(oDataset);
oVizFrame.setModel(sampleDatajson);
var oFeedValueAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Supplier"]
});
var oFeedValueAxis1 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Liquor"]
});
var oFeedValueAxis2 = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "valueAxis",
"type": "Measure",
"values": ["Quantity"]
});
var oFeedCategoryAxis = new sap.viz.ui5.controls.common.feeds.FeedItem({
"uid": "categoryAxis",
"type": "Dimension",
"values": ["Year"]
});
oVizFrame.addFeed(oFeedValueAxis);
oVizFrame.addFeed(oFeedValueAxis1);
oVizFrame.addFeed(oFeedValueAxis2);
oVizFrame.addFeed(oFeedCategoryAxis);
}
});
});
Update: JS View is deprecated since UI5 v1.90. Use Typed View instead.
When creating a control in JS view definition, always use this.createId("myControl").
From the doc:
If you want to define IDs for controls inside a JSView to guarantee their uniqueness [...], you cannot give hardcoded IDs, but have to give the view the opportunity to add its own instance ID as a prefix. This is done by using the View.createId(...) method.
For the example above, this is done as follows:
new sap.viz.ui5.controls.VizFrame(this.createId("VizFrameId"), { /*...*/ });
Then in the controller, myView.byId tries to access the control with view's own ID as a prefix, which will succeed this time since the control has an ID with the view ID as a prefix.

Mongodb pull from array attached to simple schema

I have the following collection attached to aldeed:simple schema
Posts = new Mongo.Collection("posts");
Posts.attachSchema(new SimpleSchema({
samplePost:{
type:String,
max:500
},
createdAt:{
type: Date,
autoValue: function(){
return new Date()
}
},
"comments.$.reply":{
type:String
},
"comments.$.commentId":{
type: String,
autoValue: function(){
var tempCommentId = new Meteor.Colletion.ObjectID();
return tempCommentId.str;
}
},
"comments.$.commentCreatedAt": {
type: Date,
optional: true,
autoValue: function(){
return new Date()
}
},
});
The actual document looks like the following:
{
"_id": "aaa",
"samplePost": "Hello world!",
"comments": [
{
"reply": "Goodbye",
"commentId": "bbb",
"createdAt": "2016-06-19T19:06:17.931Z"
},
{
"reply": "Good morning",
"commentId": "ccc"
"createdAt": "2016-06-19T19:05:17.931Z"
},
]
}
Now im trying to remove only the 2nd comment with commentId:"ccc" from the document with $pull
"click #delete-comment": function(event, template){
var tempCommentId = $(event.target).parent().find('#commentIdPass').text(); //commentId is collected from HTML view
Posts.update(
{_id: template.data._id}, //_id is collected from the url param
{$pull:{
comments: {
commentId: tempCommentId
}}
});
},
and this is not working. I have narrowed down the problem to
"comments.$.commentCreatedAt": {
type: Date,
optional: true,
autoValue: function(){
return new Date()
}
},
schema. If i remove this schema, i can delete the comment.
So, why is this causing a problem of pulling the whole comment item from the array. Any ideas? Any workarounds?
Try This Query:
db.getCollection('Mytest').update({"_id":"aaa"},{"$pull":{"comments":{"commentId":"ccc"}}});
Found the problem. As I have suspected attached schema was the culprit. I needed to set a conditional for inserting and updating a schema with autovalue method. The schema should look as following:
"comments.$.commentCreatedAt": {
type: Date,
autoValue: function () {
if (this.isInsert) {
return new Date;
}
}
},

UI5 Tree Binding to JSON

I have the following JSON file.
"idocs": [
{
"Docnum": "00063463",
"Mestyp": "MATMAS",
"Status": "53",
"Sndprn": "EXTSYS1",
"Direct": "Inbound",
"Message": "Material 00002342 Created",
"messages": [{
"message": "Material 00002342 Created"
}],
"segments": [{
"segment": "E1MARAM",
"fields": [{
"fieldName": "MATNR"
}]
}]
}
I want to bind this to a tree node. I have the following code to "attempt" to do this and it is not doing anything. Not even an error.
var oTree = new sap.ui.commons.Tree("tree")
.placeAt("idViewRoot--idViewDetail--toolBar-content");
oTree.bindAggregation("nodes", tgtPath, function(
sId, oContext) {
alert("stuff");
var treePath = oContext.getPath();
var bindTextName = '';
if (treePath.indexOf("fields") !== -1) {
bindTextName = "fieldName";
} else {
bindTextName = "segment";
}
return new sap.ui.commons.TreeNode()
.bindProperty("text", bindTextName);
});
I would appreciate if someone could take a look and point me in the right direction.
Should I see an alert "stuff" appearing, because I do not even see that. Could it be an issue with the binding.
The value of tgtPath is /idocs/0/segments.
Martin
// data has to be tree structured
var oData = {
root:{
name: "root",
0: {
name: "item1",
0: {
name: "subitem1",
0: {
name: "subsubitem1"
},
1: {
name: "subsubitem2"
}
},
1: {
name: "subitem2",
0: {
name: "subsubitem3"
}
}
},
1:{
name: "item2",
0: {
name: "subitem3"
}
}
}
};
var oModel = new sap.ui.model.json.JSONModel();
// set the data to the model
oModel.setData(oData);
var oTree = new sap.ui.commons.Tree("tree");
oTree.setWidth("100%");
// set the model to the tree
oTree.setModel(oModel);
var oTreeNodeTemplate = new sap.ui.commons.TreeNode("node");
oTreeNodeTemplate.bindProperty("text", "name");
oTreeNodeTemplate.setExpanded(true);
oTree.bindAggregation("nodes", "/root", oTreeNodeTemplate);
oTree.placeAt("body");
Here is sample https://jsbin.com/rexahoquso/edit?html,js,output

SAPUI5: Issue in getting datetime values from HANA db to Chart

I am trying to get the datetime values and aggregated
response time from hana database to a bar chart.
I have done the aggregation in .xsodata file as :
{
service namespace "excercise.services" {
"ABC"."XYZ" as "sample" key generate local "Key"
aggregates always(SUM of "respti" ) ;
}
}
I am getting aggregated response time values but it is not
getting synchronized with the respective date values .
Please help me on getting the correct values.
Here is the view.js file:
{
var oModel = sap.ui.model.odata.ODataModel('.xsodata/', false);
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions: [{
axis: 1,
name: 'Time Instance',
value: {
path: "ts",
formatter: function(fValue) {
jQuery.sap.require("sap.ui.core.format.DateFormat");
var oDateFormat = sap.ui.core.format.DateFormat.getDateTimeInstance();
return oDateFormat.format(new Date(fValue));
}
},
},
],
measures: [{
name: 'Response Time',
value: '{respti}'
}],
data: {
path: "/sample",
filters: [
new sap.ui.model.Filter("inst", sap.ui.model.FilterOperator.EQ, "instance")
],
parameters: {
select: 'ts,respti'
},
}
});
}
you may want to try
dimensions: [{
axis: 1,
name: 'Time Instance',
value: {
path: "ts",
formatter: function(fValue) {
if(fValue){
jQuery.sap.require("sap.ui.core.format.DateFormat");
var oDateFormat = sap.ui.core.format.DateFormat.getDateTimeInstance();
return oDateFormat.format(new Date(fValue));
} else {
return fValue;
}
}
},
}],
what is the format of respti, you may want to format that also, using a D3 formatter maybe simplest way

Kendo DataSource: How to define "Computed" Properties for data read from remote odata source

Situation:
kendo DataSource
var ordersDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: {
url: "http://localhost/odata.svc/Orders?$expand=OrderDetails"
}
},
schema: {
type: "json",
data: function(response){
return response.value;
}
total: function(response){
return response['odata.count'];
}
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
})
the json data read from the odata source is like:
{
odata.metadata: "xxxx",
odata.count: "5",
value: [
{
OrderId: 1,
OrderedDate: "2013-02-20",
OrderInfoA: "Info A",
OrderInfoB: "Info B"
OrderDetails: [
{
OrderDetailId: 6,
OrderDetailInfoC: "Info C",
OrderDetailInfoD: "Info D"
},
{
//Another OrderDetail's data
}
]
},
{
// Another Order's data
}
]
}
Question 1:
1.If I wanna define a "computed" property: OrderedDateRelative, which should be the number of days between Today(2013-02-25) and the Day the Order was Created(2013-02-20), Like: "5 days ago", HOW can i achieve this in the client side?
Answer to Question1: http://jsbin.com/ojomul/7/edit
Question 2 --UPDATE--
2.Every Order has its Nested Property OrderDetails, so is it possible to define a Calculated Field for the Nested OrderDetails Property? Like: OrderDetailInfoCAndD for each OrderDetail, and the value should be something like: OrderDetailInfoC + OrderDetailInfoD, which is "Info C Info D"?
Thanks,
dean
You can create a calculated field by specifying the model of the data source:
dataSource = new kendo.data.DataSource({
data: [
{ first: "John", last: "Doe" },
{ first: "Jane", last: "Doe" }
],
schema: {
model: {
// Calculated field
fullName: function() {
return this.get("first") + " " + this.get("last");
}
}
}
});
Here is a live demo: http://jsbin.com/ojomul/1/edit
Here is a way to use calculated field in Kendo Grid.
var crudServiceBaseUrl = "http://demos.telerik.com/kendo-ui/service",
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "/Products",
dataType: "jsonp"
}
},
pageSize: 20,
schema: {
model: {
total: function (item) {
return this.UnitPrice * this.UnitsInStock;
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 550,
sortable: true,
filterable: true,
toolbar: ["create"],
columns: [
{ field: "UnitPrice", title: "Unit Price"},
{ field: "UnitsInStock", title: "Units In Stock", width: "120px" },
{ field: "total()", title: "Total" }]
});
Below an example to use it in a grid. It can then also sort the column.
$("#grid").kendoGrid({
dataSource: {
data: [
{ first: "John", last: "Doe" },
{ first: "Jane", last: "Doe" }
],
schema: {
model: {
// Calculated field
fullName: function() {
return this.first + " " + this.last;
},
fields: {
first: { type: "string" },
last: { type: "string" }
}
}
}
},
columns: [
{
// Trigger function of the Calculated field
field: "fullName()",
title: "Fullname"
},
{
field: "first",
title: "firstname"
}
]
});