Underscore js easy javascript object hierarchical filtering
Hi,
Just want to share something that in my opinion is really a useful helper library, and that is underscore.js
When combined with knockout, you can achieve easy filtering through its helper functions.
Let's say we have an object structure like this:
Company A
- Boss A
- Supervisor A
- Employee A
- Employee B
- Employee C
- Supervisor B
- Employee C
- Employee D
- Boss B
- Supervisor C
- Employee A
- Employee C
Company B
etc..
and after you are getting the all records, you want to provide some filtering based on the Boss, Supervisor or Employee. (to make it simple I just use dropdowns)
Using underscore, I can grab the list of unique values of Boss, Supervisor and Employee like this:
After that, if you are using knockout then you can bind the list to a dropdown, and using the selected value of the observable you can then create filter functions your original data:
Then you will just need to have a computed observable to return your filtered data:
Hope this helps,
Andreas
Just want to share something that in my opinion is really a useful helper library, and that is underscore.js
When combined with knockout, you can achieve easy filtering through its helper functions.
Let's say we have an object structure like this:
Company A
- Boss A
- Supervisor A
- Employee A
- Employee B
- Employee C
- Supervisor B
- Employee C
- Employee D
- Boss B
- Supervisor C
- Employee A
- Employee C
Company B
etc..
and after you are getting the all records, you want to provide some filtering based on the Boss, Supervisor or Employee. (to make it simple I just use dropdowns)
Using underscore, I can grab the list of unique values of Boss, Supervisor and Employee like this:
1 2 3 | BossList= _(data).chain().pluck( 'Boss' ).flatten().unique( 'name' ).sortBy( 'name' ).value(); SupervisorList= _(BossList).chain().pluck( 'Supervisor' ).flatten().unique( 'name' ).sortBy( 'name' ).value(); EmployeeList= _(SupervisorList).chain().pluck( 'Employee' ).flatten().unique( 'name' ).sortBy( 'name' ).value(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | function FilterBoss(data, bossId) { return _.filter(data, function (c) { c.Boss= _.filter(c.Boss, function (b) { return b.id == bossId; }); return c.Boss.length > 0; }); } function FilterSupervisor(data, supervisorId) { return _.filter(data, function (c) { c.Boss = _.filter(c.Boss, function (b) { b.Supervisor = _.filter(b.Supervisor, function (s) { return s.id == supervisorId; }); return b.Supervisor.length > 0; }); return c.Boss.length > 0; }); } function FilterEmployee(data, employeeId) { return _.filter(data, function (c) { c.Boss = _.filter(c.Boss, function (b) { b.Supervisor = _.filter(b.Supervisor, function (s) { s.Employee = _.filter(s.Employee, function (e) { return e.id == employeeId; }); return s.Employee.length > 0; }); return b.Supervisor.length > 0; }); return c.Boss.length > 0; }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | viewModel.FilteredData = ko.computed( function () { var selectedBoss = this .SelectedBoss(); var selectedSupervisor = this .SelectedSupervisor(); var selectedEmployee = this .SelectedEmployee(); if (selectedBoss) { var origData = JSON.parse(JSON.stringify(data)); //Clone to leave original data alone var filterObj = FilterBoss(origData, selectedBoss.id); if (selectedSupervisor) { filterObj = FilterSupervisor(filterObj, selectedSupervisor.id); if (selectedEmployee) { filterObj = FilterEmployee(filterObj, selectedEmployee.id); } } if (selectedEmployee) { filterObj = FilterEmployee(filterObj, selectedEmployee.id); } return ko.mapping.fromJS(filterObj)(); } else if (selectedSupervisor) { var origData = JSON.parse(JSON.stringify(data)); var filterObj = FilterSupervisor(origData, selectedSupervisor.id); if (selectedEmployee) { filterObj = FilterEmployee(filterObj, selectedEmployee.id); } return ko.mapping.fromJS(filterObj)(); } else if (selectedEmployee) { var origData = JSON.parse(JSON.stringify(data)); var filterObj = FilterEmployee(origData, selectedEmployee.id); return ko.mapping.fromJS(filterObj)(); } else { return this .Data(); } }, viewModel); |
Hope this helps,
Andreas
Comments
Post a Comment