Filtering data in UI5 - sapui5

The filter using below code is not working. I created an application using a template from Web IDE and then bound OData to the list in XMLView, applying filter on search.
View:
<SearchField liveChange="onSearch" id="master1SearchField" search="onSearch"/>
<List id="master1List" items="{path:'/DetailsSet'}">
<items>
<ObjectListItem id="master1ListItem">
<attributes>
<ObjectAttribute text="{Name}"/>
</attributes>
</ObjectListItem>
</items>
</List>
Controller:
onSearch : function(oEvent) {
var sFilteredValue = oEvent.getSource().getValue();
var oFilter = new sap.ui.model.Filter("Name", sap.ui.model.FilterOperator.Contains, sFilteredValue);
var oElement = this.getView().byId("table");
var oBinding = oElement.getBinding("items");
oBinding.filter([oFilter]);
}

You need to get binding of the items on which the filter need to be applied.
var oElement = this.getView().byId("master1List");
should resolve the issue.

Try to force an update of the control after setting the filter:
oBinding.refresh(true);

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.

SAP UI5 Dynamically switch between fragments

How do I dynamically switch between two fragments using click / press event?
I have the following XML fragment which in turn has nested two fragments:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<IconTabFilter
id="containerFrag"
text="{name}"
key="{id}">
<dependents>
<core:Fragment
fragmentName="com.example.fragments.fragment1"
type="XML" />
<core:Fragment
fragmentName="com.example.fragments.fragment2"
type="XML" />
</dependents>
</IconTabFilter>
</core:FragmentDefinition>
Assuming each fragment has a button who's handler has the following
buttonPress: function(oEvent) {
let oView = this.getView();
let showFrag1 = oEvent.getParameter("arguments"); //showFrag1 = true / false
let fragToShow = showFrag1 ? oView.byId("frag1Id").clone() : oView.byId("frag2Id").clone()
let container = oView.byId("containerFrag");
container.destroyContent();
container.addContent(fragToShow);
}
When I debug using chrome, fragToShow updates with the correct frag depending on the showFrag1 argument, but the view doesn't get updated - container.addContent(fragToShow) seems to have no effect except if I reload the page
Not sure why this works but I had to go one up from the container and insert the new fragment there like so:
let container = oView.byId("containerFrag");
container.getParent().destroyContent();
container.getParent().addContent(fragToShow);
This example also helped: https://ui5.sap.com/#/entity/sap.ui.layout.form.Form/sample/sap.ui.layout.sample.Form354 - though they use removeAllContent and insertContent, both seem to work just fine.
Thanks #D. Seah and #Ethan Jewett

How to set the input of a combobox to read-only

In one of my UI5-Dialogs, I implemented a combobox which is invisible when the screen is initially loaded.
In the method onAfterRendering, I start with setting the input to read-only:
onAfterRendering: function(oEvent) {
var oShovel = this.getView("View0200").byId("comboShovel");
oShovel.$().find("input").attr("readonly", true);
this.setVisibleByListKey();
},
After this the method setVisibleByListKey is called, the property visibleShovel will be set to false.
setVisibleByListKey: function(oEvent) {
var oModel = this.getView("View0200").getModel("Data0200");
this.setVisibleByListKey1(oModel);
// ...
},
setVisibleByListKey1: function(oModel) {
oModel.setProperty("/visibleShovel", false);
},
The property is bound to the attribute visible on my combobox.
Because of this behavior, the method onAfterRendering will be called again, the attribute readonly is not available (because of invisibility).
<ComboBox id="comboShovel"
editable="true"
enabled="true"
visible="{Data0200>/visibleShovel}"
valueState="None"
change=".changeCombo">
<items>
<core:Item text="Ja" enabled="true" key="0" />
<core:Item text="Nein" enabled="true" key="1" />
<core:Item text="Nicht erforderlich" enabled="true" key="2" />
</items>
</ComboBox>
I tried to call the set method in onInit or onBeforeRendering but at this time the input attributes can not be changed (because of invisibility again).
So how can I set the input of the combobox to read-only when I set the named visible property?
Solution would be either to use sap.m.Select or to implement a "change" event handler for the sap.m.Combobox and use a coding similar to this sample:
handleChange: function(oEvent) {
var oValidatedComboBox = oEvent.getSource();
var sSelectedKey = oValidatedComboBox.getSelectedKey();
var sValue = oValidatedComboBox.getValue();
if (!sSelectedKey && sValue) {
oValidatedComboBox.setValueState("Error");
oValidatedComboBox.setValueStateText("Please enter a valid country!");
} else {
oValidatedComboBox.setValueState("None");
}
},
Instead of using jquery, use UI5 control's methods and properties:
The sap.m.ComboBox borrows the following two methods from sap.m.InputBase:
setEditable
setEnabled
or since you are using property binding for the visibility, do the same for the editable property, e.g. {Data0200>/editableShovel}

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");
}

How can I add sort items into a fragment dialog?

I have this fragment retrieve by this page https://openui5.hana.ondemand.com/explored.html#/sample/sap.m.sample.TableViewSettingsDialog/code
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<ViewSettingsDialog
confirm="handleConfirm" id='viewSettingsDialogId'>
<sortItems id="sortItemsId">
<!-- <ViewSettingsItem text="Product" key="Name" selected="true" />
<ViewSettingsItem text="Supplier" key="SupplierName" />
<ViewSettingsItem text="Weight" key="WeightMeasure" />
<ViewSettingsItem text="Price" key="Price" /> -->
</sortItems>
</ViewSettingsDialog>
</core:FragmentDefinition>
I want insert manually the sortItems in the control (or by data-binding in the xml-View).
How can I do it?
I try to do it by code in my controller:
//IF CLICK ON SETTINGS BUTTON
handleViewSettingsDialogButtonPressed: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("apps.appIntra.fragment.settingDialog", this);
}
// toggle compact style
jQuery.sap.syncStyleClass("sapUiSizeCompact", this.getView(), this._oDialog);
this._oDialog.open();
var element=sap.ui.getCore().byId("sortItemsId");
this.byId('sortItemsId').addSortItem(new sap.m.ViewSettingsItem({text:"field1", key:"Price"}));
this.byId('sortItemsId').addSortItem(new sap.m.ViewSettingsItem({text:"field2", key:"PLUTO"}));
},
But it not work...
I see this guide http://scn.sap.com/community/developer-center/front-end/blog/2014/02/20/sapui5-dialogwith-businesscard-as-xml-fragment-along-with-controller
but if I use
var element=sap.ui.getCore().byId("sortItemsId");
element value is undefined
The addSortItem is a method that works on the ViewSettingsDialog and not on sortItems.
Therefore, as you have already provided the id viewSettingsDialogId for the ViewSettingsDialog control, in you controller you can do the following,
var oViewSettingsDialog = sap.ui.getCore().byId("viewSettingsDialogId");
oViewSettingsDialog.addSortItem(new sap.m.ViewSettingsItem({text:"field1",
key:"Price"}));
/* and so on... */
This would add the sort items into the sortItems list.