Filtering CustomListItem with checkbox in sap.m.List works but the checkbox lose their selected state on filtering - sapui5

The checkboxes in the CustomListItem lose their selected state as soon as I filter them, could someone please help me with it?
View:
<CustomListItem id="itemList">
<CheckBox class="sapUiTinyMarginBeginEnd" text="{name}" select="onSelectionChange"/>
</CustomListItem>
Controller:
const value: string = event.getParameter("newValue");
const list: sap.m.List = this.getView().byId("listToFilter") as sap.m.List;
const listBinding = list.getBinding("items") as sap.ui.model.json.JSONListBinding;
listBinding.filter([new sap.ui.model.Filter("name", sap.ui.model.FilterOperator.Contains, value)]);

You need to bind the 'selected' property of CheckBox in the same way as 'text'

Related

ComboBox in UI5 does not display ValueState

ComboBox is not showing state like Error, Warning with highlight around the borders. But it does change the state. For example, if it is error state, and if I try to enter new value in combobox, it will show that "invalid Entry" tip near the box. But the box borders are never highlighted in red. Below is the code:
XML.view
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:l="sap.ui.layout">
<Dialog id......>
<ComboBox id="combo1" change="cChanged" items="{path: '/results'}">
<items>
<core:Item key="{ID}" text="{Name}"/>
</items>
</ComboBox>
</Dialog>
Controller.js
cChanged: function(oEvent) {
var newval = oEvent.getParameter("newValue");
var key = oEvent.getSource().getSelectedItem();
if (newval !== "" && key === null) {
sap.ui.getCore().byId("combo1").setValueState("Error");
oEvent.getSource().setValue("");
sap.m.MessageToast.show("Please select from existing IDs")
flag = false;
} else {
oEvent.getSource().setValueState('None');
}
You can also access combo1 control instance by using oEvent.getSource() event OR use byId() from the sap.ui.core.Fragment class and not sap.ui.getCore().byId()
Also, if you are writing a logic only to validate if what the user input in the combobox is a valid item, consider replacing your ComboBox by the sap.m.Select control.
Both ComboBox and Select has same look and feel, but Select does not allow a manual input. It can also have an empty option if you use the property forceSelection

Radio Button Group: get text of selected radio button

I have sap.m.RadioButton group in my view:
<RadioButtonGroup select=".changeRegion">
<RadioButton id="rb-S" text="S" />
<RadioButton id="rb-MW" text="MW" />
<RadioButton id="rb-NE" text="NE" />
<RadioButton id="rb-W" text="W"/ >
</RadioButtonGroup>
In my controller:
changeRegion: function(e) {
console.log(e.getParameter("selectedIndex"));
},
I am able to access the index of the selected radio button. Is there any way to get the text of the selected radio Button?
That's definitely possible. You already have the index, now you just need the collection of radiobuttons and select the radionbutton with the corresponding index. Once you have that radiobutton, you can read it's text.
This is how it could be done:
var idx = e.getParameter("selectedIndex");
var button = e.getSource().getButtons()[idx];
var txt = button.getText();
Or in short:
var txt = e.getSource().getButtons()[e.getParameter("selectedIndex")].getText()
You can check out this jsbin to see it in action
The simplest way would be:
e.getSource().getSelectedButton().getText();
I think I found a different option to read the selected radio button text.. Just if someone needs it.
You need to set an Id to your Radio Button group, e.g:
<m:RadioButtonGroup id='radioButtonGroup' valueState="" select="changeRegion()">
<m:buttons>
<m:RadioButton id="rb-S" text="S"/>
<m:RadioButton id="rb-MW" text="MW"/>
<m:RadioButton id="rb-NE" text="NE"/>
<m:RadioButton id="rb-W" text="W"/>
</m:buttons>
Then you can get the Text from the selected radio button like this:
var text = sap.ui.getCore().byId(this.createId("radioButtonGroup")).getSelectedButton().getText();

Passing Data from Master to Detail Page

I watched some tutorials about navigation + passing data between views, but it doesn't work in my case.
My goal is to achieve the follwing:
On the MainPage the user can see a table with products (JSON file). (Works fine!)
After pressing the "Details" button, the Details Page ("Form") is shown with all information about the selection.
The navigation works perfectly and the Detail page is showing up, however the data binding doesnt seem to work (no data is displayed)
My idea is to pass the JSON String to the Detail Page. How can I achieve that? Or is there a more elegant way?
Here is the code so far:
MainView Controller
sap.ui.controller("my.zodb_demo.MainView", {
onInit: function() {
var oModel = new sap.ui.model.json.JSONModel("zodb_demo/model/products.json");
var mainTable = this.getView().byId("productsTable");
this.getView().setModel(oModel);
mainTable.setModel(oModel);
mainTable.bindItems("/ProductCollection", new sap.m.ColumnListItem({
cells: [new sap.m.Text({
text: "{Name}"
}), new sap.m.Text({
text: "{SupplierName}"
}), new sap.m.Text({
text: "{Price}"
})]
}));
},
onDetailsPressed: function(oEvent) {
var oTable = this.getView().byId("productsTable");
var contexts = oTable.getSelectedContexts();
var items = contexts.map(function(c) {
return c.getObject();
});
var app = sap.ui.getCore().byId("mainApp");
var page = app.getPage("DetailsForm");
//Just to check if the selected JSON String is correct
alert(JSON.stringify(items));
//Navigation to the Detail Form
app.to(page, "flip");
}
});
Detail Form View:
<mvc:View xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:f="sap.ui.layout.form" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" controllerName="my.zodb_demo.DetailsForm">
<Page title="Details" showNavButton="true" navButtonPress="goBack">
<content>
<f:Form id="FormMain" minWidth="1024" maxContainerCols="2" editable="false" class="isReadonly">
<f:title>
<core:Title text="Information" />
</f:title>
<f:layout>
<f:ResponsiveGridLayout labelSpanL="3" labelSpanM="3" emptySpanL="4" emptySpanM="4" columnsL="1" columnsM="1" />
</f:layout>
<f:formContainers>
<f:FormContainer>
<f:formElements>
<f:FormElement label="Supplier Name">
<f:fields>
<Text text="{SupplierName}" id="nameText" />
</f:fields>
</f:FormElement>
<f:FormElement label="Product">
<f:fields>
<Text text="{Name}" />
</f:fields>
</f:FormElement>
</f:formElements>
</f:FormContainer>
</f:formContainers>
</f:Form>
</content>
</Page>
</mvc:View>
Detail Form Controller:
sap.ui.controller("my.zodb_demo.DetailsForm", {
goBack: function() {
var app = sap.ui.getCore().byId("mainApp");
app.back();
}
});
The recommended way to pass data between controllers is to use the EventBus
sap.ui.getCore().getEventBus();
You define a channel and event between the controllers. On your DetailController you subscribe to an event like this:
onInit : function() {
var eventBus = sap.ui.getCore().getEventBus();
// 1. ChannelName, 2. EventName, 3. Function to be executed, 4. Listener
eventBus.subscribe("MainDetailChannel", "onNavigateEvent", this.onDataReceived, this);)
},
onDataReceived : function(channel, event, data) {
// do something with the data (bind to model)
console.log(JSON.stringify(data));
}
And on your MainController you publish the Event:
...
//Navigation to the Detail Form
app.to(page,"flip");
var eventBus = sap.ui.getCore().getEventBus();
// 1. ChannelName, 2. EventName, 3. the data
eventBus.publish("MainDetailChannel", "onNavigateEvent", { foo : "bar" });
...
See the documentation here: https://openui5.hana.ondemand.com/docs/api/symbols/sap.ui.core.EventBus.html#subscribe
And a more detailed example:
http://scn.sap.com/community/developer-center/front-end/blog/2015/10/25/openui5-sapui5-communication-between-controllers--using-publish-and-subscribe-from-eventbus
Even though this question is old, the scenario is still valid today (it's a typical master-detail / n-to-1 scenario). On the other hand, the currently accepted solution is not only outdated but also a result of an xy-problem.
is there a more elegant way?
Absolutely. Take a look at this Flexible Column Layout tutorial: https://sdk.openui5.org/topic/c4de2df385174e58a689d9847c7553bd
No matter what control is used (App, SplitApp, or FlexibleColumnLayout), the concept is the same:
User clicks on an item from the master.
Get the binding context from the selected item by getBindingContext(/*modelName*/).
Pass only key(s) to the navTo parameters (no need to pass the whole item context).
In the "Detail" view:
Attach a handler to the patternMatched event of the navigated route in the Detail controller's onInit.
In the handler, create the corresponding key, by which the target entry can be uniquely identified, by accessing the event parameter arguments in which the passed key(s) are stored. In case of OData, use the API createKey.
With the created key, call bindObject with the path to the unique entry in order to propagate its context to the detail view.
The relative binding paths in the detail view can be then resolved every time when the detail page is viewed. As a bonus, this also enables deep link navigation or bookmark capability.
You can also set local json model to store your data, and use it in the corresponding views. But be sure to initialize or clear it in the right time.

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.

UI5 MessageBox remain transparent

I have a message box that I want to do some extra editing on a line. But once I show it, it remains transparent. Is there something that I'm missing to give it a normal background.
The fragment for the form:
<Label text="UnitPrice"/>
<Input id='unitpriceid' type="Text" text="{path: 'UnitPrice' }"/>
<Label text="Quantity"/>
<Input type="Text" text="{path: 'Quantity' }"/>
</form:SimpleForm>
</core:FragmentDefinition>
How I call the fragment.
handleLineItemPress : function (evt) {
var context = evt.getSource().getBindingContext();
var oLayout = sap.ui.xmlfragment("ApproveSESComponent.DO_SES.view.LinePopup", this);
var oModelTemp = this.getView().getModel().getData();
// get the view and add the layout as a dependent. Since the layout is being put
// into an aggregation any possible binding will be 'forwarded' to the layout.
var oView = this.getView();
oView.addDependent(oLayout);
var that = this;
sap.m.MessageBox.show(oLayout, {
icon: sap.m.MessageBox.Icon.INFORMATION,
title: "My message box title",
styleClass: "sapUiSizeCompact",
actions: [sap.m.MessageBox.Action.YES, sap.m.MessageBox.Action.NO],
onClose: function(oAction) { / * do something * / }
});}
I change the styleClass: "sapUiSizeCompact" to soemthing else and then added a background-color to this style.
Then the box was no longer transperant.
I don't think sap.m.MessageBox is designed for input other than simple button-based choices. Certainly that's how I read the documentation (and that's how message boxes typically work in other APIs):
Provides easier methods to create sap.m.Dialog with type sap.m.DialogType.Message, such as standard alerts, confirmation dialogs, or arbitrary message dialogs.
You may be able to shoehorn it into allowing you to add an input field but I don't think that's how it's designed (it looks undocumented to me) and don't be surprised if it breaks in a future release. Rather use sap.m.Dialog.
Same problem here...
Solution: I used the sap.m.MessageBox in a project based on sap.ui.common elements. Replaced it with sap.ui.common.MessageBox and I had a well working Message Box.