Dynamically add filter in ng-repeat - angularjs

I am building a table where the rows and columns are built entirely based on the data that is sent to it.
I'm very close to having it work, I'm having trouble figuring out how to build a custom filter and pass in the filter patterns dynamically
The object that makes up the columns looks like
{ name: 'transactionDate', displayName: 'Date / Time', displayOrder: 1, filter: "date: 'MM/dd/yy hh:mm a'" }
The object that makes up the transaction for the rows looks like this:
{ transactionDate: '2015-06-11', transactionType: 'This Type', transactionAmount: 25 }
The HTML I have is this:
<td ng-repeat="col in columns">{{transaction[col.name] | dynamicFilter: col.filter}}</td>
The filter I currently have built is:
function dynamicFilter($filter) {
return function (value, filter) {
console.log(filter);
console.log(value);
var test = $filter(filter)(value);
return test;
}
}
Both filter and value are getting passed correctly. I'm having trouble figuring out how to apply the filter to the value before returning. A value that might be passed in would 2015-06-10T16:17:14 be and a filter that would be passed in could be date: 'MM/dd/yy hh:mm a' to create date/time filter. Or 21 and currency for a dollar value.
I would like to be able to use Angular's built in features in a similar way you could on the view

For these dynamic filters that have partial params (such as the format you're providing with date), you have to remove the param from the filter and apply it later.
So filter: "date: 'MM/dd/yy hh:mm a'", needs to be just filter: "date".
The additional constraint, MM/dd/yy hh:mm a, would be sent along with the value $filter(filter)(value, 'MM/dd/yy hh:mm a');
To do this generically, you can take advantage of apply. The Object can be:
{filter: { type: "date", params: ['MM/dd/yy hh:mm a'] } }
And the directive can have (assuming you send the params as well):
var filterFn = $filter(filter.type);
return filterFn.apply(filterFn, [value].concat(filter.params));
EDIT: here's a JSFiddle with two buttons, the first demonstrates your original approach with "date: 'MM/dd/yy hh:mm a'", and the second demonstrates applied approach that I outline above http://jsfiddle.net/4whemakt/

You can apply and return the filtered value conditionally in your dynamicFilter. Something like this
function dynamicFilter($filter) {
return function (value, filter) {
if (filter.indexOf('date:') !== -1) {
//Note: I am using moment js to format the date
return moment(value).format(filter.match(/'([^']+)'/)[1]);
}
else {
return $filter(filter)(value)
}
}
}
moment.js reference http://momentjs.com/

Related

Using Filter property of PrimeReact DataTable

One of the columns of the DataTable implemented is somewhat like this
{ field: 'FieldValuesAsText#XYZ', header: 'XYZ', width: '150px', sort: true, filterElement: 'No' }
<Column key={col.field}
field={col.field}
header={col.header}
body={this.trimContent}
filter={true}
filterMatchMode="contains"
sortable={col.sort}/>
The FieldValuesAsText is a object with XYZ as one of it's attribute. The custom function used in the body property successfully retrieves the value but the problem is when I try to do the filter operation. Since the filter defaults to field which in this case is FieldValuesAsText#XYZ, so it is obviously going to return undefined. How will I be able to make my filter properly work?
You need to implement a custom filter function.
Here is a custom function that I have used to filter a similar column in my Datatable.
filterMatchMode="custom" filterFunction={customFunction}
export const customFunction = (value, filter) => {
return value.toUpperCase().indexOf(filter.toUpperCase()) >= 0
}

Filter react-admin query by dates

I am using react-admin's useGet... query to gather data from my rails backend. The main problem here is the filter property (the last pair of curly braces in the useGetList operation). How can i filter the data by Dates (like get only transactions of the last month etc.)
This is the current (working) approach:
const { data, loading, error } = useGetList(
'transactions',
{ page: 1, perPage: 10000 },
{ field: 'id', order: 'ASC' },
{},
)
if (loading) return <p>Loading</p>
if (error) return <p>Error</p>
if (!data) return null
The entries in the database all have a createdAt and updatedAt property.
My approach would be to create a filter like this:
// constraints could be dates that I can easily set beforehand
{
{'createdAt', desiredLowerTimeConstraint, operation: '<='},
{'createdAt', desiredUpperTimeConstraint, operation: '<='}
}
The react-admin documentation is quite sparce with the filter property, I couldn't find good examples for how these objects are supposed to look like.
It all depends on how your API expects filters to look like.
For instance, in REST APIs served by JSONServer, a _lte suffix on a query string parameter name indicates that you want results "Less Than or Equal to" the value:
GET /transactions?createdAt_lte=2019-12-05
Provided you use the ra-data-simple-rest, you can craft this request by passing the parameter in the filter:
const { data, loading, error } = useGetList(
'transactions',
{ page: 1, perPage: 10000 },
{ field: 'id', order: 'ASC' },
{ createdAt_lte: '2019-12-05' },
)
If your API behaves differently, then you may use the same syntax for useGetList, and transform the parameter in your dataProvider before it's sent to the API.

Angular datatables sorting issue

I am using this example https://l-lin.github.io/angular-datatables/archives/#!/bootstrapIntegration to configure my data tables. The problem is it won't sort the date and double price.
So far I try to sort the date but failed. I did find a lot of answers but no one is working.
My javascript
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withPaginationType('full_numbers')
.withOption('order', [0, 'desc']);
$scope.dtColumnDefs = [
{ targets: 0, type: 'date' }
];
My html
<table datatable="" dt-options="dtOptions" dt-column-defs="dtColumnDefs" class="row-border hover"></table
I also tried something like
$scope.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0).withOption('type', 'date'),
];
And I did tried change the date to dd/MM/yy but not working. My date in column is showed as 23/03/19
DataTables' date sorting is based on Date.parse() so any not-parseable date (or timestamp) will break the sorting.
A date in north european notation ala 23/03/19 parses to NaN, and there you have your problem. You can parse the date in a render() callback :
DTColumnDefBuilder.newColumnDef(0).renderWidth(function(data) {
data = data.split('/')
return Date.parse(data[1]+'-'+data[0]+'-'+data[2]).valueOf()
})
or you can use a custom sorting plugin like date-eu -> https://datatables.net/plug-ins/sorting/date-eu

Parsing from /Date(1487185200000)/ to date format

I want to convert this type of object to date format as (Sat 10/4/2016 5:03 PM)
how can I do that of input type /Date(1487185200000)/ using angularJs
May json is something like this
[{
"Post_Id": 1,
"Posts_Date":/Date(1487185200000)/,
"Post_Description": "Test",
},
{
"Post_Id": 2,
"Posts_Date": /Date(1487358000000)/,
"Post_Description": "Test",
}
]
This is my script in my controller
$http.post("/Home/GetPostData").then(function (d) {
$scope.Posts = d.data;
});
And this is my View
<div class="post_content" ng-repeat="p in Posts">
<h3> {{p.Post_Id}}</h3>
{{p.Post_Description}}
{{p.Posts_Date}}
</div>
And the output is somthing like this
1
Test
/Date(1487185200000)/
2
Test
/Date(1487358000000)/
want to convert my date as Standard format like (Sat 10/2/2016 4:50 PM) etc
If you are also interested in getting a Javascript Date (not just displaying), you can convert the JSON formmatted date/time information like this:
function parseJsonDate(jsonDateString){
return new Date(parseInt(jsonDateString.replace('/Date(', '')));
}
Credit
You need to visit this Angular Date filter
html
{{p.Posts_Date|removeBaces| date: 'medium'}}
js
myApp.filter('removeBaces', function() {
return function(input) {
return input.replace('/Date(','').replace(')/','');
}
});

How to filter data in UIGRID if data is mapped using celltemplate

we are using UI GRID to display data and we are using celltemplate in one column to filter data from ID to employee and we have enabled filters for every column.
sampledata:{ID:1 ,salary:3000,Gender:male}
$scope.gridOptions = {
enableFiltering: true,
data:sampledata,
columnDefs: [{Name:Employeetype, Field:ID,
cellTemplate: '<div class="ngCellText"> {{row.entity.ID | ID2EMp}}</div>'}
{Name: salary, field:salary}
{Name:Gender field:Gender}]
}
my filter is something like below:
app.filter('ID2EMp', function() {
return function(text) {
if (text=='1') {
return 'Employee';
}
if (text=='2')
return 'Contractor';
}
});
so now if try to filter grid using UI GRID text filter it wont work if i Type'Employee'/'Contractor' but it will work if i type '1'/'2'..Can anyone please advise how can i make filter work in this situation where i should be able to filter using EMployee keyword.
Also, is there any other way i can manipulate the data to display cell as Employee if ID=1 using filter but not using celltemplate.i have tried with cellfilter but it doesn't seem to work
You can do that in two way. Both with cellTemplate. First use filter like always, {{field | filter }} or use right condition in ng-if statement.
Edit:
First cellTemplate: '<div>{{row.entity.field | filter }} </div>'
where field is field from variable which you pass to ui-grid as data and filter is just filter.
Second: cellTemplate: '<div ng-if="some_condition">{{row.entity.filed}}</div> where field like in first. And some_condition is a condition statement which rows show.

Resources