Angular6 Dynamic Array Filter ( TypeScript ) - arrays

I have a question about dynamicly filter array.. I making a table and I have different filtering options. For example ; Only selected column filter, MultiSelect dropdown menu filter and ı want filter multiple columns . my table
For Example ;
Write a filter word in Brand filter. This code line is filtered my data. (veri = data. (in Turkish) ).
public filter(str, i) {
const collName = this.bizimKolon[i].Baslik; // Column Name
this.veri = this.yedekVeri.filter(x => x[collName].toString().toLowerCase().includes(str.toLowerCase())); }
I want to filter the filtered data by year but is not working. And I have a more problem. We were suppose filtered Brand and Year. if the filter word we wrote is in the array, update my array and display into table. OK. No problem. We select colors in dropdown menu. After we want filter by colors ( White and Green ). How we make do this? I don't know how many data will come to filter. in this point we need to dynamic filter. Please help me. thank you..

x[colName] should work.
#Pipe({name: 'dataListFilterPipe'})
export class DataListFilterPipe implements PipeTransform {
transform(data: any, col: string, value: string): any {
if (data !== undefined) {
return data.filter(x => x[col] == value);
}
}
}
I created a pipe in which list is filtered and it works. This is in angular 6

here is my example for filtering by many inputs:
applyFilter() {
let custs = this.ch.customers.filter((cust: Customer) => {
return (
((cust.name.toLowerCase().trim().indexOf(this.filters[0]) !== -1) || (!this.filters[0])) &&
((!this.filters[5]) || (cust.user.username.toLowerCase().trim().indexOf(this.filters[5]) !== -1)) &&
((!this.filters[2]) || (cust.state.name.toLowerCase().trim().indexOf(this.filters[2]) !== -1)) &&
((!this.filters[1]) || (cust.description.toLowerCase().trim().indexOf(this.filters[1]) !== -1)) &&
((!this.filters[3]) || (cust.last_mess.toLowerCase().trim().indexOf(this.filters[3]) !== -1))
);
});
this.dataSource.data = custs;
this.ch.customers_filter = this.dataSource.data;
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
Variable Filter is array of string.

Related

Store textbox input to an array

I want to store all the input data of the textbox to an array with unique index number each so I can control them. The problem is that it only assigns zero index for all of them.
todoField.addEventListener('keypress', function (b) {
if (b.key === 'Enter' && todoField.value != 0) {
let newtodo = todoField.value
task = [newtodo]
}
}
declear a function outside the addEventListener and push the new items to the function that will give them a unique id and store them too.
this is how you should do it.
tasks = []; // array decleartion
todoField.addEventListener('keypress', function (b) {
if (b.key === 'Enter' && todoField.value != 0) {
let newtodo = todoField.value
tasks.push(newtodo);
} }
Now tasks array will contain all your tasks.
thank you.

Querying based on multiple fields from firestore

I have a "hackathon" model that looks like this:
I need to paginate the data, but right now I'm querying the database based on the amountInPrizes range and a list of tags set by the user on the frontend first, and then filtering the array manually based on the rest of the fields specified by the user (since firestore doesn't allow multiple inequality queries on different fields and I couldn't find another way around it)
Here's what the route looks like:
const {minPrize, maxPrize, inPerson, online, startDateString, endDateString, tags} = req.query;
try {
let hackathonQuery = db.collection("hackathons");
if (minPrize && minPrize !== "") {
hackathonQuery = hackathonQuery.where("amountInPrizes", ">=", Number.parseInt(minPrize));
}
if (maxPrize && maxPrize !== "") {
hackathonQuery = hackathonQuery.where("amountInPrizes", "<=", Number.parseInt(maxPrize));
}
if (tags && tags !== "") {
const tagsList = tags.split(",");
if (tagsList.length >= 1) {
hackathonQuery = hackathonQuery.where("tags", "array-contains-any", tagsList);
}
}
// this is where the pagination should be, but there's still a bunch of manual filters after, so the pagination wouldn't be accurate
const hackathonsSnapshot = await hackathonQuery.orderBy("amountInPrizes", "desc").get();
const hackathons = [];
hackathonsSnapshot.forEach(doc => {
const hackathon = doc.data();
if (startDateString && startDateString !== "") {
const startDate = new Date(startDateString);
if (new Date(hackathon.startDate).getTime() < startDate.getTime()) {
return;
}
}
if (endDateString && endDateString !== "") {
const endDate = new Date(endDateString);
if (new Date(hackathon.endDate).getTime() > endDate.getTime()) {
return;
}
}
if (inPerson && inPerson === "true") {
// to make it so that if both are selected it queries correctly
if (online !== "true") {
if (hackathon.location == "Online") {
return;
}
}
}
if (online && online === "true") {
// to make it so that if both are selected it queries correctly
if (inPerson !== "true") {
if (hackathon.location !== "Online") {
return;
}
}
}
hackathons.push({
id: doc.id,
...hackathon,
})
})
return res.status(200).json({hackathons});
} catch (err) {
console.log(err.message);
res.status(400).send("Server error");
}
If I were to add a .limit() on my initial query, an inconsistent number of documents would be filtered out by the rest of the manual filters on each page of hackathons. Is there a way around this or a better way to do this whole thing?
(Sorry if that explanation was confusing)
If you really need full flexibility on the user input, then there is no way around it.
If you can change the model and change the user interface a bit there are some things you can do:
add onlineLocation: boolean to the model and when saving the document set it to true/false according to the data. This will eliminate your online filtering and will allow you to add a where... to the query (you will not need to use the inequality).
Date range - as I understand the user can select a start date. If it is acceptable to change the interface to allow the user to select from predefined values (like: last week, last month, last year... etc.) what you can do is save in addition to the start date:
startDayIndex = Math.floor(startDate.getTime() / millisecondsInDay)
this results in the day index since Jan 1st 1970
startWeekIndex = Math.floor(startDate.getTime() / millisecondsInWeek)
this results in the week index since Jan 1st 1970
etc...
this will allow you to query firestore with equality query (get all documents that the start date is 3 weeks ago)
I'm not sure if this is applicable for your use case.
If the date range is important to keep as is, you can change the amountInPrizes to be ranges instead of numbers. This way the user can get all documents that the amountInPrizes is between 1000-2000 for example.
again you will need to add a field to your model, say: prizeRange, and query that field with equality query, leaving the date in range query

Search/Filter a table in React: Replace null values with an empty string

I made a simple search function for filtering through a datatable filled with JSON objects from an API.
It works for most tables in my application but will crash it if any of the objects in the table have a null value.
my search function looks like this:
const search = (rows) => {
const columns = rows[0] && Object.keys(rows[0]);
return rows.filter((row) =>
columns.some(
(column) =>
row[column]
.toString()
.toLowerCase()
.indexOf(q.toString().toLowerCase()) > -1
)
);
};
I just want to replace any null values in the objects with an empty string.
Can anyone help me with this in a simple way?
Try this:
let newRows = rows.map((row) =>
columns.map(
(column) => columns || "" // return column if non empty else return ""
));
};
console.log("newRows", newRows) // rows with empty string

material-table: How to make a summary row?

How can I make a summary row like this using a material table?
Please help me, thank you.
If by "Summary row" you're referring to table title, that's a prop "title" you just add to the <MaterialTable /> component.
However, I suspect you need the row with Total result, which I couldn't find in the examples, either.
Here's a custom function you could use to calculate a total by your own, add it to your data set and achieve similar result:
const addTotal = (data, byColumn) => {
let keys = Object.keys(data[0]);
let total = data.reduce((acc, el) => {
return acc += +(el[byColumn]);
}, 0);
let totalRow = {};
let emptyRow = {};
for (let key of keys) {
if (key === keys[0]) {
totalRow[key] = 'Total';
} else if (key === byColumn) {
totalRow[key] = total;
} else {
totalRow[key] = '';
}
emptyRow[key] = '';
}
return [...data, emptyRow, totalRow];
}
This will add an empty row and a total with the argument you put as byColumn. You need to be careful about the values you are summing (i.e. add type checking or validate the column name with hasOwnProperty).
I might be a little late, but here’s another question that reminded me that material table happen to have a footer row api.
You can use it alongside a specific method to sum values (or else) that you can call before setting the datasource for example, or on demand.

ExtJS - Grid filter with multiple columns and multiple values

I create a grid and a toolbar with Two Menu of menuCheckItem. When i check the menuCheckItem the grid filters even with multiple values and multiple columns.
This working fine, as I have created grid 1st and then the toolbar
this.up('') // Used Instead of Ext.getCmp()
Working FIDDLE - https://fiddle.sencha.com/#view/editor&fiddle/2lop
Now I am trying to create same toolbar along with Menu separately on top 1st and then create grid at below. But while doing this, nly Multiple values is working.
I am trying to filter grid with multiple values as well as multiple columns.
Few things i tried -
// Only Filters One Value at a time with each Columns
store.queryBy(function(record,id){
return (record.get('name') == someValue && record.get('phone') == otherValue);
});
and
// Filters Many Columns with Single Value
filter.add(
property : name, phone
value : "somevalue"
operator : "OR"
);
Is there any way to implement Toolbar 1st and then grid ? And Filter grid with many values and columns simultaneously ?
In this FIDDLE i remade a function(checkchange), which is universal , can be put separately and you'll be able to attach it to every menucheckitem you create. The only thing is that if you add new menucheckitem filter you should name the menucheckitem id with the name of the columnDataIndex-Menu and add this columnDataIndex in menuFilters and thats all.
checkchange: function (checkbox, checked, eOpts) {
var menuFilters = ['name', 'phone'];
var getChecked = function (m) {
var checkedItems = [];
m.items.items.forEach(function (c) {
if (c.checked) {
checkedItems.push(c.text);
}
});
return checkedItems;
};
//
var menus = new Map();
menuFilters.forEach(function (e) {
menus.set(e, Ext.getCmp(e + '-Menu'));
});
//
var fieldValues = [];
menuFilters.forEach(function (e) {
fieldValues.push([e, getChecked(menus.get(e))]);
});
//
var store = checkbox.up('grid').store;
store.clearFilter();
//
if (fieldValues.length > 0) {
store.filterBy(function (record) {
var fV = this.fieldValues;
for (var i = 0; i < fV.length; i++) {
if (fV[i][1].length > 0) {
if (fV[i][1].indexOf(record.get(fV[i][0])) === -1) {
return false;
}
}
}
return true;
}, {
fieldValues: fieldValues
});
}
}

Resources