I'm having a problem trying to correct for this. I have created 2 custom Bing map types. The user can change the map type through a custom drop box. When the user changes from Default to Road. A majority of the time if the user changes back to Default, the roads stay. Am I missing something so obvious. I've included my code.
Map Types
var defaultMapColors =
{
"version": "1.0",
"settings":
{
"landColor": "#686868"
},
"elements":
{
"mapElement": { "labelVisible": false },
"area": { "visible": false },
"transportation": { "visible": false },
"countryRegion": { //country
"borderStrokeColor": "#444444",
"borderOutlineColor": "#00000000",
"borderWidthScale": 3,
"fillColor": "#888888",
"visible": true
},
"adminDistrict": { //states
"borderVisible": true,
"borderStrokeColor": "#444444",
"borderOutlineColor": "#00000000",
"borderWidthScale": 3,
"fillColor": "#888888",
},
"water": { "fillColor": "#4E5E6D" },
"point": { "visible": false }
}
};
var defaultMapColorsWithRoads =
{
"version": "1.0",
"settings":
{
"landColor": "#686868"
},
"elements":
{
"mapElement": { "labelVisible": false },
"area": { "visible": false },
"transportation": {
"visible": true,
"strokeColor": "#ffffff",
},
"countryRegion": { //country
"borderStrokeColor": "#444444",
"borderOutlineColor": "#00000000",
"borderWidthScale": 3,
"fillColor": "#888888",
"visible": true
},
"adminDistrict": { //states
"borderVisible": true,
"borderStrokeColor": "#444444",
"borderOutlineColor": "#00000000",
"borderWidthScale": 3,
"fillColor": "#888888",
},
"water": { "fillColor": "#4E5E6D" },
"point": { "visible": false }
}
};
Drop Down
<div class="form-group">
<select id="customNavSelector" class="form-control selectpicker show-tick">
<option value="Default" onclick="map.setView({ mapTypeId: Microsoft.Maps.MapTypeId.road, customMapStyle: defaultMapColors });">Default</option>
<option value="Road" onclick="map.setView({ mapTypeId: Microsoft.Maps.MapTypeId.road, customMapStyle: defaultMapColorsWithRoads });">Road</option>
<option value="Aerial" onclick="map.setView({ mapTypeId: Microsoft.Maps.MapTypeId.aerial, customMapStyle: '' });">Aerial</option>
</select>
</div>
Map Object
map = new Microsoft.Maps.Map(mapDiv,
{
credentials: "#ViewBag.BingMapKey",
center: new Microsoft.Maps.Location(#ConfigurationManager.AppSettings["CenterLatitude"], #ConfigurationManager.AppSettings["CenterLongitude"]),
customMapStyle: defaultMapColors,
mapTypeId: Microsoft.Maps.MapTypeId.road, //grayscale, aerial, road, canvasLight, canvasDark
//liteMode: true,
showMapTypeSelector: false, //set to true to show default bing map selector
disableStreetside: false,
disableStreetsideAutoCoverage: true,
zoom: zoom,
backgroundColor: 'black',
//showBreadcrumb: true,
//showLocateMeButton: locator,
enableInertia: false,
enableClickableLogo: false,
navigationBarMode: Microsoft.Maps.NavigationBarMode.compact //compact, default, minified
});
There is a known issue where setting the map style merges the new style with the old style instead of overwriting it completely. The team plans to fix this. In the mean time, if you dispose the current map and create a new instance of the map with the map style it will work as expected.
Related
I have a problem, that sometimes the controller does not get loaded:
and you can see the error message. It should load the following controller(marked with red border):
Why it is not getting loaded sometimes?
When the controller gets loaded, it looks like:
UPDATE:
I am using flexible column layout.
The App.view.xml looks like:
<mvc:View controllerName="ch.mindustrie.ZMM_CLASSIFICATION.controller.App" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:f="sap.f">
<App id="root">
<f:FlexibleColumnLayout id="idClassLayout"/>
</App>
</mvc:View>
the manifest.json file:
{
"_version": "1.9.0",
"sap.app": {
"id": "ch.mindustrie.ZMM_CLASSIFICATION",
"type": "application",
"i18n": "i18n/i18n.properties",
"applicationVersion": {
"version": "0.1.0"
},
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"sourceTemplate": {
"id": "servicecatalog.connectivityComponentForManifest",
"version": "0.0.0"
},
"dataSources": {
"ZMM_CLASSIFICATION_SRV": {
"uri": "/sap/opu/odata/sap/ZMM_CLASSIFICATION_SRV/",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"localUri": "localService/ZMM_CLASSIFICATION_SRV/metadata.xml"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"icons": {
"icon": "",
"favIcon": "",
"phone": "",
"phone#2": "",
"tablet": "",
"tablet#2": ""
},
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
},
"supportedThemes": [
"sap_hcb",
"sap_belize"
]
},
"sap.ui5": {
"handleValidation": true,
"rootView": {
"viewName": "ch.mindustrie.ZMM_CLASSIFICATION.view.App",
"type": "XML",
"async": true,
"id": "app"
},
"dependencies": {
"minUI5Version": "1.50.0",
"libs": {
"sap.ui.layout": {},
"sap.ui.core": {},
"sap.m": {},
"sap.f": {},
"sap.collaboration": {
"lazy": true
}
}
},
"contentDensities": {
"compact": true,
"cozy": true
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "ch.mindustrie.ZMM_CLASSIFICATION.i18n.i18n"
}
},
"Classification": {
"uri": "/sap/opu/odata/sap/ZMM_CLASSIFICATION_SRV/",
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Server",
"defaultBindingMode": "OneWay",
"defaultCountMode": "Request"
},
"dataSource": "ZMM_CLASSIFICATION_SRV",
"preload": true
}
},
"resources": {
"css": [
{
"uri": "css/style.css"
}
]
},
"routing": {
"config": {
"routerClass": "sap.f.routing.Router",
"viewType": "XML",
"viewPath": "ch.mindustrie.ZMM_CLASSIFICATION.view",
"controlId": "idClassLayout",
"bypassed": {
"target": [
"search",
"characteristic"
]
},
"async": true
},
"routes": [
{
"pattern": "",
"name": "search",
"target": [
"characteristic",
"search"
],
"layout": "TwoColumnsBeginExpanded"
},
{
"pattern": "search/{internalclassnum}",
"name": "characteristic",
"target": [
"search",
"characteristic"
],
"layout": "TwoColumnsMidExpanded"
}
],
"targets": {
"search": {
"viewName": "Search",
"viewLevel": 1,
"viewId": "search",
"controlAggregation": "beginColumnPages"
},
"characteristic": {
"viewName": "Characteristic",
"viewLevel": 2,
"viewId": "characteristic",
"controlAggregation": "endColumnPages"
}
}
}
},
"sap.platform.abap": {
"uri": "/sap/bc/ui5_ui5/sap/zmm_classifi/webapp",
"_version": "1.1.0"
}
}
the Search.view.xml:
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:l="sap.ui.layout" xmlns:uxap="sap.uxap"
xmlns:f="sap.ui.layout.form" xmlns:smartFilterBar="sap.ui.comp.smartfilterbar"
controllerName="ch.mindustrie.ZMM_CLASSIFICATION.controller.Search" xmlns:html="http://www.w3.org/1999/xhtml">
<smartFilterBar:SmartFilterBar id="SelectionFilterBar" entitySet="ZMM_C_CLASSIFICATION" search="onSearchClass">
<smartFilterBar:controlConfiguration>
<smartFilterBar:ControlConfiguration key="ClassType" visibleInAdvancedArea="true" preventInitialDataFetchInValueHelpDialog="false"></smartFilterBar:ControlConfiguration>
<smartFilterBar:ControlConfiguration key="ClassNum" visibleInAdvancedArea="true" preventInitialDataFetchInValueHelpDialog="false"></smartFilterBar:ControlConfiguration>
</smartFilterBar:controlConfiguration>
</smartFilterBar:SmartFilterBar>
<Tree id="ClassTree" items="{path: 'Tree>/'}" toggleOpenState="onOpenAnItemOnTree">
<CustomTreeItem>
<FlexBox width="100%" alignItems="Center" justifyContent="SpaceBetween">
<items>
<Label text="{Tree>text}" wrapping="true"/>
<Button icon="sap-icon://display" type="Transparent" press="onClassPressed"/>
</items>
</FlexBox>
</CustomTreeItem>
</Tree>
</mvc:View>
And the Search.Controller
sap.ui.define([
"ch/mindustrie/ZMM_CLASSIFICATION/controller/BaseController"
], function (BaseController) {
"use strict";
return BaseController.extend("ch.mindustrie.ZMM_CLASSIFICATION.controller.Search", {
/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* #memberOf ch.mindustrie.ZMM_CLASSIFICATION.view.Search
*/
onInit: function () {
//Set model for smart filter bar
const oModel = this.getModel("Classification");
this.setModel(oModel);
//Model for classification tree
this.setModel(new sap.ui.model.json.JSONModel(), "Tree");
},
onSearchClass: function () {
const aFilter = this.byId("SelectionFilterBar").getFilters();
const self = this;
//Build the first node
this._readClassification(aFilter)
.then(aData => self.getModel("Tree").setProperty("/", aData));
},
/*
* Read classification from server.
*/
_readClassification: function (aFilter) {
const self = this;
//Build entry node
const oModel = this.getModel("Classification");
const oDateFrom = new sap.ui.model.Filter({
path: "ValidFrom",
operator: sap.ui.model.FilterOperator.LE,
value1: new Date()
});
const oDateUntil = new sap.ui.model.Filter({
path: "ValidFrom",
operator: sap.ui.model.FilterOperator.GE,
value1: new Date()
});
return new Promise((resolve, reject) => {
oModel
.read("/ZMM_C_CLASSIFICATION", {
filters: aFilter.concat([oDateFrom, oDateUntil]),
success: function (oData) {
let aTreeWithNodes = [];
const aTree = oData.results.map(self._buildEntryTree);
aTree.forEach((oNode, index) => {
self._readSubClasses(oNode.internalClass)
.then(aData => {
const oWithNodes = aTree[index];
if (aData.length > 0) {
oWithNodes.nodes = aData;
}
aTreeWithNodes.push(oWithNodes);
if (aTreeWithNodes.length === aTree.length) {
resolve(aTreeWithNodes);
}
});
});
},
error: function (oError) {
reject(oError);
}
});
});
},
_readSubClasses: function (sSubInternalClass) {
const oModel = this.getModel("Classification");
const self = this;
const oUpInteralClass = new sap.ui.model.Filter({
path: "UpInternalClass",
operator: sap.ui.model.FilterOperator.EQ,
value1: sSubInternalClass
});
return new Promise((resolve) => {
oModel
.read("/ZMM_C_CLASSSUB_REL", {
filters: [oUpInteralClass],
success: function (oData) {
const aNewNodes = (oData.results.length > 0 ? oData.results.map(self._prepareDescEntryNodes) : []);
resolve(aNewNodes);
},
error: function () {
resolve([]);
}
});
});
},
/*
* Build the entry node.
*/
_buildEntryTree: function (oData) {
return {
text: oData.ClassType + " " + oData.ClassNum + " " + oData.ClassNumDescr,
classType: oData.ClassType,
classNum: oData.ClassNum,
internalClass: oData.InternalClass,
nodes: []
};
},
onOpenAnItemOnTree: function (oEvent) {
const bExpanded = oEvent.getParameter("expanded");
if (!bExpanded) {
return;
}
const iItemIndex = oEvent.getParameter("itemIndex");
const oItemContext = oEvent.getParameter("itemContext");
const oTree = this.byId("ClassTree");
const oModel = this.getView().getModel("Tree");
const sPath = oItemContext.getPath();
const oCurrentNode = oModel.getProperty(sPath);
this._loadOnDemand(oModel, oCurrentNode, sPath, oTree.getItems()[iItemIndex].getLevel());
},
/*
* Load descendants asynchronously.
*/
_loadOnDemand: function (oModel, oCurrentNode, sPath) {
const aChildNodes = oCurrentNode.nodes.map(oClass => {
return new sap.ui.model.Filter({
path: "InternalClass",
operator: sap.ui.model.FilterOperator.EQ,
value1: oClass.internalClass
});
});
this._readClassification(aChildNodes)
.then(aNewNodes => oModel.setProperty(sPath + "/nodes", aNewNodes));
},
/*
* When the item in the tree is getting pressed.
*/
onClassPressed: function (oEvent) {
const oRow = oEvent.getSource().getBindingContext("Tree").getObject();
this.getRouter().navTo("characteristic", {
internalclassnum: oRow.internalClass
});
}
});
});
I believe the flexibility services only work in the Fiori launchpad, not in the webide sandbox launchpad. Do you get the same issue if you deploy?
I have a map with a few dozen layers, each with a unique ID. I have checkboxes to turn the layers on and off, for which I need a single array of all the layer IDs. I can't figure out how to loop through all of the map layers to capture the layer IDs. I tried using map.getLayer() but this returns the layer as an object, not the layer ID as a string. I want to loop through all of the map layers and push the layer ID strings to a new array. How do I do this?
mapboxgl.accessToken = "myaccesstoken";
var map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mymapboxstyle",
center: [-71.0664, 42.358],
minZoom: 14 //
});
map.on("style.load", function () {
map.addSource("contours", {
type: "vector",
url: "mapbox://mapbox.mapbox-terrain-v2"
});
map.addSource("hDistricts-2017", {
"type": "vector",
"url": "mapbox://mysource"
});
map.addLayer({
"id": "contours",
"type": "line",
"source": "contours",
"source-layer": "contour",
"layout": {
"visibility": "none",
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#877b59",
"line-width": 1
}
});
map.addLayer({
"id": "Back Bay Architectural District",
"source": "hDistricts-2017",
"source-layer": "Boston_Landmarks_Commission_B-7q48wq",
"type": "fill",
"layout": {
"visibility": "none"
},
"filter": ["==", "OBJECTID", 13],
"paint": {
"fill-color": "#192E39",
"fill-outline-color": "#000000",
"fill-opacity": 0.5
}
});
});
var layerIds = [];
function getIds() {
//here I need to iterate through map layers to get id strings.
//how do I do this???
layerIds.push( ); //then push those ids to new array.
console.log(layerIds); //["contours", "Back Bay Architectural District"]
}
If kielni answer isn't convenient because of unknown reason, use map.getStyle().layers to get an array of object layers then map it to get an array of string ids.
var layers = map.getStyle().layers;
var layerIds = layers.map(function (layer) {
return layer.id;
});
You have the layer ids when you add the layer; you can save them then:
function addLayer(map, options, layerIds) {
map.addLayer(options);
layerIds.push(options.id);
}
addLayer(map, {
"id": "Back Bay Architectural District",
"source": "hDistricts-2017",
"source-layer": "Boston_Landmarks_Commission_B-7q48wq",
"type": "fill",
"layout": {
"visibility": "none"
},
"filter": ["==", "OBJECTID", 13],
"paint": {
"fill-color": "#192E39",
"fill-outline-color": "#000000",
"fill-opacity": 0.5
}
},
layerIds);
What is the correct way to manage the state of radio and checkboxes using React?
In some instances a form would be rendered partially completed so some radio and checkboxes would be pre selected on first load.
I have the following code snippet and i cannot get it to work as expected.
var formData = {
"id": 13951,
"webform_id": 1070,
"page": 0,
"type": "radios",
"name": "What industry are you in?",
"tooltip": "",
"weight": 0,
"is_required": 1,
"default_value": "",
"validation": "",
"allow_other_option": 0,
"other_option_text": "",
"mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"option_conditional_from": null,
"default_value_querystring_key": "",
"deleted_at": null,
"is_auto_save": 0,
"is_component_number_hidden": 0,
"is_component_inline": 0,
"enable_confirm_validation": 0,
"confirm_validation_text": null,
"additional_options": "",
"url_mapping": "",
"webformcomponentoptions": [
{
"id": 13888,
"webform_component_id": 13951,
"key": "Hospitality",
"value": "Hospitality",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13889,
"webform_component_id": 13951,
"key": "Retail",
"value": "Retail",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13890,
"webform_component_id": 13951,
"key": "Other",
"value": "Other",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
}
]
}
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio radio={this.props.webform.webformcomponentoptions} />
</div>
</form>
)
}
}
class Radio extends React.Component {
render() {
var options = [];
this.props.radio.forEach(function(radio, i) {
options.push(<Option option={radio} key={radio.id} index={i} />);
})
return (
<div>{options}</div>
)
}
}
class Option extends React.Component {
constructor(props) {
super(props);
this.handleOptionChange = this.handleOptionChange.bind(this);
this.state = {selectedIndex: null};
}
handleOptionChange(e) {
this.setState({selectedIndex: this.props.index}, function() {
});
}
render() {
const selectedIndex = this.state.selectedIndex;
return (
<div>
<input type="radio"
value={this.props.option.value}
name={this.props.option.webform_component_id}
id={this.props.option.id}
checked={selectedIndex === this.props.index}
onChange={this.handleOptionChange} />
<label htmlFor={this.props.option.id}>{this.props.option.key}</label>
</div>
)
}
}
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);
https://codepen.io/jabreezy/pen/KWOyMb
The most important thing would be to have the Radio component handle the state, and keeping track of the selected option.
In addition, I would simplify by using map instead of forEach, and foregoing the Option component for a class method returning an <input type='radio'>. For simplicity's sake, using the option value for keeping track of the selected state instead of the index, and mimicking React's select component allowing a default value prop instead of setting each option's selected prop (which you don't seem to be using).
Finally, for order's sake, renaming the Radio:s radio prop to the (IMO) more correct options. Ergo (caveat, I haven't tested this):
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio options={this.props.webform.webformcomponentoptions} value={this.props.webform.value} />
</div>
</form>
)
}
}
class Radio extends React.Component {
constructor (props) {
super(props)
this.handleOptionChange = this.handleOptionChange.bind(this)
this.state = {value: this.props.value}
}
render() {
return this.props.options.map(this.getOption)
}
handleOptionChange (e) {
this.setState({value: e.target.value})
}
getOption (option) {
return (
<div>
<input type='radio'
value={option.value}
name={option.webform_component_id}
id={option.id}
key={option.id}
checked={this.state.value === option.value}
onChange={this.handleOptionChange} />
<label htmlFor={option.id}>{option.key}</label>
</div>
)
}
}
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);
Thank you so much for your input Linus. You set me along the correct path and i've solved my problem the following way:
var formData = {
"id": 13951,
"webform_id": 1070,
"page": 0,
"type": "radios",
"name": "What industry are you in?",
"tooltip": "",
"weight": 0,
"is_required": 1,
"default_value": "",
"validation": "",
"allow_other_option": 0,
"other_option_text": "",
"mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"option_conditional_from": null,
"default_value_querystring_key": "",
"deleted_at": null,
"is_auto_save": 0,
"is_component_number_hidden": 0,
"is_component_inline": 0,
"enable_confirm_validation": 0,
"confirm_validation_text": null,
"additional_options": "",
"url_mapping": "",
"webformcomponentoptions": [
{
"id": 13888,
"webform_component_id": 13951,
"key": "Hospitality",
"value": "Hospitality",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13889,
"webform_component_id": 13951,
"key": "Retail",
"value": "Retail",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13890,
"webform_component_id": 13951,
"key": "Other",
"value": "Other",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
}
]
}
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio radio={this.props.webform.webformcomponentoptions} />
</div>
</form>
)
}
};
class Radio extends React.Component {
constructor(props) {
super(props);
this.state = {selectedOption: 'Other'};
}
handleOptionChange(changeEvent) {
this.setState({
selectedOption: changeEvent.target.value
})
};
renderOption(props) {
return (
<div>
<h3>{props.index}</h3>
<input type="radio"
value={props.option.value}
name={props.option.webform_component_id}
id={props.option.id}
checked={props.status}
onChange={props.clickeme} />
<label htmlFor={props.option.id}>{props.option.key}</label>
</div>
)
};
render() {
return (
<div>
{this.props.radio.map(function(radio) {
var selected = this.state.selectedOption === radio.value;
return <this.renderOption option={radio} key={radio.value} status={selected} clickeme={(e)=> this.handleOptionChange(e)} />;
}, this)}
</div>
)
};
};
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
hi i need List grouping control by using js view.but openui5 provides code by using xml view.
https://openui5.hana.ondemand.com/explored.html#/sample/sap.m.sample.ListGrouping/preview
how to convert this code into js view and how to make ListGrouping able to selection for both element level and group level and change this as dropdown box
List.view.xml
<mvc:View
controllerName="sap.m.sample.ListGrouping.List"
xmlns:l="sap.ui.layout"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<List
items="{
path: '/ProductCollection',
sorter: {
path: 'SupplierName',
descending: false,
group: true
},
groupHeaderFactory: '.getGroupHeader'
}"
headerText="Products" >
<StandardListItem
title="{Name}"
description="{ProductId}"
icon="{ProductPicUrl}"
iconDensityAware="false"
iconInset="false" />
</List>
</mvc:View>
List.controller.js
sap.ui.define([
'jquery.sap.global',
'sap/m/GroupHeaderListItem',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, GroupHeaderListItem, Controller, JSONModel) {
"use strict";
var ListController = Controller.extend("sap.m.sample.ListGrouping.List", {
onInit : function (evt) {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
getGroupHeader: function (oGroup){
return new GroupHeaderListItem( {
title: oGroup.key,
upperCase: false
} );
}
});
return ListController;
});
how to write the same code by using js view
I have tried like as follows, but i am getting Error: Missing template or factory function for aggregation items of Element sap.m.List#__list0 !
List.view.js
sap.ui.jsview("oui5mvc.List", {
getControllerName : function() {
return "oui5mvc.List";
},
createContent : function(oController) {
odbbshiftGlobalId = this.getId();
var oMyFlexbox = new sap.m.FlexBox({
items: [
oList = new sap.m.List({
width: '500px',
group: true,
groupHeaderFactory: '.getGroupHeader',
items: [
]
}),
]
});
oMyFlexbox.placeAt(this.getId()).addStyleClass("tes");
}
});
List.controller.js
sap.ui.controller("oui5mvc.List", {
onInit: function() {
var data = {
"ProductCollection": [
{
"ProductId": "1239102",
"Name": "Power Projector 4713",
"Category": "Projector",
"SupplierName": "Titanium",
"Description": "A very powerful projector with special features for Internet usability, USB",
"WeightMeasure": 1467,
"WeightUnit": "g",
"Price": 856.49,
"CurrencyCode": "EUR",
"Status": "Available",
"Quantity": 3,
"UoM": "PC",
"Width": 51,
"Depth": 42,
"Height": 18,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-6100.jpg"
},
{
"ProductId": "2212-121-828",
"Name": "Gladiator MX",
"Category": "Graphics Card",
"SupplierName": "Technocom",
"Description": "Gladiator MX: DDR2 RoHS 128MB Supporting 512MB Clock rate: 350 MHz Memory Clock: 533 MHz, Bus Type: PCI-Express, Memory Type: DDR2 Memory Bus: 32-bit Highlighted Features: DVI Out, TV Out , HDTV",
"WeightMeasure": 321,
"WeightUnit": "g",
"Price": 81.7,
"CurrencyCode": "EUR",
"Status": "Discontinued",
"Quantity": 10,
"UoM": "PC",
"Width": 34,
"Depth": 14,
"Height": 2,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-1071.jpg"
},
{
"ProductId": "K47322.1",
"Name": "Hurricane GX",
"Category": "Graphics Card",
"SupplierName": "Red Point Stores",
"Description": "Hurricane GX: DDR2 RoHS 512MB Supporting 1024MB Clock rate: 550 MHz Memory Clock: 933 MHz, Bus Type: PCI-Express, Memory Type: DDR2 Memory Bus: 64-bit Highlighted Features: DVI Out, TV-In, TV-Out, HDTV",
"WeightMeasure": 588,
"WeightUnit": "g",
"Price": 219,
"CurrencyCode": "EUR",
"Status": "Out of Stock",
"Quantity": 25,
"UoM": "PC",
"Width": 34,
"Depth": 14,
"Height": 2,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-1072.jpg"
},
],
"ProductCollectionStats": {
"Counts": {
"Total": 14,
"Weight": {
"Ok": 7,
"Heavy": 5,
"Overweight": 2
}
},
"Groups": {
"Category": {
"Projector": 1,
"Graphics Card": 2,
"Accessory": 4,
"Printer": 2,
"Monitor": 3,
"Laptop": 1,
"Keyboard": 1
},
"SupplierName": {
"Titanium": 3,
"Technocom": 3,
"Red Point Stores": 5,
"Very Best Screens": 3
}
},
"Filters": [
{
"type": "Category",
"values": [
{
"text": "Projector",
"data": 1
},
{
"text": "Graphics Card",
"data": 2
},
{
"text": "Accessory",
"data": 4
},
{
"text": "Printer",
"data": 2
},
{
"text": "Monitor",
"data": 3
},
{
"text": "Laptop",
"data": 1
},
{
"text": "Keyboard",
"data": 1
}
]
},
{
"type": "SupplierName",
"values": [
{
"text": "Titanium",
"data": 3
},
{
"text": "Technocom",
"data": 3
},
{
"text": "Red Point Stores",
"data": 5
},
{
"text": "Very Best Screens",
"data": 3
}
]
}
]
}
};
var oTemplate11 = new sap.m.StandardListItem({title : "{Name}"});
oList.setModel(new sap.ui.model.json.JSONModel(data));
oList.bindItems("/ProductCollection");
oList.placeAt('content');
},
getGroupHeader: function (oGroup){
return new sap.m.GroupHeaderListItem( {
title: oGroup.key,
upperCase: false
});
},
});
Your call to bind items to the list is not entirely correct.
The method takes an object with binding information as parameter instead of just the path to the model property. See the documentation for bindItems and bindAggregation in general.
In your case it should look like
oList.bindItems({
path: "/ProductCollection",
template: new sap.m.StandardListItem({
title: "{Name}",
description: "{ProductId}",
icon: "{ProductPicUrl}"
})
});
Here is a jsfiddle example where I cannot get data label values or percentages to display when initializing the chart by passing it options when creating the chart object. Only the point.name is displayed in the label. Seems like you can only get these options to work when you create the entire object at run time using the plotOptions structure.
http://jsfiddle.net/nstvx7wc/7/
$(document).ready(function(){
var options = {
chart: {
renderTo: 'chartdiv',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '{point.name} {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
},
title: {
text: ''
},
};
options.series = [{"colorByPoint": "true", "data": [{"y": 0.36, "name": "series1"}, {"y": 0, "name": "series2"}, {"y": 0, "name": "series3"}, {"y": 0.03, "name": "series4"}, {"y": 0.04, "name": "series5"}, {"y": 0.07, "name": "series6"}]}];
options.title.text = "test pie";
options.pie.dataLabels.enabled = 'true';
chartObject = new Highcharts.Chart(options);
});
You 'pie' option was misconfigured. options.pie doesn't exist. It should be placed under series or the plotoptions property;
See this example; http://jsfiddle.net/nstvx7wc/21/
$(document).ready(function() {
var options = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'test pie'
}
};
options.series = [{
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '{point.name} {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
"colorByPoint": "true",
"data": [{
"y": 0.36,
"name": "series1"
}, {
"y": 0,
"name": "series2"
}, {
"y": 0,
"name": "series3"
}, {
"y": 0.03,
"name": "series4"
}, {
"y": 0.04,
"name": "series5"
}, {
"y": 0.07,
"name": "series6"
}]
}];
Highcharts.chart('chartdiv', options);
});