Polymer Template Repeat Over Multiple Charts - javascript

I have a polymer highcharts element that works:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="bar-chart" attributes="source">
<template>
<div id="container" style="max-width: 600px; height: 360px;"></div>
</template>
<script>
Polymer("bar-chart", {
ready: function() {
var options = {
chart: {type: 'bar', renderTo: this.$.container},
title: {text: ''},
subtitle: {text: ''},
xAxis: {categories: []},
yAxis: {title: {text: ''}},
plotOptions: {bar: {dataLabels: {enabled: true}}},
legend: {enabled: false},
credits: {enabled: false},
series: [{}]
};
$.getJSON(this.source).done(function(chartjson) {
options.xAxis.categories = chartjson.categories;
options.series[0].data = chartjson.series;
options.title.text = chartjson.title;
options.subtitle.text = chartjson.subtitle;
options.yAxis.title.text = chartjson.yAxistitle;
var chart = new Highcharts.Chart(options);
});
}
});
</script>
</polymer-element>
<bar-chart source="json/grass-roots/2014 Mayor.json"></bar-chart>
I pass it some nice data via the '2014 Mayor.json' file:
{
"categories": ["Muriel E Bowser", "Tommy Wells", "Jack Evans", "Vincent C Gray", "David Catania", "Andy Shallal", "Reta Jo Lewis", "Carol Schwartz", "Vincent Orange", "Christian Carter", "Nestor DJonkam", "Bruce Majors", "Michael L Green"],
"series": [2505, 1654, 1332, 956, 699, 399, 183, 81, 72, 3, 3, 2, 1],
"title": "Mayor (2014)",
"subtitle": "Grassroots Contributors",
"yAxistitle": "Number of DC Residents Contributing to Candidate"
}
And I get a chart.
But what I really want to do is iterate over an array of chart data to produce multiple charts. I've tried very hard to figure out how template repeat works, but I'm new to both Polymer and javascript, and haven't been able to crack it.
Let's say my data file, 'arrayofdata.json' has the following in it:
[
{
"categories": ["Phil Mendelson", "Kris Hammond", "John C Cheeks"], "series": [172, 44, 4],
"title": "Council Chairman (2014)",
"subtitle": "Grassroots Contributors",
"yAxistitle": "Number of DC Residents Contributing to Candidate"
},
{
"categories": ["Muriel E Bowser", "Tommy Wells", "Jack Evans", "Vincent C Gray", "David Catania", "Andy Shallal", "Reta Jo Lewis", "Carol Schwartz", "Vincent Orange", "Christian Carter", "Nestor DJonkam", "Bruce Majors", "Michael L Green"],
"series": [2505, 1654, 1332, 956, 699, 399, 183, 81, 72, 3, 3, 2, 1],
"title": "Mayor (2014)",
"subtitle": "Grassroots Contributors",
"yAxistitle": "Number of DC Residents Contributing to Candidate"
}
]
How do I iterate over that to produce multiple charts using template repeat?

I don't have a solution for Highcharts, but the Polymeric way to do this is to think declaratively. You don't need $.getJSON. You need an element like <google-chart>, that declaratively renders a chart from data and <core-ajax> for fetching the json data.
The whole element definition becomes something like:
<polymer-element name="bar-charts" attributes="source" noscript>
<template>
<core-ajax auto url="{{source}} response="{{items}}" handleAs="json"></core-ajax>
<template repeat="{{item in items}}">
<google-chart type='pie' height='300px' width='400px'
options='{{item.options}}' cols='{{item.cols}}'
rows='{{item.rows}}' data='{{item.data}}'>
</google-chart>
</template>
</template>
</polymer-element>
How wicked is that!? No code :)
The hardest part would be to get the data in the format google-chart expects. See <google-chart> element for examples.

I know it's an old question but here's the updated Polymeric 1.0/2.0 way of doing it, using Highcharts-Chart:
<link rel="import" href="bower_components/highcharts-chart/highcharts-chart.html">
<template is="dom-bind" id="app">
<template is="dom-repeat" items="{{dynamicChartData}}" as="e">
<highcharts-chart index$="[[index]]" type="pie" data="[[zip(e.categories,e.series)]]" title="[[e.title]]" subtitle="[[e.subtitle]]" y-label="[[e.yAxistitle]]"></highcharts-chart>
</template>
<iron-ajax auto url="{{source}}" last-response="{{dynamicChartData}}" handle-as="json"></iron-ajax>
</template>
<script>
var app = document.querySelector("#app")
app.source = "Your URL-------------------"
app.zip = function(a,b) {
return a.map(function (_, i) {return [a[i], b[i]]})
}
</script>
And if you're looking for more examples you can check out http://avdaredevil.github.io/highcharts-chart/.

I don't know much about Polymer, but from the docs it looks like changing <template> to <template repeat="{{ yourarray }}"> might be the critical step in making this happen.

Related

jsreport, dynamic number of charts through jquery

I'm using JSreport 3.4.1. and Chart.js 3.8.0. From a server API I'm getting a series of data to create n. charts. The problem is that the number of charts are never the same (they depend on various parameters in a database).
I cannot create n. static charts for the reason above, so I was trying to dynamically create and inject them in the DOM through jQuery, but I'm having some difficulties:
It successfully creates the first chart, but with incorrect data (like it isn't waiting for the trigger input), and the second chart isn't shown at all.
Any idea on how to create a dynamic number of charts based on the number of objects (inside an array) that arrives through an API?
const datasets = {
"datasets": [{
"dynamic_id": 0,
"NomeAnomalia": "MIT Appoggi",
"GruppiAnomalie": 199,
"anomalyList": [{
"GruppiAnomalie": 199,
"Code": "Classe 1\nApp1",
"Name": "Piastra di base deformata",
"Class": "Classe 1",
"Severity": "0 - Lieve",
"Value": 100
}],
"pieChartData": [{
"severityName": "Lieve",
"severityValue": 100
},
{
"severityName": "Media",
"severityValue": 0
},
{
"severityName": "Forte",
"severityValue": 0
}
]
},
{
"dynamic_id": 1,
"NomeAnomalia": "MIT Impalcati,Travi,Traversi CA CAP",
"GruppiAnomalie": 199,
"anomalyList": [{
"GruppiAnomalie": 199,
"Code": "Classe 1\nApp1",
"Name": "Piastra di base deformata",
"Class": "Classe 1",
"Severity": "0 - Lieve",
"Value": 100
}],
"pieChartData": [{
"severityName": "Lieve",
"severityValue": 100
},
{
"severityName": "Media",
"severityValue": 0
},
{
"severityName": "Forte",
"severityValue": 0
}
]
}
]
}
var content = document.getElementById('content');
for (dataset of datasets.datasets) {
var divPieChart = `
<div class="row">
<div class="col-sm-12">
<div class="chart-container">
<canvas id="bar_chart_${dataset.dynamic_id}"></canvas>
</div>
</div>
</div>`;
content.innerHTML += divPieChart;
var bar_chart_ctx = document.getElementById(`bar_chart_${dataset.dynamic_id}`).getContext('2d');
var bar_chart = new Chart(bar_chart_ctx, {
type: 'bar',
data: {
labels: [1, 2, 3],
datasets: [{
"label": "2017",
"data": [5, 3, 7.5],
"backgroundColor": ["rgba(215, 221, 234)"]
}]
},
options: {
maintainAspectRatio: false,
devicePixelRatio: 1.5,
plugins: {
legend: {
display: true,
position: "top"
}
},
scales: {
y: {
beginAtZero: true
}
},
animation: {
onComplete: function() {
// set the PDF printing trigger when the animation is done
// to have this working, the chrome-pdf menu in the left must
// have the wait for printing trigger option selected
window.JSREPORT_READY_TO_START = true
}
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#2.0.0"></script>
<div id="test"></div>
<div id="content"></div>
I've set a playground with mock data (not really needed cause I've put static data inside the charts) so you can see what I mean:
playground test
Thank you
EDIT
I figured out how to do it (JSReport specifically): in JSReport, window.JSREPORT_READY_TO_START = true tells the report that all the components in the page are done to print. Breaking down the "creation" of the html and the "creation" of the charts into two separates loop, using the length of the dataset as control, makes the work (only JSReport, I won't post a snippet cause it won't work the same as window.JSREPORT_READY_TO_START = true is not present).
Here's the playground if someone needs it: playground test

React select with nested data

I am trying to make a nested select optgroup and tried the following,
const data = [
{
sectorId: 5,
sectorName: "Sector One",
departments: [
{
deptName: "Production",
jobtitles: [
{
JobTitleID: 167,
DepartmentID: 51,
JobName: "Production Manager",
Deleted: false,
SortOrder: 5
},
{
JobTitleID: 178,
DepartmentID: 51,
JobName: "Production Supervisor",
Deleted: false,
SortOrder: 3
},
{
JobTitleID: 449,
DepartmentID: 51,
JobName: "Senior Wall Panel Designer",
Deleted: false,
SortOrder: 15
}
]
},
{
deptName: "Design/Engineering",
jobtitles: [
{
JobTitleID: 294,
DepartmentID: 52,
JobName: "Senior Truss Designer",
Deleted: false,
SortOrder: 5
}
]
}
]
},
{
sectorId: 24,
sectorName: "Sector Two",
departments: [
{
deptName: "Consulting",
jobtitles: [
{
JobTitleID: 191,
DepartmentID: 92,
JobName: "Saw Shop Supervisor",
Deleted: false,
SortOrder: 1
},
{
JobTitleID: 474,
DepartmentID: 92,
JobName: "Senior Truss Designer - Part Time",
Deleted: false,
SortOrder: 11
}
]
},
{
deptName: "Administration",
jobtitles: [
{
JobTitleID: 461,
DepartmentID: 114,
JobName: "Sawyer",
Deleted: false,
SortOrder: 7
},
{
JobTitleID: 278,
DepartmentID: 114,
JobName: "Service Manager",
Deleted: false,
SortOrder: 2
}
]
}
]
}
];
const App = () => {
return (
<select>
{data.map((levelOne, i) => (
<optgroup label={levelOne.sectorName} key={i}>
{levelOne.departments.map((levelTwo, j) => (
<optgroup label={levelTwo.deptName} key={j}>
{levelTwo.jobtitles.map((job, l) => (
<>
<option key={job.JobTitleID} value={job.JobTitleID}>
{job.JobName}
</option>
</>
))}
</optgroup>
))}
</optgroup>
))}
</select>
);
};
render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"> </div>
Sorry the above snippet has errors and you can also look at the working example here
This doesn't provide nested group of data and it stops with single level itself.
Current output:
Sector One
Sector Two
Expected output:
Sector One
Production
-> Production Manager
-> Production Supervisor
-> Senior Wall Panel Designer
Design/Engineering
-> Senior Truss Designer
Sector Two
Consulting
-> Saw Shop Supervisor
-> Senior Truss Designer - Part Time
Administration
-> Sawyer
-> Service Manager
Here only the jobtitles will be option, so as per the above data, the list that has -> will alone be option and others will be label.
So only using optgroup I have tried the above code, But don't know what mistake I am doing which results in not populating the data as per the expected result.
Kindly please help me to solve the above issue and make the above example work as like the expected output.
Adding any other react based library to achieve this also welcomed.
optgroup may not be nested, so only the sectorName is displayed;
you can try to use the react-selector library. Here is an example react-select nested groups that I've found with nested levels.

Highcharts.js different structure of input data

I have a simple Highcharts pie chart that takes the following data as input:
data: [
{"y":4, "name":"Russia", "txt": "Our hotel at the countryside was very nice and welcoming."},
{"y":2, "name":"Australia", "txt": "The trip to Ayers Rock was one of the highlights of our trip. The Great Barrier Reef and its clear water were simply amazing!"},
{"y":1, "name":"Argentina", "txt": "It has been a childhood dream to just go into the wild."},
{"y":4, "name":"China", "txt": "in year 1930 it was this is just a silly simple text to check if everything here is working."},
{"y":2, "name":"Neverland", "txt": "in year 1940 it was like this."},
{"y":4, "name":"Mars", "txt": "in year 1900 it was like this."}
]
Example:
$(document).ready(function() {
//var colors = ['#8d62a0', '#ceb3d8', '#d5dddd'];
Highcharts.getOptions().plotOptions.pie.colors = (function () {
var colors = [],
base = '#801a00',
i;
for (i = 0; i < 100; i += 1) {
colors.push(Highcharts.Color(base).brighten((i - 3) / 15).get());
}
return colors;
}());
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie'
},
tooltip: {
formatter: function() {
return '<b>'+this.point.name+'</b>';
}
},
legend: {
enabled: false
},
plotOptions: {
pie: {
innerSize: '75%'
},
series: {
cursor: 'pointer',
point: {
events: {
click: function(){
defineInnerData(this.y, this.txt, this);
},
}
},
states: {
hover: {
enabled: false
}
}
}
},
yAxis: {
title: {
text: null
},
labels: {
enabled: false
}
},
series: [{
dataLabels: {
enabled: false
},
data: [
{"y":4, "name":"Russia", "txt": "Our hotel at the countryside was very nice and welcoming."},
{"y":2, "name":"Australia", "txt": "The trip to Ayers Rock was one of the highlights of our trip. The Great Barrier Reef and its clear water were simply amazing!"},
{"y":1, "name":"Argentina", "txt": "It has been a childhood dream to just go into the wild."},
{"y":4, "name":"China", "txt": "in year 1930 it was this is just a silly simple text to check if everything here is working."},
{"y":2, "name":"Neverland", "txt": "in year 1940 it was like this."},
{"y":4, "name":"Mars", "txt": "in year 1900 it was like this."}
]
}]
});
function defineInnerData(name, y, obj) { // on complete
var chart=$("#container").highcharts();
$( "#pieChartInfoText" ).remove();
var textX = chart.plotLeft + (chart.plotWidth * 0.5);
var textY = chart.plotTop + (chart.plotHeight * 0.5);
var span = '<span id="pieChartInfoText" style="position:absolute; text-align:block;left: 235px;top:210px;width: 150px; height: 180px; overflow: scroll;">';
span += '<span style="font-size: 11px">'+ y +'</span><br>';
span += '</span>';
$("#addText").append(span);
span = $('#pieChartInfoText');
span.css('left', textX + (span.width() * -0.5));
span.css('top', textY + (span.height() * -0.5));
span.css('overflow', 'auto');
}
defineInnerData("", "Click on the slices to see the text");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div>
<div id="container" style="position:absolute; left:0px; top:0px;"></div>
<div id="addText" style="position:absolute; left:0px; top:0px;"></div>
</div>
<script src="testfile_highcharts.js"></script>
</body>
</html>
My question now is: How would I read data as input that comes in a different structure like the json code below (its geoJSON), where I would like to get the following values as input for my chart:
The tooltip should show the name of the country (which corresponds to properties.name in the geoJSON).
The number of slices corresponds to the value of data.features.articles (which in turn corresponds to the number of sentences in data.features.text).
When clicking on a slice the corresponding sentence (from data.features.text) should be displayed in the center of the circle.
Here is how the geoJSON data looks like:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 4,
"properties": {
"id": 4,
"name": "Thailand",
"lat": "13.7538929",
"lon": "100.8160803",
"2005": 14
},
"geometry": {
"type": "Point",
"coordinates": [
"100.8160803",
"13.7538929"
]
},
"text": ["The official reason given was that he wanted to give the Thai people time to mourn his father before he became king.", "Thailand has rarely had what might be called routine royal successions. The last was 70 years ago, when the young King Ananda was found shot dead in his bedroom in still unexplained circumstances."],
"sentences": "2"
},
{
"type": "Feature",
"id": 7,
"properties": {
"id": 7,
"name": "the United States",
"lat": "38.8949549",
"lon": "-77.0366455",
"2005": 14
},
"geometry": {
"type": "Point",
"coordinates": [
"-77.0366455",
"38.8949549"
]
},
"text": ["The presidential elections will be a hard fight this year", "The best travelling season is September until end of October", "New York City is a must-see when travelling on the East Coast."],
"sentences": "3"
},
{
"type": "Feature",
"id": 8,
"properties": {
"id": 8,
"name": "Greece",
"lat": "37.9841493",
"lon": "23.7279843",
"2005": 14
},
"geometry": {
"type": "Point",
"coordinates": [
"23.7279843",
"37.9841493"
]
},
"text": ["The Aegean islands are little paradise spots not far away from the bustling capital Athens "],
"sentences": "1"
}
]
}
I've tried for hours now to get this working, but I cannot seem to be able to do it. I'm very new to JavaScript and would appreciate every help here. I'm also sorry if the explanation of my problems should not be entirely clear, but I hope that there is someone who can still help me...
The key point to accomplish this is to convert the json structured data to a javascript object in the strucuture you want.
For do this you should iterate over the json object, get the values you want and exports it to the list you're passing to chart.
// The empty list passed to chart
var dataToChart = [];
// Empty object of the list
var dataToChartObject = {"y":0, "name":"", "txt": ""}
// Iterate over jSon to populate dataToChartObject
$.each(jsonObject.features, function(index, value){
dataToChartObject.name = value.properties.name;
dataToChartObject.txt = value.text[0]
// I didn't realize what the articles number is, but do the same logic to get it
// Now let's insert the object to the list
dataToChart.push(dataToChartObject);
});
This can be done in by traversing the JSON object by its properties:
var featureSet = theJSON.features;
var theData = [];
for (var item in featureSet) {
var set = featureSet[item];
for (var theText in set.text) {
var theSlice = {};
theSlice.name = set.properties.name;
theSlice.y = set.text.length;
theSlice.txt = set.text[theText];
theData.push(theSlice);
}
}
Where theJSON is your returned JSON object. From here you modify the chart to use theData.
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie'
},
tooltip: {
formatter: function() {
return '<b>'+this.point.name+'</b>';
}
},
legend: {
enabled: false
},
plotOptions: {
pie: {
innerSize: '75%'
},
series: {
cursor: 'pointer',
point: {
events: {
click: function(){
defineInnerData(this.y, this.txt, this);
},
}
},
states: {
hover: {
enabled: false
}
}
}
},
yAxis: {
title: {
text: null
},
labels: {
enabled: false
}
},
series: [{
dataLabels: {
enabled: false
},
data: theData
}]
});
Sample jsFiddle. Note that your selector on which slice to pick is not happy due to multiple same name/value slices. I would add an index value to each slice and key off of that instead.

Polymer nesting dom-repeat templates multiplicate second template

I follow the Polymer official example of nesting templates and the second template is repeated.
My array data is similar to this:
[
{
"title": "My title book",
"author": "The author",
"votes": [
{ "bad": 0 },
{ "regular": 2 },
{ "good": 201 },
{ "excellent": 458 }
]
},
{
"title": "My title book",
"author":"The author",
"votes": [
{ "bad": 0 },
{ "regular": 2 },
{ "good":201 },
{ "excellent": 458 }
]
}
]
and here is my code of polymer element:
<template is="dom-repeat" items="{{books}}" as="book">
<div><b>Title: </b><span>{{book.title}}</span></div>
<div><b>Author: </b><span>{{book.author}}</span></div>
<div>
<p>Votes:</p>
<template is="dom-repeat" items="{{book.votes}}" as="vote">
<b>Bad: </b><span>{{vote.bad}}</span>
<b>Regular: </b><span>{{vote.regular}}</span>
<b>Good: </b><span>{{vote.good}}</span>
<b>Excellent: </b><span>{{vote.excellent}}</span>
</template>
</div>
</template>
The result of this is:
Title: My book title
Author: My author
Votes:
Bad: 0 Regular: Good: Excellent: Bad: Regular: 2 Good: Excellent: Bad: Regular: Good: 201 Excellent: Bad: Regular: Good: Excellent: 458
Each element in book.votes contains either bad, regular, good, or excellent, but the inner template repeater assumes all voting types are present in each object. That is, the template outputs the tally for all votes in each iteration when only one of those votes is available.
Walking through the four iterations...
The repeater reads book.votes[0] ({"bad": 0}) as vote.
It reads vote.bad and gets a value of 0.
It can't find vote.regular.
It can't find vote.good.
It can't find vote.excellent.
Result:
Bad: 0 Regular: Good: Excellent:
The repeater reads book.votes[1] ({"regular": 2}) as vote.
It can't find vote.bad.
It reads vote.regular and gets a value of 2.
It can't find vote.good.
It can't find vote.excellent.
Result:
Bad: Regular: 2 Good: Excellent:
The repeater reads book.votes[2] ({"good": 201}) as vote.
It can't find vote.bad.
It can't find vote.regular.
It reads vote.good and gets a value of 201.
It can't find vote.excellent.
Result:
Bad: Regular: Good: 201 Excellent:
The repeater reads book.votes[3] ({"excellent": 458}) as vote.
It can't find vote.bad.
It can't find vote.regular.
It can't find vote.good.
It reads vote.excellent and gets a value of 458.
Result:
Bad: Regular: Good: Excellent: 458
If the intention is to show all voting tallies at once, book.votes should be an object instead of an array of objects:
"votes": {
"bad": 0,
"regular": 2,
"good": 201,
"excellent": 458
}
...and the inner template repeater should be removed, binding to book.votes.* directly:
<div>
<b>Bad: </b><span>{{book.votes.bad}}</span>
<b>Regular: </b><span>{{book.votes.regular}}</span>
<b>Good: </b><span>{{book.votes.good}}</span>
<b>Excellent: </b><span>{{book.votes.excellent}}</span>
</div>
<head>
<base href="https://polygit.org/polymer+:master/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-card/paper-card.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<template is="dom-repeat" items="{{books}}" as="book">
<paper-card>
<div><b>Title: </b><span>{{book.title}}</span>
</div>
<div><b>Author: </b><span>{{book.author}}</span>
</div>
<div>
<p>Votes:</p>
<div>
<b>Bad: </b><span>{{book.votes.bad}}</span>
<b>Regular: </b><span>{{book.votes.regular}}</span>
<b>Good: </b><span>{{book.votes.good}}</span>
<b>Excellent: </b><span>{{book.votes.excellent}}</span>
</div>
</div>
</paper-card>
</template>
</template>
<script>
Polymer({
is: 'x-foo',
properties: {
books: {
type: Array,
value: function() {
return [{
"title": "My title book",
"author": "The author",
"votes": {
"bad": 0,
"regular": 2,
"good": 201,
"excellent": 458
}
}, {
"title": "The other book",
"author": "The other author",
"votes": {
"bad": 11,
"regular": 22,
"good": 33,
"excellent": 44
}
}];
}
}
}
});
</script>
</dom-module>
</body>
jsbin before / after

Binding and relationships in OpenUI5

Currently, I am trying to build an interface in OpenUI5, which is supposed to allow managing relationships. The whole application connects to the backend via oData.
Consider the following example: Two entities, "Group" and "Person". Each Group may consist of a number of Persons ("members"). What I'd like to do is to list all the Groups in a table - and for each groups members, I'd like to present a MultiComboBox to select the Persons associated with the group, like so:
Setting up the views is easy, but I have some trouble regarding the bindings. Binding a collection (like "Groups") to a table and binding properties (like "name") to an item is no problem of course, but I have no clue how to bind a collection - which is a child of another collection - to a nested list so to speak.
I don't even know if it is possible at all, especially since I want not only the Persons currently affiliated with a group to show up in the combo box, but all others as well to be able to select them. And of course, I want changes made in the interface to apply to the model as well...
Any hint towards a way to achieve the described functionality is much appreciated!
Two different models are binded to the Table..
YOu can have Groups and Members as entities with navigation property as members
you can play around here
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<title>Mobile App in 23 Seconds Example</title>
<script src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"></script>
<!-- only load the mobile lib "sap.m" and the Blue Crystal theme -->
<script type="text/javascript">
var sampleData = {
"Groups": [
{
"GroupId": "D1",
"GroupName": "Developers",
"Members": []
},
{
"GroupId": "D2",
"GroupName": "GreenDay",
"Members": []
},
{
"GroupId": "D3",
"GroupName": "BackStreet Boys",
"Members": []
},
{
"GroupId": "D4",
"GroupName": "Managers",
"Members": []
}
]
};
var oModel = new sap.ui.model.json.JSONModel(sampleData);
var aData = [
{
key: "A",
text: "John"
},
{
key: "B",
text: "Sachin"
},
{
key: "C",
text: "Dravid"
},
{
key: "D",
text: "David"
},
{
key: "E",
text: "Sunil"
},
{
key: "F",
text: "Ronald"
},
{
key: "G",
text: "Albert"
}
];
var oMulti = new sap.m.MultiComboBox({
selectionChange: function (oEvent) {
//change your group data?
}
});
oMulti.setModel(new sap.ui.model.json.JSONModel(aData));
var oTemplate = new sap.ui.core.Item({
key: "{key}",
text: "{text}",
customData: new sap.ui.core.CustomData({
key: "{GroupId}",
value: "{GroupName}"
})
});
oMulti.bindItems("/", oTemplate);
//Build Table
var oTable = new sap.m.Table({
columns: [
new sap.m.Column({
width: "150px",
header: new sap.m.Label({
text: "Group Name"
})
}),
new sap.m.Column({
header: new sap.m.Label({
text: "Members"
})
})
]
}).placeAt("content");
var oTemplate = new sap.m.ColumnListItem({
cells: [
new sap.m.Label({
text: "{GroupName}"
}),
oMulti
],
press: function (oEvent) {
alert(oEvent.getSource().getBindingContext());
}
});
oTable.setModel(oModel);
oTable.bindItems("/Groups", oTemplate);
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>

Categories