diff --git a/test/spec/filtersSpec.js b/test/spec/filtersSpec.js index b6d426ccc1..7bf37ca77f 100644 --- a/test/spec/filtersSpec.js +++ b/test/spec/filtersSpec.js @@ -27,4 +27,28 @@ describe('Custom Filters', function() { }); }); }); + + describe('filterByTextAndNotes', function () { + it('returns undefined when no input given', function () { + expect(filter('filterByTextAndNotes')()).to.eql(undefined); + }); + + it('returns input if term is not a string', function () { + var input = [1, 2, 3]; + expect(filter('filterByTextAndNotes')(input, '')).to.eql(input); + expect(filter('filterByTextAndNotes')(input, undefined)).to.eql(input); + expect(filter('filterByTextAndNotes')(input, [])).to.eql(input); + expect(filter('filterByTextAndNotes')(input, new Date())).to.eql(input); + }); + + it('filters items by notes and text', function () { + var tasks = [ + { text: 'foo' }, + { text: 'foo', notes: 'bar' } + ]; + + expect(filter('filterByTextAndNotes')(tasks, 'bar')).to.eql([tasks[1]]); + expect(filter('filterByTextAndNotes')(tasks, 'foo')).to.eql([tasks[0], tasks[1]]); + }); + }); }); diff --git a/website/public/js/filters/filters.js b/website/public/js/filters/filters.js index 4578c1a5db..cb59c76042 100644 --- a/website/public/js/filters/filters.js +++ b/website/public/js/filters/filters.js @@ -28,4 +28,25 @@ angular.module('habitrpg') } return array; }; + }]) + .filter('filterByTextAndNotes', ['$filter', function($filter) { + return function (input, term) { + if (!input) return; + + if (!angular.isString(term) || term.legth === 0) { + return input; + } + + term = new RegExp(term, 'i'); + + var result = [], i; + + for (i = 0; i < input.length; i++) { + if (term.test(input[i].text) || term.test(input[i].notes)) { + result.push(input[i]); + } + } + + return result; + }; }]); diff --git a/website/views/shared/tasks/task.jade b/website/views/shared/tasks/task.jade index 3a18c99168..80f2769df3 100644 --- a/website/views/shared/tasks/task.jade +++ b/website/views/shared/tasks/task.jade @@ -1,4 +1,4 @@ -li(bindonce='list', id='task-{{::task.id}}', ng-repeat='task in obj[list.type+"s"] | filter:{text: obj.filterQuery} | conditionalOrderBy: list.view=="dated":"date"', class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && (list.type != "reward") && castEnd(task, "task", $event)', ng-class='{"cast-target":spell && (list.type != "reward"), "locked-task":obj._locked === true}', popover-trigger='mouseenter', data-popover-html="{{task.popoverOpen ? '' : task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}', ng-show='shouldShow(task, list, user.preferences)') +li(bindonce='list', id='task-{{::task.id}}', ng-repeat='task in obj[list.type+"s"] | filterByTextAndNotes: obj.filterQuery | conditionalOrderBy: list.view=="dated":"date"', class='task {{Shared.taskClasses(task, user.filters, user.preferences.dayStart, user.lastCron, list.showCompleted, main)}}', ng-click='spell && (list.type != "reward") && castEnd(task, "task", $event)', ng-class='{"cast-target":spell && (list.type != "reward"), "locked-task":obj._locked === true}', popover-trigger='mouseenter', data-popover-html="{{task.popoverOpen ? '' : task.notes | markdown}}", popover-placement="top", popover-append-to-body='{{::modal ? "false":"true"}}', ng-show='shouldShow(task, list, user.preferences)') // right-hand side control buttons .task-meta-controls