Filtering doesn't work when fields are object properties #531

Closed
esheffield-ivantage opened this Issue Jul 2, 2013 · 25 comments

Comments

Projects
None yet

Filtering doesn't seem to work when the data in the grid consists of nested objects. For example, suppose you have data that looks like this:

$scope.myData = [{fields: {name: "Moroni", age: 50}},
                 {fields: {name: "Tiancum", age: 43}},
                 ...];

You can configure the column definitions so that the data displays properly in the grid:

columnDefs:[
  {
    field: "fields['name']",
    displayName: "Name"
  },
  ...
]

... but any attempts at filtering with the search box will result in no items showing in the grid. Presumably this is because ng-grid filters strings, not objects. Is there a way to get filtering to work in such a case? Here's a Plunker demonstrating this example: http://plnkr.co/edit/l2J1S9

@jonricaurte jonricaurte added a commit that referenced this issue Jul 6, 2013

@jonricaurte jonricaurte Fix for #531 and #533 8017eee
Member

jonricaurte commented Jul 6, 2013

This is fixed in latest 2.0.7.

jonricaurte closed this Jul 6, 2013

Member

jonricaurte commented Jul 6, 2013

What you want to do is instead of using fields['name'] you want to use fields.name like so:

http://plnkr.co/edit/SFz7jf?p=preview

@jonricaurte Thanks for the quick fix! Unfortunately, this still doesn't work in my case since my attribute names haves dots in them and therefore require square bracket notation to access. Apologies, I should have reflected this in my original plunker. Here's an updated one: http://plnkr.co/edit/wClSI4

Member

jonricaurte commented Jul 9, 2013

I'll look into it.

jonricaurte reopened this Jul 9, 2013

zstlaw commented Jul 16, 2013

If you have MULTIPLE nested objects displayed in the grid then filtering ignores all of them and only applies to non-nested columns. http://plnkr.co/edit/o6odBn?p=preview Note: link shows it is broken in 2.0.7. Removing either nested reference makes the other work.

Additionally when you format data for display (converting date formats for example) then filtering appears to be broken for that column. See http://plnkr.co/edit/MCtPEk?p=preview This is a problem since we need to localize date formatting. So the value on the wire is different from the value in the grid.

Contributor

sonicparke commented Sep 13, 2013

Just wondering if there's been any progress on this one? I've got pretty much the same problem.

The filtering does work for "fields.name" but not if capitalised "Item.name" like my data is being returned:

http://plnkr.co/edit/j18SQC?p=preview

Contributor

sonicparke commented Oct 30, 2013

@scottmcdonnell You've given me hope but I changed my structure to all lowercase and it's still not working. Can you see what I'm doing wrong?
http://plnkr.co/edit/AANkzL?p=preview

The square brackets don't seem to work. Funnily enough the array can be accessed using dots.
Instead of:

field: 'level2array[0].value'

try:

field: 'level2array.0.value'

http://plnkr.co/edit/r6Ezse?p=preview

filtering is now working for just the first column 'level2array.0' - hmmn not much better.
I think you will need to change your json structure to really make this work...

Contributor

sonicparke commented Oct 30, 2013

Thanks for the .0. thought. But yeah, I wonder why it only picks up the first column and not the rest of the items in that 2nd array.

Any progress on this issue?

Filter doesn't work for nested objects; when i make as single object it works.
Is there any way to make it work with nested objects.

pamcdm commented Mar 12, 2014

Still can't filter using filter options of ng-grid when using nested objects

acostaf commented Mar 24, 2014

Not much luck with this any update ?

@christopherhill christopherhill pushed a commit to christopherhill/ng-grid that referenced this issue Apr 19, 2014

@jonricaurte jonricaurte + Christopher Hill Fix for #531 and #533
Conflicts:
	src/classes/searchProvider.js
8af0574

roblarsen closed this Apr 24, 2014

This still doesn't seem to work in 2.0.11.

any update on this issue? Using custom cell templates also break search feature.
see the plunkr
http://plnkr.co/edit/QA690p?p=preview

Member

c0bra commented May 9, 2014

No updates. Anyone is free to take initiative and submit a PR though.

@mizanRahman - The search works by only searching for columnDef.field so keep that the same and refer to your link by accessing the row. See this plunkr - http://plnkr.co/edit/gOpMM8esXvyAkN2MvKXp?p=preview.

Nested search seems to be working fine for me now. Anyone have any current version plunkr test case of a search not working?

I tried the 2.0.11 version and filtering with complex field names(item.name) is still not working for me.

I've created a plunkr to demonstrate the issue. The filtering does work when searchEntireRow() is used (as demonstrated by the plunkr created by scottmcdonnell), but it doesn't work when searchColumn() is used: http://plnkr.co/edit/QjdHIjrUQiFyBrT9NfYb?p=preview
(It only works when the displayName is used in the search conditions)

The problem is that searchColumn searches the column like this:


var col = self.fieldMap[condition.columnDisplay];

"condition.columnDisplay" contains the fieldname of the column in lowercase (in my case: "user.name"), but this key is not present in "self.fieldMap"!
"self.fieldMap" contains an object with key "user" (this object does provide the name as a nested property), and it also contains the key "profile", which is the displayName in lowercase and without spaces. but the key "user.name" (with the dot) is not present in "self.fieldMap", which is the reason why "col" is undefined and no search results are returned.

The function buildSearchConditions() provides condition.columnDisplay, but it uses the columnName instead of the displayName (not sure if this is meant this way):


searchConditions.push({
    column: columnName,
    columnDisplay: columnName.replace(/\s+/g, '').toLowerCase(),
    regex: getRegExp(columnValue, 'i')
});

If I change r2753 (where "fieldMap" is constructed) in ng-grid.debug.js from:


if (col.displayName) {
    self.fieldMap[col.displayName.toLowerCase().replace(/\s+/g, '')] = col;
}

to:


if (col.displayName) {
    self.fieldMap[col.displayName.toLowerCase().replace(/\s+/g, '')] = col;
    self.fieldMap[col.field.toLowerCase().replace(/\s+/g, '')] = col;
}

Then the column filtering does work for nested properties (without having to use the displayName).

Please reopen this issue and fix this problem. I'm sorry I didn't create a PR but I don't have much experience with GIT, so I'd rather explain the problem here.

I looked at what @scottmcdonnell presented in his plunkr and it actually works, but only because he has used lowercase identifiers. I've create an example at http://plnkr.co/edit/UwwCDlnyuydNQbNpoYZv?p=preview There are two grids, one bound to lowercase identifers, and second to uppercase. The filter is shared.

If you enter "mor" you will see that only the first grid reacts properly. The second one will flush all items out.

However, if you enter "Profile:mor" both grids will behave correctly.

So, I've remapped all my involved entites to use lowercase identifiers, and magically it started working. However, this can be quite problematic in other scenarios. The full expression "Profile:xxx" works, so it's only about the quick-full-row-search.

Unfortunatelly, I've been not able to test @stephanie-dm's patch, nor fully understand it as I don't know internals of ng-grid well enough. However, it seems to the similar problems and I'm pretty sure that describes the same problem in more in-depth words.

wienand commented Jul 28, 2014

I had to change the following line in searchEntireRow due get the filtering to work with nested objects:

            var c = fieldMap[prop.toLowerCase()];

to

            var c = fieldMap[prop] || fieldMap[prop.toLowerCase()];

Also note that in case the underlying data contains a field with the same name as the label of another field (e.g. AssignedBy = index of user, assignedBy = user object and column in grid with label "Assigned By" and field "assignedBy.Name") the search for a specific column will pick up the index column and not the assignedBy.Name for filtering.

swlasse commented Nov 18, 2014

@wienand I have just tried your patch and it solves the problem of having to use lowercase field names. Thanks. I know it is not pretty to apply changes in my local ng-grid source, but until this get fixed in the ng-grid project, your solution is definitely usable.

shanimal commented Mar 6, 2015

fwiw, I got around this issue by adding the nested field values onto the object root instead of using dot syntax for field. something like this...

$scope.invoices = _(data.content.orderList).map(function(v){
    v.adTitle = v.oDetails.adTitle;
    return v;
})
....
// set the field
field: 'adTitle',

vs.

$scope.invoices = data.content.orderList
....
// set the field
field: 'oDetails.adTitle',

agriboss commented Feb 7, 2016

I have not tried what the others above have suggested as I do not want to modify the source. Here is a workaround that gets around it...

I believe the problem occurs here (nested data causes dot notation to be returned in "field"):


          if ( row.entity[field].match(matcher) ){
                 match = true;
          }

You can do something like this in your search function:

                var j = field.split(".");
                //j is now array of prop names to drill into data
                var rowEntity = row.entity;

                //descend into object using array of prop names
                angular.forEach(j, function(prop){
                    rowEntity = rowEntity[prop];
                }); `

                if ( rowEntity.match(matcher) ){
                     match = true;
                }

shon-otmazgin referenced this issue in talgarusi/Itorerut-Project Apr 12, 2016

Closed

numOfTasks filter fail #16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment