How to add a Autofill filter in FilterBar - sapui5

I'm trying to implement filters using SAPUI5 FilterBar. I want to add a field which works like a dropdown filter only when you type something in it. When you put the cursor, it should not show any results, but as you start typing something, the matching results should show up in the dropdown.

Here is a working example: Plunker
You could use a Input object in the filterGroupItems aggregation of the FilterBar control.
Note: The filterItems aggregation is deprecated as of version 1.48
<fb:FilterBar id="filterBar">
<fb:filterGroupItems>
<fb:FilterGroupItem
groupName="GroupExample"
name="regionGroup"
label="Example"
visibleInFilterBar="true">
<fb:control>
<Input showSuggestion="true">
<suggestionItems>
<core:Item key="001" text="Russia"/>
<core:Item key="002" text="America"/>
<core:Item key="003" text="Australia"/>
<core:Item key="004" text="Germany"/>
</suggestionItems>
</Input>
</fb:control>
</fb:FilterGroupItem>
</fb:filterGroupItems>
</fb:FilterBar>
Which produces:
Be sure to add the visibleInFilterBar="true" attribute if you want your input field to be visible without having to add it in the Filters prompt.
If you want to add the Input items dynamically, add an aggregation binding to the <items>.
To do that, change the Input control as follows:
<Input suggestionItems="{path: '/dropdownData'}" showSuggestion="true">
<suggestionItems>
<core:Item key="{key}" text="{text}"/>
</suggestionItems>
</Input>
And set the model according to your datasource (here it's a JSONModel) in the controller:
onInit: function() {
this.oModel = new JSONModel("/data.json");
var oView = this.getView();
oView.setModel(this.oModel);
}

Related

How to customize the "sap.ui.comp.filterbar.FilterBar" control?

I developed a SAPUI5 page with a list of items and a search feature using the control sap.ui.comp.filterbar.FilterBar. The framework defines automatically a text for the button which triggers the search and also for a placeholder that appears as default in the search field.
I would like to customize this in order to have better control of its content and a better multi language management with i18n settings. How can I do this customization? I looked at the documentation but it does not mention a property which I can easily make this change.
Follows a piece of code that implements this part of the View
<!-- ... -->
<fb:FilterBar xmlns:fb="sap.ui.comp.filterbar" xmlns="sap.m" xmlns:core="sap.ui.core"
id="filterBar"
search=".onSearch"
showRestoreButton="false"
showClearButton="true"
showFilterConfiguration="false"
>
<fb:filterGroupItems>
<fb:FilterGroupItem
groupName="__$INTERNAL$"
name="A"
label="{i18n>workstreamsOptions}"
partOfCurrentVariant="true"
visibleInFilterBar="true"
>
<fb:control>
<ComboBox id="WorkStreamCombobox" change=".onChange">
<core:Item key="001" text="{i18n>ws1}" />
<core:Item key="002" text="{i18n>ws2}" />
<core:Item key="003" text="{i18n>ws3}" />
<core:Item key="004" text="{i18n>ws4}" />
<core:Item key="005" text="{i18n>ws5}" />
<core:Item key="006" text="{i18n>ws6}" />
<core:Item key="007" text="{i18n>ws7}" />
<core:Item key="008" text="{i18n>ws8}" />
<core:Item key="009" text="{i18n>ws9}" />
</ComboBox>
</fb:control>
</fb:FilterGroupItem>
<fb:FilterGroupItem
groupName="__$INTERNAL$"
name="B"
label="{i18n>typeOfInterface}"
labelTooltip="Tooltip Example"
partOfCurrentVariant="true"
visibleInFilterBar="true"
>
<fb:control>
<ComboBox id="TypeCombobox" change=".onChange">
<core:Item key="001" text="{i18n>typeInbound}" />
<core:Item key="002" text="{i18n>typeOutbound}" />
<core:Item key="003" text="{i18n>typeNotClassified}" />
</ComboBox>
</fb:control>
</fb:FilterGroupItem>
</fb:filterGroupItems>
</fb:FilterBar>
<!-- ... -->
If I understood it correctly you are looking to overwrite and customize the placeholder for the default search ..
It can be controlled by the following code.
onToggleSearchField: function (oEvent) {
var oSearchField = this.oFilterBar.getBasicSearch();
var oBasicSearch;
if (!oSearchField) {
oBasicSearch = new SearchField({
showSearchButton: false,
placeholder:"Custom Placeholder"
});
} else {
oSearchField = null;
}
this.oFilterBar.setBasicSearch(oBasicSearch);
oBasicSearch.attachBrowserEvent("keyup", function (e) {
if (e.which === 13) {
this.onSearch();
}
}.bind(this)
);
},
and Initialize the onToggleSearchField() in your onInit() function.
Customizing the same via i18n... Set your text in your i18n and control the placeholder accordingly using the following logic.
this.getView().getModel('i18n').getResourceBundle().getText(
'Your PlaceHolder Name from i18n')
Thanks,
Abhi

SAP UI5 : Unable to bind a controller variable in xml

Button on click of which the variable is getting changed:
<f:content>
<Button icon="sap-icon://edit" press="editClick" type="Transparent"></Button>
</f:content>
xml code where i need 2-way binding:
<VBox class="sapUiSmallMargin">
<form:SimpleForm id="SimpleFormDisplayColumn_oneGroup">
<form:content>
<Label text="{i18n>contextofusage}"/>
<Text text="{contextofusagetext}" visible="{!isInfoEditable}"/>
<Input type="Text" visible="{isInfoEditable}" value="{contextofusagetext}"></Input>
</form:content>
</form:SimpleForm>
</VBox>
controller:
var isInfoEditable=false;
return Controller.extend("abc.controller.Detail", {
editInfoClick: function(event){
if(isInfoEditable){
isInfoEditable=false;
}
else{
isInfoEditable=true;
}
}
});
It seems like you have tried nothing, but I will try to guide you:
You cannot simply declare a variable in your controller and then use it in your view. That's not how UI5 works. Instead create a model and bind it to your view. I also give my models a name, in this case "view":
onInit: function() {
var oViewModel = new sap.ui.model.json.JSONModel({
isInfoEditable: false
});
this.getView().setModel(oViewModel, "view");
}
Then use it in your view. Make sure that you use the name of your model ("view") in your bindings. If you want to do more than simply use the raw value (e.g. negate it) you have to use expression binding. Also you have to use an absolute path starting with /:
<form:SimpleForm id="SimpleFormDisplayColumn_oneGroup">
<form:content>
<Label text="{i18n>contextofusage}"/>
<Text text="{contextofusagetext}" visible="{= !${view>/isInfoEditable} }"/>
<Input type="Text" visible="{view>/isInfoEditable}" value="{contextofusagetext}"></Input>
</form:content>
</form:SimpleForm>
When you click on the button you have to modify/toggle the value in your model:
editClick: function (oEvent) {
var oViewModel = this.getView().getModel("view");
var bIsEditable = oViewModel.getProperty("/isInfoEditable");
// negate the current value and set it as the new value
oViewModel.setProperty("/isInfoEditable", !bIsEditable);
}
I suggest strongly reading on the basics of UI5. Your approach looks more like Vue.js, but UI5 has its own paradigms.

Input assisted doesn't show all suggestions

I have input field i need suggest items from odata model.
<Input
id="productInput"
type="Text"
placeholder="Enter Product ..."
showSuggestion="true"
showValueHelp="true"
valueHelpRequest="handleValueHelp"
suggestionItems="{/ProductCollection}" >
<suggestionItems>
<core:Item text="{Name}" />
</suggestionItems>
</Input>
the problem is there are missing items : not all items are displayed (you can check this link
https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.InputAssisted/preview
it is the same behaviour when you put a for example it shows some items in the search it shows more with a )
What you are trying to do is basically show all items that contains the value in the input. SAPUI5 has a convenient filter for this called sap.ui.model.FilterOperator.Contains.
The problem with the sap.m.Input is that it will only work one way, even if you manually set the Contains filter in the Suggest event, it will show suggestions that will start with the provided letter instead, just like sap.ui.model.FilterOperator.StartsWith filter operator. That's why it is showing you less suggestions.
Using the same products.json model in your question, we can do the following:
XML Input:
<Label text="Product" labelFor="productInput"/>
<Input
id="productInput"
type="Text"
placeholder="Enter Product ..."
showSuggestion="true"
showValueHelp="false"
suggest="handleSuggest"
suggestionItems="{productsModel>/ProductCollection}" >
<suggestionItems>
<core:Item text="{productsModel>Name}" />
</suggestionItems>
</Input>
Controller:
handleSuggest: function (oEvent) {
var aFilters = [];
var sTerm = oEvent.getParameter("suggestValue");
if (sTerm) {
aFilters.push(new sap.ui.model.Filter("Name", sap.ui.model.FilterOperator.Contains, sTerm));
}
oEvent.getSource().getBinding("suggestionItems").filter(aFilters);
//do not filter the provided suggestions before showing them to the user - important
oEvent.getSource().setFilterSuggests(false);
}
It is very important to set the setFilterSuggests() method to false in order not to filter the provided suggestions before showing them to the user, this would go against we just did previously.
Using this approach, the suggested item will show only those values filtered by the specified filter condition which is sap.ui.model.FilterOperator.Contains.
Other SAPUI5 Filter Operators

Add button in sap.m.list row

I want to add buttons to each row in my sap.m.List. On that button I want to open a popup to display further details without navigating to another page.
Any code snippet or examples out there how I can add buttons to each row and bind them to fetch data from another model.
Instead of the StandardListItem you need a CustomListItem. There you can add any control you like:
<List headerText="Custom Content" items="{path: '/ProductSet'}" >
<CustomListItem>
<HBox>
<Label text="{ProductName}"/>
<Button text="More Infos" click="onPressMoreInfos" />
</HBox>
</CustomListItem>
</List>
I think the tricky part here is the binding. One CustomListItem is bound to a single entity of your set. If you add a Button to your CustomListItem (or any other control) they are also automatically bound to the specific entity.
So in your click handler you can do the following:
onPressMoreInfos: function(oEvent) {
var oButton = oEvent.getSource();
// if your model has a name, don't forget to pass it as a parameter
var oContext = oButton.getBindingContext();
// create the popover, either here or in a new method
var oPopover = this.getTheInfoPopover();
// if your model has a name, don't forget to pass it as the second parameter
oPopover.setBindingContext(oContext);
}
Then your Popover has the same binding information as the list item and you can access every property of the specific entity.
Try below code to add a button to each row, in your XML view:
<columns>
<Column id="userNameColumn">
<Text text="userNameLabelText" />
</Column>
<Column id="buttonColumn">
<Text text="Button" />
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Input value="{UserName}"/>
</cells>
<Button id="buttonId" icon="sap-icon://add" press="handleResponsivePopoverPress"></Button>
</ColumnListItem>
</items>
Controller to handle button press, see example here
https://sapui5.hana.ondemand.com/#/sample/sap.m.sample.ResponsivePopover/preview
You can use sap.m.CustomListItem as a template for items aggregation. There is a sample here. You can add any control to the item.

Data Binding from TableSelectDialog to Form

I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
onInit: function () {
// 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);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.