From 93ca7e7620c750066b8b4c2440824607acce3925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Muszy=C5=84ski?= Date: Tue, 13 Jan 2015 17:47:55 +0100 Subject: [PATCH] expand on topic search --- .../public/js/angular-ui-tree-filter.min.js | 149 +++++++++++++----- .../Resources/public/js/tree.js | 56 ++++--- .../Resources/views/Topics/index.html.twig | 2 +- 3 files changed, 152 insertions(+), 55 deletions(-) diff --git a/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/angular-ui-tree-filter.min.js b/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/angular-ui-tree-filter.min.js index b20a1c9e92..789d77f878 100644 --- a/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/angular-ui-tree-filter.min.js +++ b/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/angular-ui-tree-filter.min.js @@ -1,37 +1,114 @@ -/*! angular-ui-tree-filter 0.1.0, 06-06-2014 */ ! function(a) { - "use strict"; - a.module("ui.tree-filter", []).provider("uiTreeFilterSettings", function() { - var a = this; - this.addresses = ["title"], this.regexFlags = "gi", this.descendantCollection = "items", this.$get = function() { - return { - addresses: a.addresses, - regexFlags: a.regexFlags, - descendantCollection: a.descendantCollection +(function (angular) { + 'use strict'; + + angular.module('ui.tree-filter', []) + /** + * @ngdoc object + * @name ui.tree-filter.provider:uiTreeFilterSettings + */ + .provider('uiTreeFilterSettings', function () { + + var uiTreeFilterSettings = this; + + this.addresses = ['title']; + this.regexFlags = 'gi'; + this.descendantCollection = 'items'; + + this.$get = function () { + return { + addresses: uiTreeFilterSettings.addresses, + regexFlags: uiTreeFilterSettings.regexFlags, + descendantCollection: uiTreeFilterSettings.descendantCollection, + }; + }; + }) + /** + * @ngdoc function + * @name project.factory:projectWbsFilter + */ + .filter('uiTreeFilter', ["uiTreeFilterSettings", function (uiTreeFilterSettings) { + /** + * Iterates through given collection if flag is not true and sets a flag to true on first match. + * + * @param {Array} collection + * @param {string} pattern + * @param {string} address + * + * @returns {boolean} + */ + function visit(collection, pattern, address, scope) { + collection = collection || []; + var foundSoFar = false; + + collection.forEach(function (collectionItem) { + foundSoFar = foundSoFar || testForField(collectionItem, pattern, address, scope); + if (foundSoFar) { + scope.expanded = true; + } else { + scope.expanded = false; + } + }); + + return foundSoFar; + } + + /** + * Resolves object value from dot-delimited address. + * + * @param object + * @param path + * @returns {*} + */ + function resolveAddress(object, path) { + var parts = path.split('.'); + return parts.length < 2 ? object[parts[0]] : resolveAddress(object[parts[0]], parts.slice(1).join('.')); + } + + /** + * Checks if object or its children matches a pattern on a given field + * + * First it resolves the property address and gets the value. + * If the value is a string it matches it against provided pattern. + * If item matches because its property matches it's children are not checked. + * Otherwise all item descendants are checked as well + * + * @param {Object} item + * @param {string} pattern + * @param {string} address property name or dot-delimited path to property. + * + * @returns {boolean} + */ + function testForField(item, pattern, address, scope) { + var value = resolveAddress(item, address); + var found = typeof value === 'string' ? + !!value.match(new RegExp(pattern, uiTreeFilterSettings.regexFlags)) : + false; + return found || visit(item[uiTreeFilterSettings.descendantCollection], pattern, address, scope); } - } - }).filter("uiTreeFilter", ["uiTreeFilterSettings", function(a) { - function b(a, b, c) { - a = a || []; - var e = !1; - return a.forEach(function(a) { - e = e || d(a, b, c) - }), e - } - - function c(a, b) { - var d = b.split("."); - return d.length < 2 ? a[d[0]] : c(a[d[0]], d.slice(1).join(".")) - } - - function d(d, e, f) { - var g = c(d, f), - h = "string" == typeof g ? !!g.match(new RegExp(e, a.regexFlags)) : !1; - return h || b(d[a.descendantCollection], e, f) - } - return function(b, c, e) { - return e = e || a.addresses, void 0 === c || e.reduce(function(a, e) { - return a || d(b, c, e) - }, !1) - } - }]) -}(angular); \ No newline at end of file + + /** + * Checks if pattern matches any of addresses + * + * @param {object} item + * @param {string} pattern + * + * @returns {boolean} + */ + return function (item, pattern, addresses, scope) { + addresses = addresses || uiTreeFilterSettings.addresses; + if (pattern !== undefined && pattern.length <= 3) { + scope.expanded = false; + + return true; + } + + return pattern === undefined || addresses.reduce(function (foundSoFar, fieldName) { + if (!foundSoFar || !testForField(item, pattern, fieldName, scope)) { + scope.expanded = false; + } + + return foundSoFar || testForField(item, pattern, fieldName, scope); + }, false); + }; + }]); +})(angular); \ No newline at end of file diff --git a/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/tree.js b/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/tree.js index d6e3bafa5c..bb8afb4e61 100644 --- a/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/tree.js +++ b/newscoop/src/Newscoop/NewscoopBundle/Resources/public/js/tree.js @@ -419,6 +419,14 @@ app.controller('treeCtrl', function($scope, TopicsFactory, $filter) { } } + if (scope.expanded) { + scope.$nodeScope.collapsed = true; + scope.$nodeScope.expanded = false; + } else { + scope.$nodeScope.collapsed = false; + scope.$nodeScope.expanded = true; + } + scope.toggle(); }; @@ -438,12 +446,10 @@ app.controller('treeCtrl', function($scope, TopicsFactory, $filter) { */ $scope.expandCollapseAll = function(s) { var scope = getRootNodesScope(); - if (s.collapsedTree) { - scope.expandAll(); - s.collapsedTree = false; + if (!scope.expanded) { + scope.expanded = true; } else { - scope.collapseAll(); - s.collapsedTree = true; + scope.expanded = false; } }; @@ -673,18 +679,39 @@ app.controller('treeCtrl', function($scope, TopicsFactory, $filter) { // if set to true, set fallback to false // else to true var setfallback = true; + var i; angular.forEach(node.translations, function(value, key) { if (value.activeLabel) { setfallback = false; } }); - angular.forEach(node.translations, function(value, key) { - if (value.activeLabel == undefined && setfallback) { - value.fallback = true; + for (i = 0; i < node.translations.length; i++) { + if (node.translations[i].activeLabel == undefined && setfallback) { + node.translations[i].fallback = true; + } + } + + // if languageCode not in array + // choose first locale and set fallback + var inArray = false; + for (i = 0; i < node.translations.length; i++) { + if (angular.equals(node.translations[i].locale, languageCode)) { + inArray = true; + } + } + + if (!inArray) { + // restore fallback fields + // first translation is always default, so we unset fallback + // for all translations diffrent than default + for (i = 0; i < node.translations.length; i++) { + if (!angular.equals(node.translations[i].locale, languageCode) && i !== 0) { + node.translations[i].fallback = false; } - }); - } + } + } + }; }) /** * Ad-hoc $sce trusting to be used with ng-bind-html @@ -693,12 +720,5 @@ app.controller('treeCtrl', function($scope, TopicsFactory, $filter) { return function (val) { return $sce.trustAsHtml(val); }; - }) - .filter('startFrom', function() { - return function(input, start) { - if(!input) return input; - start = +start; - return input.slice(start); - }; - }); + }); })(); diff --git a/newscoop/src/Newscoop/NewscoopBundle/Resources/views/Topics/index.html.twig b/newscoop/src/Newscoop/NewscoopBundle/Resources/views/Topics/index.html.twig index f51e6a85e3..8f3e10bb18 100644 --- a/newscoop/src/Newscoop/NewscoopBundle/Resources/views/Topics/index.html.twig +++ b/newscoop/src/Newscoop/NewscoopBundle/Resources/views/Topics/index.html.twig @@ -164,7 +164,7 @@ -
    +