How to fliter the filtered items in sap.m.list - sapui5

I alredy have an sap.m.list which is already filtered based on one property.Now I again need to apply filter for that list to implement live search.
filterList:function(evt){
debugger;
var filters = [];
var oFilter="";
var query = evt.oSource.mProperties.value;
if (query && query.length > 0) {
var filter = new sap.ui.model.Filter("CLTYPE", sap.ui.model.FilterOperator.Contains, query);
filters.push(filter);
var filter1 = new sap.ui.model.Filter("CLCAT", sap.ui.model.FilterOperator.Contains, query);
filters.push(filter1);
var filter2 = new sap.ui.model.Filter("CLNUM", sap.ui.model.FilterOperator.Contains, query);
filters.push(filter2);
oFilter = new sap.ui.model.Filter( filters, false );
}
// update list binding
var list = sap.ui.getCore().byId("List");
var binding = list.getBinding("items");
binding.filter(oFilter);
},
here my list is already filtered.here list.getBinding('items') will give me all the items not the filtered Items.I applied filter for my sap.m.list as follows
obj[filterParam] = context;
var contextClauses=_.where(clauses,obj);
sap.ui.getCore().getModel('ClauseModel').setProperty("/DATA/CURRENTCLAUSES",contextClauses);
// update list binding
var list = sap.ui.getCore().byId("List");
var binding = list.getBinding("items");
binding.filter(oFilter);
how to implement that??any suggestions?

Add livechange to your textfield and call a function to filter your list.
new sap.ui.commons.TextField({type:"Text",
value:"",
liveChange: function(oEvent){
//Now call a function to filter your list.
filterList(oEvent,oStorage.get("previousFilteredList"));
}});
filterList: function(oEvent,yourObj){
var like = oEvent.getParameter("liveValue");
var oFilter = new sap.ui.model.Filter("name",
sap.ui.model.FilterOperator.StartsWith,like);
var element = sap.ui.getCore().getElementById("sample");
var listBinding = element.getBinding("items");
listBinding.filter([oFilter]);
//Add the filtered object oStorage after every filter to access the previous filtered data
//oStorage.put("previousFilteredList","yourobj");
},
//Wherever you filter your data first.
oStorage = jQuery.sap.storage("session");
oStorage.put("previousFilteredList","yourobj");

I think you have 2 options:
Apply the original filter and then the additional filters.
Make a new instance of the initially filtered list:
// assumes you have declared lists (initialList and newList)
// values between <..> should be replaced
jQuery.each (initialList, function (index, item) {
if (item.<someField> == <somevalue>) {
// you could add an additional field to the new list item like so:
item["<newFieldName"] = <newValue>;
if (item.<someOtherField> >= <someOtherValue>) {
newList.push(item); // adds this item to the new array / list
}
}
newListModel.setData(newList); // assumes newListModel has been created
//bind to control

I solved it using the 'and' condition in filter
var mainFilter=new sap.ui.model.Filter(parameter,sap.ui.model.FilterOperator.Contains,context);
var query =evt.getParameter("newValue");
if (query && query.length > 0)var filter1= new sap.ui.model.Filter("CLNAME",sap.ui.model.FilterOperator.Contains,query);
filtersArr1.push(filter1);
filtersArr1.push(mainFilter);
var filter2 = new sap.ui.model.Filter("CLNUM",sap.ui.model.FilterOperator.Contains, query);
filtersArr2.push(filter2);
filtersArr2.push(mainFilter);oFilter1 = new sap.ui.model.Filter(filtersArr1,true);oFilter2 = new sap.ui.model.Filter(filtersArr2,true);filterGroup.push(oFilter1,oFilter2);oFilter4 = new sap.ui.model.Filter(filterGroup,false);
binding.filter(oFilter4);
WORKING FINE

var listFilter=new sap.ui.model.Filter(parameter,sap.ui.model.FilterOperator.Contains,context);
var query =evt.getParameter("newValue");
if (query && query.length > 0)
var filter1= new sap.ui.model.Filter({
new sap.ui.model.Filter("CLNAME",sap.ui.model.FilterOperator.Contains,query),
new sap.ui.model.Filter("CLNUM",sap.ui.model.FilterOperator.Contains, query)}, and:false),
var oFilter = new sap.ui.model.Filter( [filter1, listFilter], true)
binding.filter(oFilter);
});

Related

How to modify the available filter operators of a smart table

I have a smart table that shows data from odata service. all properties of the entity type are Edm.String.
now i can set a filter for each column of the resulting table with a lot of filter operators.
My goal is to filter the list of available filter operators depending on the selected column.
e.g.
selected colum 'A' then allow only 'equal to'.
Is that somehow possible? I would like to solve it in front end code.
I didn't find anything like that in ui5 docu...
you need to use equals FilterOperator
here is a link for FilterOperator and another example how to use filter in grid table https://sapui5.hana.ondemand.com/
Here is a quick example of setting more than one filter each with different Filter Operator
filterGlobally : function(oEvent) {
var sQuery = oEvent.getParameter("query");
this._oGlobalFilter = null;
if (sQuery) {
this._oGlobalFilter = new Filter([
new Filter("columA", FilterOperator.EQ, sQuery),
new Filter("columB", FilterOperator.Contains, sQuery)
], false);
}
var oFilter = null;
if (this._oGlobalFilter) {
oFilter = new Filter([this._oGlobalFilter], true);
}
this.byId("idTable").getBinding().filter(oFilter, "Application");

How to sort all the data by date in google apps script?

I have retrieved the data from REST API and inserted into google apps script but i am not sure how to sort the data based on the subscription date. I have used the sort() but it is only sorting one column instead of everything. This is my current code and screenshot so far:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("test")
var apiKey = 'test';
var URL_STRING = "";
var url = URL_STRING + "?ApiKey=" + apiKey;
var response = UrlFetchApp.fetch(url);
var json = response.getContentText();
var data = JSON.parse(json);
var firstname = [];
var lastname = [];
var subscriptionDate = [];
for (var i=0;i<data.output.o1.length;i++){
fn=(data.output.o1[i].first_name);
firstname.push([fn]);
ln=(data.output.o1[i].last_name);
lastname.push([ln]);
sd=(data.output.o1[i].subscription_date);
subscriptionDate.push([sd]);
};
mainSheet.getRange(2, 1, firstname.length).setValues(firstname);
mainSheet.getRange(2, 2, lastname.length).setValues(lastname);
mainSheet.getRange(2, 3, subscriptionDate.length).setValues(subscriptionDate);
}
In this case, how about sorting the values when the array for putting to Spreadsheet is created? When this is reflected to your script, it becomes as follows.
From:
var firstname = [];
var lastname = [];
var subscriptionDate = [];
for (var i=0;i<data.output.o1.length;i++){
fn=(data.output.o1[i].first_name);
firstname.push([fn]);
ln=(data.output.o1[i].last_name);
lastname.push([ln]);
sd=(data.output.o1[i].subscription_date);
subscriptionDate.push([sd]);
};
mainSheet.getRange(2, 1, firstname.length).setValues(firstname);
mainSheet.getRange(2, 2, lastname.length).setValues(lastname);
mainSheet.getRange(2, 3, subscriptionDate.length).setValues(subscriptionDate);
To:
var values = data.output.o1.map(({first_name, last_name, subscription_date}) => [first_name, last_name, subscription_date]);
values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? 1 : -1);
mainSheet.getRange(2, 1, values.length, values[0].length).setValues(values);
When values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? 1 : -1); is modified to values.sort((a, b) => new Date(a[2]).getTime() > new Date(b[2]).getTime() ? -1 : 1);, the order of sort direction is changed.
Note:
As other method, when the following script to the bottom of your current script, the sort is run with the column "C".
mainSheet.getRange("A2:C").sort([{ column: 3, ascending: true }]);
In this answer, from your sample image, I supposed that your column "C" is the date object.
References:
map()
sort()
sort(sortSpecObj)
mainSheet.getRange(2,1,mainSheet.getLastRow()-1,3).sort({column:3,ascending:true});

Error filtering in SAPUI5 data type not allowed

I am adding multiple search filters in my Query App, but the fields of type SAPB1.BoYesNoEnum of the Metadata of the services layer, throw me an error when filtering.
EntitySet BusinessPartners property
<Property Name="Valid" Type="SAPB1.BoYesNoEnum"/> = tYes/tNo
Filter event:
onSearch: function(oEvent) {
var oFilterModel = this.getView().getModel("filters");
var sID = oFilterModel.getProperty("/id");
var sName = oFilterModel.getProperty("/name");
var sStatus = oFilterModel.getProperty("/status");
var aFilters = [];
if( sID ) {
aFilters.push( new Filter("CompanyName", FilterOperator.Contains, sID.toUpperCase()) );
}
if( sStatus ) {
aFilters.push( new Filter("Valid", FilterOperator.EQ, sStatus.toUpperCase()) );
}
this.byId("idPartnerTable").getBinding("items").filter(aFilters);
},
The other filters, ID, Name, work perfectly
Console Error
Failed to get contexts for /destinations/miruta/BusinessPartners with start index 0 and length 5 - Error: Unsupported type: SAPB1.BoYesNoEnum

Remove Filter from table in SAP UI5

I want to display all table records when is there is filter field is empty or blank. Whenever there is value in USER Field, data is getting filtered based on value. Now I want to display all records if USER field is blank or empty.
Could you please help.
Below is the code
onSettingsSaveBtn: function (oEvent) {
var oModel = this._oSettingsDialog.getModel("SettingsContext"),
oData = oModel.getData(),
user = oData.StoreID;
var aTableSearchState = [];
aTableSearchState = [new Filter("DeliveryStatus", "EQ", user)];
var oBinding = this._oTable1.getBinding("items");
this._oSettingsDialog.close();
if (user === "") {
}
else {
oBinding.filter(aTableSearchState,"Application");
}
}

How to implement search with multiple filters using lucene.net

I'm new to lucene.net. I want to implement search functionality on a client database. I have the following scenario:
Users will search for clients based on the currently selected city.
If the user wants to search for clients in another city, then he has to change the city and perform the search again.
To refine the search results we need to provide filters on Areas (multiple), Pincode, etc. In other words, I need the equivalent lucene queries to the following sql queries:
SELECT * FROM CLIENTS
WHERE CITY = N'City1'
AND (Area like N'%area1%' OR Area like N'%area2%')
SELECT * FROM CILENTS
WHERE CITY IN ('MUMBAI', 'DELHI')
AND CLIENTTYPE IN ('GOLD', 'SILVER')
Below is the code I've implemented to provide search with city as a filter:
private static IEnumerable<ClientSearchIndexItemDto> _search(string searchQuery, string city, string searchField = "")
{
// validation
if (string.IsNullOrEmpty(searchQuery.Replace("*", "").Replace("?", "")))
return new List<ClientSearchIndexItemDto>();
// set up Lucene searcher
using (var searcher = new IndexSearcher(_directory, false))
{
var hits_limit = 1000;
var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
// search by single field
if (!string.IsNullOrEmpty(searchField))
{
var parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, searchField, analyzer);
var query = parseQuery(searchQuery, parser);
var hits = searcher.Search(query, hits_limit).ScoreDocs;
var results = _mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
else // search by multiple fields (ordered by RELEVANCE)
{
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, new[]
{
"ClientId",
"ClientName",
"ClientTypeNames",
"CountryName",
"StateName",
"DistrictName",
"City",
"Area",
"Street",
"Pincode",
"ContactNumber",
"DateModified"
}, analyzer);
var query = parseQuery(searchQuery, parser);
var f = new FieldCacheTermsFilter("City",new[] { city });
var hits = searcher.Search(query, f, hits_limit, Sort.RELEVANCE).ScoreDocs;
var results = _mapLuceneToDataList(hits, searcher);
analyzer.Close();
searcher.Dispose();
return results;
}
}
}
Now I have to provide more filters on Area, Pincode, etc. in which Area is multiple. I tried BooleanQuery like below:
var cityFilter = new TermQuery(new Term("City", city));
var areasFilter = new FieldCacheTermsFilter("Area",areas); -- where type of areas is string[]
BooleanQuery filterQuery = new BooleanQuery();
filterQuery.Add(cityFilter, Occur.MUST);
filterQuery.Add(areasFilter, Occur.MUST); -- here filterQuery.Add not have an overloaded method which accepts string[]
If we perform the same operation with single area then it's working fine.
I've tried with ChainedFilter like below, which doesn't seems to satisfy the requirement. The below code performs or operation on city and areas. But the requirement is to perform OR operation between the areas provided in the given city.
var f = new ChainedFilter(new Filter[] { cityFilter, areasFilter });
Can anybody suggest to me how to achieve this in lucene.net? Your help will be appreciated.
You're looking for the BooleanFilter. Almost any query object has a matching filter object.
Look into TermsFilter (from Lucene.Net.Contrib.Queries) if your indexing doesn't match the requirements of FieldCacheTermsFilter. From the documentation of the later; "this filter requires that the field contains only a single term for all documents".
var cityFilter = new FieldCacheTermsFilter("CITY", new[] {"MUMBAI", "DELHI"});
var clientTypeFilter = new FieldCacheTermsFilter("CLIENTTYPE", new [] { "GOLD", "SILVER" });
var areaFilter = new TermsFilter();
areaFilter.AddTerm(new Term("Area", "area1"));
areaFilter.AddTerm(new Term("Area", "area2"));
var filter = new BooleanFilter();
filter.Add(new FilterClause(cityFilter, Occur.MUST));
filter.Add(new FilterClause(clientTypeFilter, Occur.MUST));
filter.Add(new FilterClause(areaFilter, Occur.MUST));
IndexSearcher searcher = null; // TODO.
Query query = null; // TODO.
Int32 hits_limit = 0; // TODO.
var hits = searcher.Search(query, filter, hits_limit, Sort.RELEVANCE).ScoreDocs;
What you are looking for is nested boolean queries so that you have an or (on your cities) but that whole group (matching the or) is itself matched as an and
filter1 AND filter2 AND filter3 AND (filtercity1 OR filtercity2 OR filtercity3)
There is already a good description of how to do this here:
How to create nested boolean query with lucene API (a AND (b OR c))?