Value of a select in SAPUI5 - sapui5

I have the following select in a table in my xml view.
Table:
<Table id="variables"
rows="{
path: 'modelname>/ZDATSet'
}">
...
Select:
<m:Select
selectedKey="{modelname>Datetype}"
items="{
path: 'modelname>/ZTYPESet'
}">
<core:Item key="{modelname>Datetype}" text="modelname>Datetypetxt}" />
</m:Select>
Furthermore I have a button in an other row in the table.
In the press-function I want to read the currently selected key of the select-box.
If I try it with
var button = oEvent.getSource();
var context = button.getBindingContext("modelname");
var datetype = context.getProperty("Datetype");
I only get the preselected value but not the change from the user input.
(Same problem with an text input in the row)
I already put data-sap-ui-xx-bindingSyntax="complex" in the index.html

I found the solution now.
I thought <script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-xx-bindingSyntax="complex" ... should be enough for the default two way binding.
Now I added oModel.setDefaultBindingMode(sap.ui.model.BindingMode.TwoWay); to the model and it works fine.

If your button is in the same row you could do something like this in its press event:
onPress:function(oEvent){
var button = oEvent.getSource();
var context = button.getBindingContext("modelname"); //Points to the current row
var datetype = context.getProperty("DateType");
...
}
If the button is outside of the table you have to give us more details: Which Table are you using and how is it configured, do you want to read the value of the selectbox in the currently selected row? Add more code!

Based on your code snippet, you are using model binding to set the items and the selected key of your Select.
In the Button press handler you can get the current value from the binding context:
onPress: function (oEvent) {
oEvent.getSource().getBindingContext("modelname").getProperty("Datetype");
}

Here once you set the selectedKey property in SelectionInputType.COMBOBOX, you can take value as below.
oController = this; var view = oController.getView(); var oModel = view.getModel(); var data = oModel.getData();

Related

SAPUI5 sap.m.list in a popover is emtpy when populated using bindElement

I have a table (sap.m.table) with different columns. One columns contains a link and when the user clicks on the link a popover fragment opens and shows some details in a list (sap.m.list). The data is coming from an oData Service. One Entity feeds the table and through a navigation property the data for the popover is fetched.
I have a working example for this scenario where I create the the list template in the controller. But I believe that this should also be possible just by xml and a bindElement in the controller. What is the mistake in my second scenario?
First Scenario (which is working fine):
Popover XML:
<Popover
showHeader="false"
contentWidth="320px"
contentHeight="300px"
placement="Bottom"
ariaLabelledBy="master-title">
<Page
id="master"
class="sapUiResponsivePadding--header"
title="Aktionen">
<List
id="AktionList">
</List>
</Page>
</Popover>
Calling the Popover in the controller file (sPath is /TableEntity('123456')/AktionSet):
if (!this._oPopover) {
Fragment.load({
id: "popoverNavCon",
name: "bernmobil.ZPM_STOERUNG_FDA.view.AktionPopover",
controller: this
}).then(function(oPopover){
this._oPopover = oPopover;
this.getView().addDependent(this._oPopover);
var oList = Fragment.byId("popoverNavCon", "AktionList");
var oItemTemplate = this._BuildItemTemplate();
oList.bindAggregation("items", sPath, oItemTemplate);
this._oPopover.openBy(oControl);
}.bind(this));
} else {
var oList = Fragment.byId("popoverNavCon", "AktionList");
var oItemTemplate = this._BuildItemTemplate();
oList.bindAggregation("items", sPath, oItemTemplate);
this._oPopover.openBy(oControl);
}
_BuildItemTemplate: function(){
var oItemTemplate = new sap.m.ObjectListItem({
title:"{AktionsBez}",
type: "Inactive"
});
oItemTemplate.addAttribute(new sap.m.ObjectAttribute({
text : "{Aktionstext}"
}));
oItemTemplate.addAttribute(new sap.m.ObjectAttribute({
text : "{path: 'ChangedAt', type: 'sap.ui.model.type.DateTime'}"
}));
return oItemTemplate;
}
And this is the idea of the second scenario which is calling the oDataService but not displaying any data:
Instead of having only the List definition in XML also the ObjectListItem is defined in the XML:
<List
id="AktionList"
items="{AktionSet}">
<ObjectListItem
title="{AktionsBez}"
type="Active">
<ObjectAttribute text="{Aktionstext}" />
<ObjectAttribute text="{ChangedAt}" />
</ObjectListItem>
</List>
And in the controller instead of building the template and doing the bindAggretation there is just:
var oList = Fragment.byId("popoverNavCon", "AktionList");
oList.bindElement(sPath);
How do I get the second scenario displaying data in the list?
I would suggest a third solution:
When pressing on your table row, get the binding context of the current row using oContext = oClickedRow.getBindingContext() or something similar. This context should point to /TableEntity('123456').
Apply this context to your Popover using oPopover.setBindingContext(oContext).
Now your Popover has the same context as your table row. The XML should look like in your second scenario.
Using the path is an extra step imo. I think it also makes more sense to bind the complete Popover and not just the List. Has the neat side effect that you can use a property of your TableEntity as the title for the Popover. It also completely avoids working with controls directly (which is one of the seven deadly sins) and you should be able to remove all those IDs.
Here is how the relevant part of the view should look:
<List
id="AktionList"
items="{AktionSet}">
<dependents>
<ObjectListItem
id="oObjectListItem"
title="{AktionsBez}"
type="Active">
<ObjectAttribute text="{Aktionstext}" />
<ObjectAttribute text="{ChangedAt}" />
</ObjectListItem>
</dependents>
</List>
And in the controller:
var oList = sap.ui.core.Fragment.byId(this.getView().createId("popoverNavCon"), "AktionList");
oList.bindItems({
path: sPath,
template: sap.ui.core.Fragment.byId(this.getView().createId("popoverNavCon"), "oObjectListItem")
});
Check dependents in sap.m.List aggregation section for details.

How get selected item from StandardListItem

I'm building a master-detail app. I'm using sap.m.StandardListItem for listing master objects. I want that selected master object appear on a detail page.
<List id="lstRequest" headerText="Custom Content" selected="true" items="{
path: '/Requests',
parameters: {
expand: 'RequestTypeDetails'
}
}">
<StandardListItem
title="{RequestTypeDetails/RequestType2} - {RequestCode}"
description="{TotalAdvance}"
icon="sap-icon://request"
iconDensityAware="false"
iconInset="false"
type="Navigation"
press="onSelectApprovation"
/>
</List>
I'm following the guide from here but it doesn't work in my case.
var source = event.getSource();
var bindingobject = event.getBindingContext("Requests");
bindingobject is undefined.
Inside onSelectApprovation do the following:
var oItem = oEvent.getParameter("listItem") || oEvent.getSource());
var oCtx = oItem.getBindingContext();
var requestCode = oCtx.getProperty("RequestCode");
By the way: sap.m.List does not have a property called "selected" of type boolean. However, it has a select event that could also be used instead of using the press event of the StandardListItem...
Give the logical name while setting json model to list like below.
this.getView().byId("lstRequest").setModel(oListJson,"List");
oListJson will be your array of data.
now use your code for accessing list object in your onSelectApprovation fuction as below
onSelectApprovation : function(oEvent){
var bindingobject = oEvent.getSource().getBindingContext("List");
}

Method getPath called in onBeforeRendering returns undefined

I have a List Report which, once selected an item, prompts to an Object Page. I am using no FIORI Elements, everything was created from scratch.
The object page has a static header, but its body changes from item to item. In essence, the body uses different fragments that depends on a field (Position Type) of the selected item. In other words:
Pos Type 1 ---> fragment A
Pos Type 2 ---> fragment B
To do all this, on the controller of the object page, I have implemented the following withing the onBeforeRendering lifecycle method:
onBeforeRendering: function() {
// // Set Fragment to be used
var oLayout = this.getView().byId("ObjectPageLayout"),
oFragment = sap.ui.xmlfragment(this._fragmentName());
oLayout.addSection(oFragment);
},
_fragmentName: function() {
var oModel = this.getView().getModel();
var sPosType = oModel.getProperty(this.getView().getObjectBinding().getPath() + "/PositionType");
var sFragment;
if (sPosType === "1") {
sFragment = "A";
} else if (sPosType === "2") {
sFragment = "B";
}
return sFragment;
},
The problem I am facing is that this code is throwing the following error message: "Uncaught (in promise) TypeError: Cannot read property 'getPath' of undefined"
The only way I found to make this to work is by, instead of using method onBeforeRendering, I used onInit. This way, getPath() works fine. But if the user goes back to the List Report, and then selects an item of a different Position Type, then the Object Page displays the same fragment used in the previous item selected.
In case you wonder, bellow you will find the object view:
<mvc:View height="100%" xmlns="sap.uxap" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:m="sap.m" xmlns:semantic="sap.m.semantic"
xmlns:forms="sap.ui.layout.form" xmlns:layout="sap.ui.layout" controllerName="objectview.controller"
xmlns:aud="sap.uxap.sample.SharedBlocks.fragmentblocks">
<semantic:FullscreenPage id="page" navButtonPress="onNavBack" showNavButton="true" title="{i18n>ObjectPageTitle}">
<m:Page title="Object Page Title">
<m:content>
<ObjectPageLayout id="ObjectPageLayout">
<headerTitle>
<ObjectPageHeader id="ItemTitle" objectTitle="Item Title">
<actions>
Some actions defined
</actions>
</ObjectPageHeader>
</headerTitle>
<headerContent>
Some Header Content
</headerContent>
<sections>
</sections>
</ObjectPageLayout>
</m:content>
<m:footer>
<m:Bar>
<m:contentRight>
Buttons added to the Footer
</m:contentRight>
</m:Bar>
</m:footer>
</m:Page>
</semantic:FullscreenPage>
What happens is that each time you go to the page you add a new section on the container of sections.
You can remove all the existent sections before adding the new one.
oLayout.removeAllSections();
oLayout.addSection(oFragment);

Get value from checkbox in SapUI5

I have a main.controller.js where I want to check the value of a Checkbox. If the checkbox has been checked, the first flexbox will be shown and the second flexbox will not be shown in the fragment.
This my controller.js:
checkDone: function () {
var checkV = this.byId("ch1").getSelected();// not working
}
This my fragment.xml
<CheckBox id="ch1" select ="checkDone" text="Check"></CheckBox>
<FlexBox class="sapUiSmallMarginEnd" id="f1">
<Input value=""></Input>
</FlexBox>
<FlexBox direction="Column" id="f2">
<Input value=""></Input>
</FlexBox>
This code works (see example with sap.m.Checkbox here).
Just a recommendation: in your checkbox's 'select' handler you use:
this.byId("ch1").getSelected();
in order to whether the checkbox is selected or not, but this value is already given as a parameter of the select handler:
checkDone: function (oEvent) {
var bSelected = oEvent.getParameter('selected'));
}
Simmilar is for the sap.ui.commons.Checkbox API. Check change event.
It looks like the View.byId function returns an element in its initial form. When you find element from DOM, getSelected() function works as expected.
Instead of getSelected() try getChecked().
getChecked() will return true or false based on checked/unchecked.

getting class attr in jquery

I have some divs that are generated dynamically with content. I add the content id to the class for the div like so:
<div class="div-1"></div>
<div class="div-3"></div>
<div class="div-6"></div>
<div class="div-8"></div>
How do I select the id for a div because I need it as a param to send via ajax. e.g. I need to get the 1 when I click on the 1st div, 3 when I click on 2nd and so on
var id = $(this).attr('class').replace('div-', '');
Or even simple
var id = this.className.replace('div-', '');
Where this points to the dom element you click on inside the click handler.
//Here instead of document it is better to specify a parent container of all divs
$(document).on('click', '[class^="div-"]', function(){
var id = this.className.replace('div-', '');
});
Try this, and remember changing "div" for your selector:
$(document).on("click", "div", function() {
var class_elem = $(this).attr("class").split("-");
var n = class_elem[1]; // This is your number
});
The correct jQuery syntax is:
$("div").click( function() {
var id = $(this).attr('class').replace('div-', '');
});