SAPUI5 Binding Context for array hierarchy - sapui5

I have a questions object which contains an answers array
var oModel = new JSONModel({
questions: [{
order: 1,
title: "",
answers: [{
sequence: 1,
label: "Yes",
}, {
sequence: 3,
label: "N/A",
}]
}]
});
And the context set as follows
this.getView().setModel(oModel, "viewmodel");
var oContext = oModel.createBindingContext("/questions/0/");
this.getView().setBindingContext(oContext, "viewmodel");
In my view, I can bind questions fine
<Input value="{viewmodel>title}"/>
However, updating the answers binding updates ALL the answer arrays in EVERY questions context!, e.g. below i'm binding to my current context (questions/0/) but update the label will update the answers for all questions....
<f:Form id="formCustomRadio" editable="true" visible="true" formContainers="{viewmodel>answers}">
<f:layout>
<f:ResponsiveGridLayout/>
</f:layout>
<f:formContainers>
<f:FormContainer title="Answer {viewmodel>sequence}">
<f:formElements>
<f:FormElement label=" {i18n>radioLabel}">
<f:fields>
<Input value="{viewmodel>label}"/>
</f:fields>
Any ideas?

The issue was related to the the array push when creating new questions...
questionData.questions.push({
order: questionData.questions.length + 1,
title: questionData.questions[questionData.questions.length - 1].title,
answers: questionData.questions[questionData.questions.length - 1].answers
});
As answers is an array of objects , you can't simply push to it as this creates duplicate references. That's the reason answers where duplicated after each update. Solution was to push each answer separately in a for loop.
for (var i = 0; i < answerArray.length; i++) {
questionData.questions[newIndex].answers.push({
sequence: answerArray[i].sequence,
label: answerArray[i].label,
points: answerArray[i].points,
imageFlag: answerArray[i].imageFlag,
image: answerArray[i].image,
mandatoryComments: answerArray[i].mandatoryComments,
additionalQuestion: answerArray[i].additionalQuestion
});
}

Related

How to remove added items using ID from controller

I have tried adding buttons to HBox and FlexBox dynamically
In the XML view i have did as below:
<HBox id="upperchart">
<m:Input value=" Key Code " editable='false' width='360px'/>
</m:HBox>
<FlexBox
alignItems="Start" id="lowerchart">
<FlexBox>
In the controller I tried accessing these with the ID's as
Controller:
var lowerHBox = this.getView().byId("lowerchart");
var upperHBox = this.getView().byId('upperchart');
var oHBox = new sap.m.HBox();
oHBox.addItem(new sap.m.Input({
value: "Test Data",
editable: false,
width: graphWidth*10 + 'px'
}));
upperHBox.addItem(oHBox);
var oMyFlexbox = new sap.m.FlexBox();
// I am adding Buttons to HBox dynamically
for (var i = 0; i < 5.length; i++){
oMyFlexbox.addItem(new sap.m.Button({
text: "Button",
width: allWidths[i]*10 + 'px'
}));
}
lowerHBox.addItem(oMyFlexbox);
Here the thing is When i just navigate through the page it gets created multiple times.
so i have tried to remove on first and add as again under this as:
lowerHBox.removeItem();
upperHBox.removeItem();
But this doesn't work to my luck ,
May I know how can I avoid it creating again and again or check if items already exists remove and create a new like this..
Any help or guiding links are appreciated thanks in advance.
You can remove the items of HBox here as:
lowerHBox.removeAllItems();
upperHBox.removeAllItems();
This could remove Items which I understood is one of your Q's
link to docs:
https://sapui5.hana.ondemand.com/#/api/sap.m.HBox%23methods/Summary
I Would wait for other expert's say for more efficient way :)

Button Filter to Table

Trying to add a filter that takes a table that uses xsodata and have a dropdown that applies a filter
current code:
var testButton = new sap.m.Button('filterTable', {
text: "Filter",
tooltip: "Filter table to selection",
icon: sap.ui.core.IconPool.getIconURI("filter"),
press: new sap.ui.model.Filter(testTable['testColumn'], sap.ui.model.FilterOperator.EQ, "testValue")
});
I think that this example in the SDK is what you are looking for. Take a look at how the "availability" column is declared in the XML view and at the implementation of the toggleAvailabilityFilter function in the controller.
EDIT: Here the basic code, as example.
How the column should be declared in the XML View:
<Column
id="columnId"
filterProperty="Available"
showFilterMenuEntry="false"
defaultFilterOperator="EQ"
filterType="sap.ui.model.type.Boolean">
<m:Label text="Status" />
<template>
...template...
</template>
</Column>
Example of button callback:
toggleAvailabilityFilter : function(oEvent) {
this.byId("columnId").filter(oEvent.getParameter("pressed") ? "X" : "");
},

Input value is deleted on applying filters to suggestion items for Sap.m.Input

I am working on Sap.m.Input suggestion items. Suggestions for the input is working fine but when i choose an item from the suggestions list and then remove the value and enter a new value, it is deleting the freshly entered value automatically without showing any suggestions. I debugged my code and the value is deleted at line oBinding.filters(). My code is as below,
<Input id="input" placeholder="{i18n>input}" editable="true" startSuggestion="2"
showSuggestion="true" suggest="handleSuggest"
suggestionItemSelected="onSelectedItem"
suggestionItems="{path:'abc>/abSet',templateShareable:true, parameters:{select: 'ab,bc'}}">
<suggestionItems growing="true" growingScrollToLoad="true">
<core:Item key="{abc>ab}" text="{abc>ab} {abc>bc}"/>
</suggestionItems>
</Input>
controller
handleSuggest: function (oEvent) {
var sTerm = oEvent.getParameter("suggestValue"),
oSource = oEvent.getSource(),
oBinding,
aFilters = [];
oSource.setBusy(false);
if (sTerm) {
aFilters.push(new Filter("bc", FilterOperator.Contains, sTerm));
aFilters.push(new Filter("cd", FilterOperator.EQ, ""));
aFilters.push(new Filter("de",FilterOperator.EQ, ""));
}
oBinding = oSource.getBinding("suggestionItems");
var Filters = [];
Filters.push(new Filter({
filters: aFilters,
and: true
}));
oBinding.getModel().setSizeLimit(500);
oBinding.filter(Filters);
},
//Once the suggestion BP is choosen retreiving the key
onSelectedItem: function (oEvent) {
var sItems = oEvent.getParameter("selectedItem");
if (sItems !== null)
filterValue = sItems.getKey();
},
Your help is much appreciated
For me the solution was removing the property key from the <core:Item /> elements in the suggestionItems aggregation.
After version 1.44 something changed and the property key somewhat causes some strange behaviors but I still can't figure it out why.
"After version 1.44 something changed and the property key somewhat causes some strange behaviors but I still can't figure it out why."
To avoid strange behavior please add valueLiveUpdate="true"
Your code shoud look like this
<Input
id="input"
placeholder="{i18n>input}"
editable="true"
startSuggestion="2"
showSuggestion="true"
suggest="handleSuggest"
suggestionItemSelected="onSelectedItem"
valueLiveUpdate="true"
suggestionItems="{
path: 'abc>/abSet',
templateShareable: true,
parameters:{select: 'ab,bc'}
}">
<suggestionItems
growing="true"
growingScrollToLoad="true">
<core:Item key="{abc>ab}" text="{abc>ab} {abc>bc}"/>
</suggestionItems>
</Input>

Is it possible to hide sap.m.input "description" property value

I'm using the description field to hold an value that I don't want to be displayed, is it possible to set this property to visible:false or set to width to 0?
new sap.m.Input("idAltDistInput"+refDocID+sequenceID, {value:"{AltDistrictDesc}",
description: { path : 'AltDistrictID' }
:
visible : false doesn't seem to work.
Yes you can by adding StyleClass.
sap.m.Input("id",{
//Properties
}).addStyleClass("InputDescripTionHidden");
Add following css
.InputDescripTionHidden>span{
display:none
}
Your comment above suggests that you want to store some hidden value, for later use.
Rather than "hijack" (in the nicest sense of the word) another property, you should consider using Custom Data, which is designed for this sort of thing. Here's an example.
new sap.m.List({
mode: "SingleSelectMaster",
items: {
path: "/records",
template: new sap.m.InputListItem({
label: "District",
content: new sap.m.Input({
value: "{AltDistrictDesc}",
customData: [new sap.ui.core.CustomData({
key: "DistrictID",
value: "{AltDistrictID}"
})]
})
})
},
select: function(oEvent) {
var id = oEvent.getParameter("listItem")
.getContent()[0] // the Input control
.getCustomData()[0] // the only Custom Data
.getValue();
alert("Selected District ID : " + id);
}
})
.setModel(new sap.ui.model.json.JSONModel({
records: [{
AltDistrictID: "D1",
AltDistrictDesc: "District 1"
}, {
AltDistrictID: "D2",
AltDistrictDesc: "District 2"
}]
}))
.placeAt("content");
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-libs="sap.m" data-sap-ui-theme="sap_bluecrystal"></script>
<div class="sapUiBody" id="content"></div>
(Note that for simplicity, I'm just grabbing the first content and the first custom data within that content in the select listener. You will want to do this slightly more precisely in real code.)

SAP UI5: error in binding

Even though quite experienced in SAP HCM development, I have just started my quest to learn UI5 (using eclipse) so my apologies in advance if my question is a bit basic...
I am trying to create a binding of data (based upon the example of UI5 rockstar
DJ Adams) but for some reason, have no result.
in my controller I have entered the following code (in the onInit function) to create the data and make them available:
onInit: function() {
var cities = [ { id: "A1", name: "Kobe" },
{ id: "A2", name: "Hiroshoma" }
];
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(cities);
sap.ui.getCore().setModel(oModel);
},
in my view, I try to bind the data using the following code:
</IconTabFilter>
<IconTabFilter
binding="{/cities/0}"
text="{name}"
icon="sap-icon://group"
design="Horizontal">
</IconTabFilter>
<IconTabFilter
binding="{/cities/1}"
text="{name} ({id})"
icon="sap-icon://group"
design="Horizontal">
</IconTabFilter>
</items>
</IconTabBar>
</content>
</Page>
</core:View>
in my output,all the elements display correctly, however I don't get the values that I initialised in my model. However I don't get any errors either
My questions:
1. can you provide some assistance/guidance to see where I made an error?
2. what would be the easiest way to detect where issues are when it comes to databinding (debugger, other tips)?
Many thanks for your guidance,
Tom
The error is indeed in your bindings.
Although you have a variable cities, your JSON context starts with id.
You could update your JSONModel to have root element cities:
.setModel({
cities: [
{ id: "A1", name: "Kobe" },
{ id: "A2", name: "Hiroshoma" }
]
});
As for debugging, I prefer the standard Google Chrome browser tools. It allows for watches, breakpoints, and (small) live code changes.
Please try to use template, instead of binding individual elements you can use the template to bind the array to individual elements.
Example:
<List
items="{/ProductCollection}"
headerText="Products">
<items>
<ObjectListItem
title="{Name}"
type="Active"
press="onListItemPress"
number="{Price}"
numberUnit="{CurrencyCode}">
<firstStatus>
<ObjectStatus
text="Overweight"
state="Error" />
</firstStatus>
<secondStatus>
<ObjectStatus
text="In Stock"
state="Success" />
</secondStatus>
<attributes>
<ObjectAttribute text="{WeightMeasure} {WeightUnit}" />
<ObjectAttribute text="{Width} x {Depth} x {Height} {DimUnit}" />
</attributes>
</ObjectListItem>
</items>
[Live example: https://sapui5.hana.ondemand.com/sdk/explored.html#/sample/sap.m.sample.ObjectListItem/code]
If you want to have finer control on the data then you can set multiple model with key value pair.
Example:
sap.ui.getCore().setModel("key",oModel);
and to get the value:
sap.ui.getCore().getModel("key");
Your approach of creating model is not quiet right. Variable cities is not object but an array. Either you can set data to model:
onInit: function() {
var cities ={ "cities": [{ "id": "A1", "name": "Kobe" },
{ "id": "A2", "name": "Hiroshoma" }
]}
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(cities);
sap.ui.getCore().setModel(oModel);
},
or you can set property:
var cities = [ { id: "A1", name: "Kobe" },
{ id: "A2", name: "Hiroshoma" }
];
var oModel = new sap.ui.model.json.JSONModel();
oModel.setProperty("/cities", cities);
sap.ui.getCore().setModel(oModel);
and you also have to bind your xml correctly. You can follow the template of list items from SapUi5 explored or developers guide