diff --git a/src/components/selectors.js b/src/components/selectors.js index 0608461..7824f22 100644 --- a/src/components/selectors.js +++ b/src/components/selectors.js @@ -3,10 +3,10 @@ $.extend(edges, { // Selector implementations - newRefiningANDTermSelector : function(params) { + newRefiningANDTermSelector: function (params) { return edges.instantiate(edges.RefiningANDTermSelector, params, edges.newSelector); }, - RefiningANDTermSelector : function(params) { + RefiningANDTermSelector: function (params) { //////////////////////////////////////////// // configurations to be passed in @@ -31,6 +31,15 @@ $.extend(edges, { this.valueMap = params.valueMap || false; this.valueFunction = params.valueFunction || false; + // function to parse the value selected (which will be a string) into whatever + // datatype the filter requires + this.parseSelectedValueString = edges.getParam(params.parseSelectedValueString, false); + + // function to convert the filter value to the same type as the aggregation value, if they + // differ (e.g. if the filter is `true` but the agg value is `1` this function can convert + // between them. + this.filterToAggValue = edges.getParam(params.filterToAggValue, false); + // due to a limitation in elasticsearch's clustered node facet counts, we need to inflate // the number of facet results we need to ensure that the results we actually want are // accurate. This option tells us by how much. @@ -60,7 +69,7 @@ $.extend(edges, { ////////////////////////////////////////// // overrides on the parent object's standard functions - this.init = function(edge) { + this.init = function (edge) { // first kick the request up to the superclass edges.up(this, "init", [edge]); @@ -69,7 +78,7 @@ $.extend(edges, { } }; - this.contrib = function(query) { + this.contrib = function (query) { var params = { name: this.id, field: this.field, @@ -84,7 +93,7 @@ $.extend(edges, { ); }; - this.synchronise = function() { + this.synchronise = function () { // reset the state of the internal variables if (this.lifecycle === "update") { // if we are in the "update" lifecycle, then reset and read all the values @@ -99,12 +108,16 @@ $.extend(edges, { var filters = this.edge.currentQuery.listMust(es.newTermFilter({field: this.field})); for (var i = 0; i < filters.length; i++) { var val = filters[i].value; + if (this.filterToAggValue) { + val = this.filterToAggValue(val); + } + let term = val; val = this._translate(val); - this.filters.push({display: val, term: filters[i].value}); + this.filters.push({display: val, term: term}); } }; - this._readValues = function(params) { + this._readValues = function (params) { var result = params.result; // assign the terms and counts from the aggregation @@ -138,7 +151,11 @@ $.extend(edges, { var exclude = false; for (var j = 0; j < predefined.length; j++) { var f = predefined[j]; - if (bucket.key === f.value) { + let filterValue = f.value; + if (this.filterToAggValue) { + filterValue = this.filterToAggValue(f.value) + } + if (bucket.key === filterValue) { exclude = true; break; } @@ -170,7 +187,7 @@ $.extend(edges, { ///////////////////////////////////////////////// // query handlers for getting the full list of terms to display - this.listAll = function() { + this.listAll = function () { // to list all possible terms, build off the base query var bq = this.edge.cloneBaseQuery(); bq.clearAggregations(); @@ -197,7 +214,7 @@ $.extend(edges, { }); }; - this.listAllQuerySuccess = function(params) { + this.listAllQuerySuccess = function (params) { var result = params.result; // set the values according to what comes back @@ -208,7 +225,7 @@ $.extend(edges, { this.draw(); }; - this.listAllQueryFail = function() { + this.listAllQueryFail = function () { this.values = []; console.log("RefiningANDTermSelector asynchronous query failed"); }; @@ -216,7 +233,11 @@ $.extend(edges, { ////////////////////////////////////////// // functions that can be called on this component to change its state - this.selectTerm = function(term) { + this.selectTerm = function (term) { + if (this.parseSelectedValueString) { + term = this.parseSelectedValueString(term); + } + var nq = this.edge.cloneQuery(); // first make sure we're not double-selecting a term @@ -245,7 +266,11 @@ $.extend(edges, { return true; }; - this.removeFilter = function(term) { + this.removeFilter = function (term) { + if (this.parseSelectedValueString) { + term = this.parseSelectedValueString(term); + } + var nq = this.edge.cloneQuery(); nq.removeMust(es.newTermFilter({ @@ -259,7 +284,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.clearFilters = function(params) { + this.clearFilters = function (params) { var triggerQuery = edges.getParam(params.triggerQuery, true); if (this.filters.length > 0) { @@ -278,7 +303,7 @@ $.extend(edges, { } }; - this.changeSize = function(newSize) { + this.changeSize = function (newSize) { this.size = newSize; var nq = this.edge.cloneQuery(); @@ -290,7 +315,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.changeSort = function(orderBy, orderDir) { + this.changeSort = function (orderBy, orderDir) { this.orderBy = orderBy; this.orderDir = orderDir; @@ -306,7 +331,7 @@ $.extend(edges, { ////////////////////////////////////////// // "private" functions for internal use - this._translate = function(term) { + this._translate = function (term) { if (this.valueMap) { if (term in this.valueMap) { return this.valueMap[term]; @@ -318,12 +343,14 @@ $.extend(edges, { }; }, - newORTermSelector : function(params) { - if (!params) { params = {} } + newORTermSelector: function (params) { + if (!params) { + params = {} + } edges.ORTermSelector.prototype = edges.newSelector(params); return new edges.ORTermSelector(params); }, - ORTermSelector : function(params) { + ORTermSelector: function (params) { // whether this component updates itself on every request, or whether it is static // throughout its lifecycle. One of "update" or "static" this.lifecycle = edges.getParam(params.lifecycle, "static"); @@ -373,7 +400,7 @@ $.extend(edges, { this.reQueryAfterListAll = false; - this.init = function(edge) { + this.init = function (edge) { // first kick the request up to the superclass edges.newSelector().init.call(this, edge); @@ -386,7 +413,7 @@ $.extend(edges, { } }; - this.synchronise = function() { + this.synchronise = function () { // reset the internal properties this.selected = []; @@ -406,7 +433,7 @@ $.extend(edges, { } }; - this._synchroniseTermsMergeInitial = function(params) { + this._synchroniseTermsMergeInitial = function (params) { var result = params.result; // mesh the terms in the aggregation with the terms in the terms list @@ -429,7 +456,7 @@ $.extend(edges, { } }; - this._synchroniseTerms = function(params) { + this._synchroniseTerms = function (params) { if (this.updateType === "mergeInitial") { this._synchroniseTermsMergeInitial(params); } else { @@ -437,7 +464,7 @@ $.extend(edges, { } }; - this._synchroniseTermsFresh = function(params) { + this._synchroniseTermsFresh = function (params) { var result = params.result; this.terms = []; @@ -451,7 +478,7 @@ $.extend(edges, { ///////////////////////////////////////////////// // query handlers for getting the full list of terms to display - this.listAll = function() { + this.listAll = function () { // to list all possible terms, build off the base query var bq = this.edge.cloneBaseQuery(); bq.clearAggregations(); @@ -478,7 +505,7 @@ $.extend(edges, { }); }; - this.listAllQuerySuccess = function(params) { + this.listAllQuerySuccess = function (params) { var result = params.result; // get the terms out of the aggregation @@ -503,11 +530,11 @@ $.extend(edges, { } }; - this.listAllQueryFail = function() { + this.listAllQueryFail = function () { this.terms = []; }; - this.setupEvent = function() { + this.setupEvent = function () { if (this.lifecycle === "update") { this.edge.context.on("edges:pre-query", edges.eventClosure(this, "doUpdate")); // we used to do this, but no need, as when the query cycles, the event handler set above will run it anyway @@ -515,7 +542,7 @@ $.extend(edges, { } }; - this.doUpdate = function() { + this.doUpdate = function () { // is an update already happening? if (this.updating) { return @@ -551,7 +578,7 @@ $.extend(edges, { }); }; - this.doUpdateQuerySuccess = function(params) { + this.doUpdateQuerySuccess = function (params) { var result = params.result; this._synchroniseTerms({result: result}); @@ -563,7 +590,7 @@ $.extend(edges, { this.draw(); }; - this.doUpdateQueryFail = function() { + this.doUpdateQueryFail = function () { // just do nothing, hopefully the next request will be successful this.updating = false; }; @@ -571,7 +598,7 @@ $.extend(edges, { /////////////////////////////////////////// // state change functions - this.selectTerms = function(params) { + this.selectTerms = function (params) { var terms = params.terms; var clearOthers = edges.getParam(params.clearOthers, false); @@ -619,11 +646,11 @@ $.extend(edges, { return true; }; - this.selectTerm = function(term) { - return this.selectTerms({terms : [term]}); + this.selectTerm = function (term) { + return this.selectTerms({terms: [term]}); }; - this.removeFilter = function(term) { + this.removeFilter = function (term) { var nq = this.edge.cloneQuery(); // first find out if there was a terms filter already in place @@ -645,7 +672,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.clearFilters = function(params) { + this.clearFilters = function (params) { var triggerQuery = edges.getParam(params.triggerQuery, true); if (this.selected.length > 0) { @@ -663,7 +690,7 @@ $.extend(edges, { ////////////////////////////////////////// // "private" functions for internal use - this._translate = function(term) { + this._translate = function (term) { if (this.valueMap) { if (term in this.valueMap) { return this.valueMap[term]; @@ -675,12 +702,14 @@ $.extend(edges, { }; }, - newBasicRangeSelector : function(params) { - if (!params) { params = {} } + newBasicRangeSelector: function (params) { + if (!params) { + params = {} + } edges.BasicRangeSelector.prototype = edges.newSelector(params); return new edges.BasicRangeSelector(params); }, - BasicRangeSelector : function(params) { + BasicRangeSelector: function (params) { ////////////////////////////////////////////// // values that can be passed in @@ -708,7 +737,7 @@ $.extend(edges, { // {display: , from: , to: } this.filters = []; - this.contrib = function(query) { + this.contrib = function (query) { var ranges = []; for (var i = 0; i < this.ranges.length; i++) { var r = this.ranges[i]; @@ -730,7 +759,7 @@ $.extend(edges, { ); }; - this.synchronise = function() { + this.synchronise = function () { // reset the state of the internal variables this.values = []; this.filters = []; @@ -766,7 +795,7 @@ $.extend(edges, { } }; - this.selectRange = function(from, to) { + this.selectRange = function (from, to) { var nq = this.edge.cloneQuery(); // just add a new range filter (the query builder will ensure there are no duplicates) @@ -785,7 +814,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.removeFilter = function(from, to) { + this.removeFilter = function (from, to) { var nq = this.edge.cloneQuery(); // just add a new range filter (the query builder will ensure there are no duplicates) @@ -804,7 +833,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this._getRangeDef = function(from, to) { + this._getRangeDef = function (from, to) { for (var i = 0; i < this.ranges.length; i++) { var r = this.ranges[i]; var frMatch = true; @@ -833,7 +862,7 @@ $.extend(edges, { return false; }; - this._getRangeBucket = function(buckets, from, to) { + this._getRangeBucket = function (buckets, from, to) { for (var i = 0; i < buckets.length; i++) { var r = buckets[i]; var frMatch = true; @@ -860,7 +889,7 @@ $.extend(edges, { return false; }; - this._formatUnknown = function(from, to) { + this._formatUnknown = function (from, to) { if (this.formatUnknown) { return this.formatUnknown(from, to) } else { @@ -888,12 +917,14 @@ $.extend(edges, { }; }, - newBasicGeoDistanceRangeSelector : function(params) { - if (!params) { params = {} } + newBasicGeoDistanceRangeSelector: function (params) { + if (!params) { + params = {} + } edges.BasicGeoDistanceRangeSelector.prototype = edges.newSelector(params); return new edges.BasicGeoDistanceRangeSelector(params); }, - BasicGeoDistanceRangeSelector : function(params) { + BasicGeoDistanceRangeSelector: function (params) { // list of distances (in order) which define the filters // {"from" : , "to" : , "display" : ""} this.distances = params.distances || []; @@ -913,18 +944,20 @@ $.extend(edges, { this.values = []; - this.synchronise = function() { + this.synchronise = function () { // reset the state of the internal variables this.values = []; }; }, - newDateHistogramSelector : function(params) { - if (!params) { params = {} } + newDateHistogramSelector: function (params) { + if (!params) { + params = {} + } edges.DateHistogramSelector.prototype = edges.newSelector(params); return new edges.DateHistogramSelector(params); }, - DateHistogramSelector : function(params) { + DateHistogramSelector: function (params) { // "year, quarter, month, week, day, hour, minute ,second" // period to use for date histogram this.interval = params.interval || "year"; @@ -941,7 +974,7 @@ $.extend(edges, { this.values = []; this.filters = []; - this.contrib = function(query) { + this.contrib = function (query) { query.addAggregation( es.newDateHistogramAggregation({ name: this.id, @@ -951,7 +984,7 @@ $.extend(edges, { ); }; - this.synchronise = function() { + this.synchronise = function () { // reset the state of the internal variables this.values = []; this.filters = []; @@ -964,9 +997,9 @@ $.extend(edges, { if (this.displayFormatter) { key = this.displayFormatter(key); } - var obj = {"display" : key, "gte": bucket.key, "count" : bucket.doc_count}; + var obj = {"display": key, "gte": bucket.key, "count": bucket.doc_count}; if (i < buckets.length - 1) { - obj["lt"] = buckets[i+1].key; + obj["lt"] = buckets[i + 1].key; } this.values.push(obj); } @@ -998,7 +1031,7 @@ $.extend(edges, { } }; - this.selectRange = function(params) { + this.selectRange = function (params) { var from = params.gte; var to = params.lt; @@ -1021,7 +1054,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.removeFilter = function(params) { + this.removeFilter = function (params) { var from = params.gte; var to = params.lt; @@ -1043,7 +1076,7 @@ $.extend(edges, { this.edge.doQuery(); }; - this.clearFilters = function(params) { + this.clearFilters = function (params) { var triggerQuery = edges.getParam(params.triggerQuery, true); var nq = this.edge.cloneQuery(); @@ -1057,19 +1090,21 @@ $.extend(edges, { }; }, - newAutocompleteTermSelector : function(params) { - if (!params) { params = {} } + newAutocompleteTermSelector: function (params) { + if (!params) { + params = {} + } edges.AutocompleteTermSelector.prototype = edges.newComponent(params); return new edges.AutocompleteTermSelector(params); }, - AutocompleteTermSelector : function(params) { + AutocompleteTermSelector: function (params) { this.defaultRenderer = params.defaultRenderer || "newAutocompleteTermSelectorRenderer"; }, - newNavigationTermList : function(params) { + newNavigationTermList: function (params) { return edges.instantiate(edges.NavigationTermList, params, edges.newComponent); }, - NavigationTermList : function(params) { + NavigationTermList: function (params) { this.urlTemplate = params.urlTemplate; this.placeholder = edges.getParam(params.placeholder, "{term}"); this.sourceResults = edges.getParam(params.sourceResults, false); @@ -1077,7 +1112,7 @@ $.extend(edges, { this.terms = []; - this.synchronise = function() { + this.synchronise = function () { this.terms = []; var results = this.edge.result; @@ -1092,53 +1127,106 @@ $.extend(edges, { } var agg = results.aggregation(this.sourceAggregation); - this.terms = agg.buckets.map(function(x) { return x.key}); + this.terms = agg.buckets.map(function (x) { + return x.key + }); }; - this.navigate = function(params) { + this.navigate = function (params) { var term = params.term; var url = this.urlTemplate.replace(this.placeholder, term); window.location.href = url; } }, - newTreeBrowser : function(params) { - return edges.instantiate(edges.TreeBrowser, params, edges.newComponent); + newTreeBrowserCore: function (params) { + return edges.instantiate(edges.TreeBrowserCore, params, edges.newComponent); }, - TreeBrowser : function(params) { - this.field = edges.getParam(params.field, false); - this.size = edges.getParam(params.size, 10); + newTreeBrowser: function (params) {`` + return edges.instantiate(edges.TreeBrowserSearch, params, edges.newTreeBrowserCore); + }, + TreeBrowserCore: function (params) { this.tree = edges.getParam(params.tree, {}); - this.nodeMatch = edges.getParam(params.nodeMatch, false); - this.filterMatch = edges.getParam(params.filterMatch, false); - this.nodeIndex = edges.getParam(params.nodeIndex, false); - this.pruneTree = edges.getParam(params.pruneTree, false); - this.syncTree = []; - this.parentIndex = {}; - - this.pruned = false; - this.nodeCount = 0; - this.init = function(edge) { - // first kick the request up to the superclass - edges.newSelector().init.call(this, edge); + this.init = function (edge) { + edges.newComponent().init.call(this, edge); + }; - // now trigger a request for the terms to present, if not explicitly provided + // Common recurse function + this.baseRecurse = function (tree, path, processNode) { + var anySelected = false; + var childCount = 0; + + for (var i = 0; i < tree.length; i++) { + var node = tree[i]; + this.nodeCount++; + + this.parentIndex[node.value] = $.extend(true, [], path); + + // Process the node and check if it was selected + var nodeSelected = processNode(node); + if (nodeSelected) { + anySelected = true; + } + + if (node.children) { + path.push(node.value); + var childReport = this.baseRecurse(node.children, path, processNode); + path.pop(); + if (childReport.anySelected) { + node.selected = true; + anySelected = true; + } + childCount += childReport.childCount; + node.childCount = childReport.childCount; + } else { + node.childCount = 0; + } + } + return {anySelected: anySelected, childCount: childCount}; + }; + + this.addFilter = function (params) { + console.log('addFilter method must be implemented.'); + // throw new edges.error.NotImplementedError('addFilter method must be implemented.'); + } + + this.removeFilter = function (params) { + console.log('removeFilter method must be implemented.'); + // throw new edges.error.NotImplementedError('removeFilter method must be implemented.'); + } + + this.synchronise = function (params) { + console.log('synchronise method must be implemented.');`` + // throw new edges.error.NotImplementedError('synchronise method must be implemented.'); + } + + }, + TreeBrowserSearch: function (params) { + + this.field = edges.getParam(params.field, false); + this.size = edges.getParam(params.size, 10); + this.pruneTree = edges.getParam(params.pruneTree, false); + this.pruned = false; + + this.init = function (edge) { + // first kick the request up to the core component + edges.newTreeBrowserCore().init.call(this, edge); if (this.pruneTree) { this._pruneTree(); } }; - this.contrib = function(query) { + this.contrib = function (query) { var params = { name: this.id, field: this.field @@ -1151,10 +1239,8 @@ $.extend(edges, { ); }; - this.synchronise = function() { - // synchronise if: - // * we are not pruning the tree - // * we are pruning the tree, and it has now been pruned + this.synchronise = function () { + this.nodeCount = 0; if (!(!this.pruneTree || (this.pruneTree && this.pruned))) { this.syncTree = []; @@ -1163,7 +1249,6 @@ $.extend(edges, { } this.syncTree = $.extend(true, [], this.tree); - var results = this.edge.result; if (!results) { return; @@ -1180,57 +1265,27 @@ $.extend(edges, { var buckets = $.extend(true, [], agg.buckets); var that = this; - function recurse(tree, path) { - var anySelected = false; - var childCount = 0; - - for (var i = 0; i < tree.length; i++) { - var node = tree[i]; - that.nodeCount++; - - that.parentIndex[node.value] = $.extend(true, [], path); - - var idx = that.nodeMatch(node, buckets); - if (idx === -1) { - node.count = 0; - } else { - node.count = buckets[idx].doc_count; - } - childCount += node.count; - - if (that.filterMatch(node, selected)) { - node.selected = true; - anySelected = true; - } - - if (that.nodeIndex) { - node.index = that.nodeIndex(node); - } else { - node.index = node.display; - } + var processNode = function (node) { + var idx = that.nodeMatch(node, buckets); + if (idx === -1) { + node.count = 0; + } else { + node.count = buckets[idx].doc_count; + } + node.index = that.nodeIndex ? that.nodeIndex(node) : node.display; + if (that.filterMatch(node, selected)) { + node.selected = true; + return true; // Node is selected + } + return false; // Node not selected + }; - if (node.children) { - path.push(node.value); - var childReport = recurse(node.children, path); - path.pop(); - if (childReport.anySelected) { - node.selected = true; - anySelected = true; - } - childCount += childReport.childCount; - node.childCount = childReport.childCount; - } else { - node.childCount = 0; - } - } - return {anySelected: anySelected, childCount: childCount} - } var path = []; - recurse(this.syncTree, path); + this.baseRecurse(this.syncTree, path, processNode); }; - this.addFilter = function(params) { + this.addFilter = function (params) { var value = params.value; var parents = this.parentIndex[value]; var terms = [params.value]; @@ -1238,21 +1293,17 @@ $.extend(edges, { var nq = this.edge.cloneQuery(); - // first find out if there was a terms filter already in place var filters = nq.listMust(es.newTermsFilter({field: this.field})); - // if there is, just add the term to it (removing and parent terms along the way) if (filters.length > 0) { var filter = filters[0]; var originalValues = $.extend(true, [], filter.values); originalValues.sort(); - // if this is an exclusive filter that clears all others, just do that if (clearOthers) { filter.clear_terms(); } - // next, if there are any terms left, remove all the parent terms for (var i = 0; i < parents.length; i++) { var parent = parents[i]; if (filter.has_term(parent)) { @@ -1260,7 +1311,6 @@ $.extend(edges, { } } - // now add all the provided terms var hadTermAlready = 0; for (var i = 0; i < terms.length; i++) { var term = terms[i]; @@ -1271,21 +1321,18 @@ $.extend(edges, { } } - // if, as a result of the all the operations, the values didn't change, then don't search if (originalValues === filter.values.sort()) { return false; } else if (!filter.has_terms()) { nq.removeMust(es.newTermsFilter({field: this.field})); } } else { - // otherwise, set the Terms Filter nq.addMust(es.newTermsFilter({ field: this.field, values: terms })); } - // reset the search page to the start and then trigger the next query nq.from = 0; this.edge.pushQuery(nq); this.edge.doQuery(); @@ -1293,22 +1340,18 @@ $.extend(edges, { return true; }; - this.removeFilter = function(params) { + this.removeFilter = function (params) { var term = params.value; var nq = this.edge.cloneQuery(); - // first find out if there was a terms filter already in place var filters = nq.listMust(es.newTermsFilter({field: this.field})); if (filters.length > 0) { var filter = filters[0]; if (filter.has_term(term)) { - // the filter we are being asked to remove is the actual selected one filter.remove_term(term); } else { - // the filter we are being asked to remove may be a parent of the actual selected one - // first get all the parent sets of the values that are currently in force var removes = []; for (var i = 0; i < filter.values.length; i++) { var val = filter.values[i]; @@ -1322,14 +1365,10 @@ $.extend(edges, { } } - // look to see if the term has a parent chain var grandparents = this.parentIndex[term]; if (grandparents.length > 0) { - // if it does, get a candidate value to add to the filter var immediate = grandparents[grandparents.length - 1]; - // we only want to add the candidate value to the filter if it is not a grandparent of any - // of the existing filters var other_terms = filter.values; var tripwire = false; for (var i = 0; i < other_terms.length; i++) { @@ -1351,19 +1390,16 @@ $.extend(edges, { } } - // reset the search page to the start and then trigger the next query nq.from = 0; this.edge.pushQuery(nq); this.edge.doQuery(); }; - this._pruneTree = function() { - // to list all possible terms, build off the base query + this._pruneTree = function () { var bq = this.edge.cloneBaseQuery(); bq.clearAggregations(); bq.size = 0; - // now add the aggregation that we want var params = { name: this.id, field: this.field @@ -1375,7 +1411,6 @@ $.extend(edges, { es.newTermsAggregation(params) ); - // issue the query to elasticsearch this.edge.queryAdapter.doQuery({ edge: this.edge, query: bq, @@ -1384,7 +1419,7 @@ $.extend(edges, { }); }; - this._querySuccess = function(params) { + this._querySuccess = function (params) { var result = params.result; var agg = result.aggregation(this.id); @@ -1423,28 +1458,25 @@ $.extend(edges, { } return {newTree: newTree, treeCount: treeCount} } + var treeUpdate = recurse(this.tree); this.tree = treeUpdate.newTree; this.pruned = true; - // in case there's a race between this and another update operation, subsequently synchronise this.synchronise(); - // since this happens asynchronously, we may want to draw this.draw(); }; - this._queryFail = function() { - console.log("pruneTree query failed"); + this._queryFail = function () { this.tree = []; this.pruned = true; - // in case there's a race between this and another update operation, subsequently synchronise this.synchronise(); - // since this happens asynchronously, we may want to draw this.draw(); }; } + }); diff --git a/src/edges.js b/src/edges.js index ec908a2..61ab30a 100644 --- a/src/edges.js +++ b/src/edges.js @@ -28,12 +28,14 @@ var edges = { * @param components {Array} List of all the components that are involved in this edge * @param renderPacks=[edges.bs3, edges.nvd3, edges.highcharts, edges.google, edges.d3] {Array} Render packs to use to source automatically assigned rendering objects. Defaults to [edges.bs3, edges.nvd3, edges.highcharts, edges.google, edges.d3] */ - newEdge : function(params) { - if (!params) { params = {} } + newEdge: function (params) { + if (!params) { + params = {} + } return new edges.Edge(params); }, /** @class */ - Edge : function(params) { + Edge: function (params) { ///////////////////////////////////////////// // parameters that can be set via params arg @@ -158,7 +160,7 @@ var edges = { // startup functions // at the bottom of this constructor, we'll call this function - this.startup = function() { + this.startup = function () { // obtain the jquery context for all our operations this.context = $(this.selector); @@ -169,7 +171,7 @@ var edges = { if (this.manageUrl) { var urlParams = this.getUrlParams(); if (this.urlQuerySource in urlParams) { - this.urlQuery = es.newQuery({raw : urlParams[this.urlQuerySource]}); + this.urlQuery = es.newQuery({raw: urlParams[this.urlQuerySource]}); delete urlParams[this.urlQuerySource]; } this.urlParams = urlParams; @@ -195,13 +197,13 @@ var edges = { this.loadStaticsAsync(onward); }; - this.startupPart2 = function() { + this.startupPart2 = function () { // FIXME: at this point we should check whether the statics all loaded correctly var onward = edges.objClosure(this, "startupPart3"); this.runPreflightQueries(onward); }; - this.startupPart3 = function() { + this.startupPart3 = function () { // determine whether to initialise with either the openingQuery or the urlQuery var requestedQuery = this.openingQuery; @@ -230,12 +232,12 @@ var edges = { ///////////////////////////////////////////////////////// // Edges lifecycle functions - this.doQuery = function() { + this.doQuery = function () { // the original doQuery has become doPrimaryQuery, so this has been aliased for this.cycle this.cycle(); }; - this.cycle = function() { + this.cycle = function () { // if a search is currently executing, don't do anything, else turn it on // FIXME: should we queue them up? - see the d3 map for an example of how to do this if (this.searching) { @@ -263,12 +265,12 @@ var edges = { } }; - this.cyclePart2 = function() { + this.cyclePart2 = function () { var onward = edges.objClosure(this, "cyclePart3"); this.runSecondaryQueries(onward); }; - this.cyclePart3 = function() { + this.cyclePart3 = function () { this.synchronise(); // pre-render trigger @@ -282,7 +284,7 @@ var edges = { this.searching = false; }; - this.synchronise = function() { + this.synchronise = function () { // ask the components to synchronise themselves with the latest state for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; @@ -290,7 +292,7 @@ var edges = { } }; - this.draw = function() { + this.draw = function () { for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; component.draw(this); @@ -298,7 +300,7 @@ var edges = { }; // reset the query to the start and re-issue the query - this.reset = function() { + this.reset = function () { // tell the world we're about to reset this.trigger("edges:pre-reset"); @@ -322,14 +324,14 @@ var edges = { this.cycle(); }; - this.sleep = function() { + this.sleep = function () { for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; component.sleep(); } }; - this.wake = function() { + this.wake = function () { for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; component.wake(); @@ -339,28 +341,28 @@ var edges = { //////////////////////////////////////////////////// // functions for working with the queries - this.cloneQuery = function() { + this.cloneQuery = function () { if (this.currentQuery) { return $.extend(true, {}, this.currentQuery); } return false; }; - this.pushQuery = function(query) { + this.pushQuery = function (query) { if (this.baseQuery) { query.merge(this.baseQuery); } this.currentQuery = query; }; - this.cloneBaseQuery = function() { + this.cloneBaseQuery = function () { if (this.baseQuery) { return $.extend(true, {}, this.baseQuery); } return es.newQuery(); }; - this.cloneOpeningQuery = function() { + this.cloneOpeningQuery = function () { if (this.openingQuery) { return $.extend(true, {}, this.openingQuery); } @@ -372,8 +374,8 @@ var edges = { // execute the query and all the associated workflow // FIXME: could replace this with an async group for neatness - this.doPrimaryQuery = function(callback) { - var context = {"callback" : callback}; + this.doPrimaryQuery = function (callback) { + var context = {"callback": callback}; this.queryAdapter.doQuery({ edge: this, @@ -382,7 +384,7 @@ var edges = { }); }; - this.queryFail = function(params) { + this.queryFail = function (params) { var callback = params.callback; var response = params.response; this.trigger("edges:query-fail"); @@ -395,7 +397,7 @@ var edges = { callback(); }; - this.querySuccess = function(params) { + this.querySuccess = function (params) { this.result = params.result; var callback = params.callback; @@ -404,7 +406,7 @@ var edges = { callback(); }; - this.runPreflightQueries = function(callback) { + this.runPreflightQueries = function (callback) { if (!this.preflightQueries || Object.keys(this.preflightQueries).length == 0) { callback(); return; @@ -422,7 +424,7 @@ var edges = { var that = this; var pg = edges.newAsyncGroup({ list: entries, - action: function(params) { + action: function (params) { var entry = params.entry; var success = params.success_callback; var error = params.error_callback; @@ -436,16 +438,16 @@ var edges = { }); }, successCallbackArgs: ["result"], - success: function(params) { + success: function (params) { var result = params.result; var entry = params.entry; that.preflightResults[entry.id] = result; }, - errorCallbackArgs : ["result"], - error: function(params) { + errorCallbackArgs: ["result"], + error: function (params) { that.trigger("edges:error-preflight"); }, - carryOn: function() { + carryOn: function () { that.trigger("edges:post-preflight"); callback(); } @@ -454,7 +456,7 @@ var edges = { pg.process(); }; - this.runSecondaryQueries = function(callback) { + this.runSecondaryQueries = function (callback) { this.realisedSecondaryQueries = {}; if (!this.secondaryQueries || Object.keys(this.secondaryQueries).length == 0) { callback(); @@ -478,7 +480,7 @@ var edges = { var that = this; var pg = edges.newAsyncGroup({ list: entries, - action: function(params) { + action: function (params) { var entry = params.entry; var success = params.success_callback; var error = params.error_callback; @@ -492,16 +494,16 @@ var edges = { }); }, successCallbackArgs: ["result"], - success: function(params) { + success: function (params) { var result = params.result; var entry = params.entry; that.secondaryResults[entry.id] = result; }, - errorCallbackArgs : ["result"], - error: function(params) { + errorCallbackArgs: ["result"], + error: function (params) { // FIXME: not really sure what to do about this }, - carryOn: function() { + carryOn: function () { callback(); } }); @@ -512,7 +514,7 @@ var edges = { //////////////////////////////////////////////// // various utility functions - this.getComponent = function(params) { + this.getComponent = function (params) { var id = params.id; for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; @@ -524,7 +526,7 @@ var edges = { }; // return components in the requested category - this.category = function(cat) { + this.category = function (cat) { var comps = []; for (var i = 0; i < this.components.length; i++) { var component = this.components[i]; @@ -535,7 +537,7 @@ var edges = { return comps; }; - this.getRenderPackObject = function(oname, params) { + this.getRenderPackObject = function (oname, params) { for (var i = 0; i < this.renderPacks.length; i++) { var rp = this.renderPacks[i]; if (rp && rp.hasOwnProperty(oname)) { @@ -547,11 +549,11 @@ var edges = { // get the jquery object for the desired element, in the correct context // you should ALWAYS use this, rather than the standard jquery $ object - this.jq = function(selector) { + this.jq = function (selector) { return $(selector, this.context); }; - this.trigger = function(event_name) { + this.trigger = function (event_name) { if (event_name in this.callbacks) { this.callbacks[event_name](this); } @@ -561,22 +563,22 @@ var edges = { ///////////////////////////////////////////////////// // URL management functions - this.getUrlParams = function() { + this.getUrlParams = function () { return edges.getUrlParams(); }; - this.urlQueryArg = function(objectify_options) { + this.urlQueryArg = function (objectify_options) { if (!objectify_options) { if (this.urlQueryOptions) { objectify_options = this.urlQueryOptions } else { objectify_options = { - include_query_string : true, - include_filters : true, - include_paging : true, - include_sort : true, - include_fields : false, - include_aggregations : false + include_query_string: true, + include_filters: true, + include_paging: true, + include_sort: true, + include_fields: false, + include_aggregations: false } } } @@ -586,17 +588,17 @@ var edges = { return obj; }; - this.fullQueryArgs = function() { + this.fullQueryArgs = function () { var args = $.extend(true, {}, this.urlParams); $.extend(args, this.urlQueryArg()); return args; }; - this.fullUrlQueryString = function() { + this.fullUrlQueryString = function () { return this._makeUrlQuery(this.fullQueryArgs()) }; - this._makeUrlQuery = function(args) { + this._makeUrlQuery = function (args) { var keys = Object.keys(args); var entries = []; for (var i = 0; i < keys.length; i++) { @@ -607,7 +609,7 @@ var edges = { return entries.join("&"); }; - this.fullUrl = function() { + this.fullUrl = function () { var args = this.fullQueryArgs(); var fragment = ""; if (args["#"]) { @@ -620,7 +622,7 @@ var edges = { return url; }; - this.updateUrl = function() { + this.updateUrl = function () { var currentQs = window.location.search; var qs = "?" + this.fullUrlQueryString(); @@ -641,7 +643,7 @@ var edges = { ///////////////////////////////////////////// // static file management - this.loadStaticsAsync = function(callback) { + this.loadStaticsAsync = function (callback) { if (!this.staticFiles || this.staticFiles.length == 0) { this.trigger("edges:post-load-static"); callback(); @@ -651,7 +653,7 @@ var edges = { var that = this; var pg = edges.newAsyncGroup({ list: this.staticFiles, - action: function(params) { + action: function (params) { var entry = params.entry; var success = params.success_callback; var error = params.error_callback; @@ -669,24 +671,24 @@ var edges = { }) }, successCallbackArgs: ["data"], - success: function(params) { + success: function (params) { var data = params.data; var entry = params.entry; if (entry.processor) { - var processed = entry.processor({data : data}); + var processed = entry.processor({data: data}); that.resources[entry.id] = processed; if (entry.opening) { - entry.opening({resource : processed, edge: that}); + entry.opening({resource: processed, edge: that}); } } that.static[entry.id] = data; }, - errorCallbackArgs : ["data"], - error: function(params) { + errorCallbackArgs: ["data"], + error: function (params) { that.errorLoadingStatic.push(params.entry.id); that.trigger("edges:error-load-static"); }, - carryOn: function() { + carryOn: function () { that.trigger("edges:post-load-static"); callback(); } @@ -703,11 +705,13 @@ var edges = { ////////////////////////////////////////////////// // Asynchronous resource loading feature - newAsyncGroup : function(params) { - if (!params) { params = {} } + newAsyncGroup: function (params) { + if (!params) { + params = {} + } return new edges.AsyncGroup(params); }, - AsyncGroup : function(params) { + AsyncGroup: function (params) { this.list = params.list; this.successCallbackArgs = params.successCallbackArgs; this.errorCallbackArgs = params.errorCallbackArgs; @@ -728,13 +732,13 @@ var edges = { this.finished = false; - this.construct = function(params) { + this.construct = function (params) { for (var i = 0; i < this.list.length; i++) { this.checkList.push(0); } }; - this.process = function(params) { + this.process = function (params) { if (this.list.length == 0) { this.functions.carryOn(); } @@ -746,7 +750,8 @@ var edges = { var error_callback = edges.objClosure(this, "_actionError", this.successCallbackArgs, context); var complete_callback = false; - this.functions.action({entry: this.list[i], + this.functions.action({ + entry: this.list[i], success_callback: success_callback, error_callback: error_callback, complete_callback: complete_callback @@ -754,7 +759,7 @@ var edges = { } }; - this._actionSuccess = function(params) { + this._actionSuccess = function (params) { var index = params.index; delete params.index; @@ -767,7 +772,7 @@ var edges = { } }; - this._actionError = function(params) { + this._actionError = function (params) { var index = params.index; delete params.index; @@ -780,15 +785,15 @@ var edges = { } }; - this._actionComplete = function(params) { + this._actionComplete = function (params) { }; - this._isComplete = function() { + this._isComplete = function () { return $.inArray(0, this.checkList) === -1; }; - this._finalise = function() { + this._finalise = function () { if (this.finished) { return; } @@ -803,20 +808,25 @@ var edges = { ///////////////////////////////////////////// // Query adapter base class and core ES implementation - newQueryAdapter : function(params) { - if (!params) { params = {} } + newQueryAdapter: function (params) { + if (!params) { + params = {} + } return edges.instantiate(edges.QueryAdapter, params); }, - QueryAdapter : function(params) { - this.doQuery = function(params) {}; + QueryAdapter: function (params) { + this.doQuery = function (params) { + }; }, - newESQueryAdapter : function(params) { - if (!params) { params = {} } + newESQueryAdapter: function (params) { + if (!params) { + params = {} + } return edges.instantiate(edges.ESQueryAdapter, params); }, - ESQueryAdapter : function(params) { - this.doQuery = function(params) { + ESQueryAdapter: function (params) { + this.doQuery = function (params) { var edge = params.edge; var query = params.query; var success = params.success; @@ -839,31 +849,38 @@ var edges = { ///////////////////////////////////////////// // Base classes for the various kinds of components - newRenderer : function(params) { - if (!params) { params = {} } + newRenderer: function (params) { + if (!params) { + params = {} + } return new edges.Renderer(params); }, - Renderer : function(params) { + Renderer: function (params) { this.component = params.component || false; - this.init = function(component) { + this.init = function (component) { this.component = component }; - this.draw = function(component) {}; - this.sleep = function() {}; - this.wake = function() {} + this.draw = function (component) { + }; + this.sleep = function () { + }; + this.wake = function () { + } }, - newComponent : function(params) { - if (!params) { params = {} } + newComponent: function (params) { + if (!params) { + params = {} + } return new edges.Component(params); }, - Component : function(params) { + Component: function (params) { this.id = params.id; this.renderer = params.renderer; this.category = params.category || "none"; this.defaultRenderer = params.defaultRenderer || "newRenderer"; - this.init = function(edge) { + this.init = function (edge) { // record a reference to the parent object this.edge = edge; this.context = this.edge.jq("#" + this.id); @@ -877,39 +894,43 @@ var edges = { } }; - this.draw = function() { + this.draw = function () { if (this.renderer) { this.renderer.draw(); } }; - this.contrib = function(query) {}; - this.synchronise = function() {}; + this.contrib = function (query) { + }; + this.synchronise = function () { + }; - this.sleep = function() { + this.sleep = function () { if (this.renderer) { this.renderer.sleep(); } }; - this.wake = function() { + this.wake = function () { if (this.renderer) { this.renderer.wake(); } }; // convenience method for any renderer rendering a component - this.jq = function(selector) { + this.jq = function (selector) { return this.edge.jq(selector); } }, - newSelector : function(params) { - if (!params) { params = {} } + newSelector: function (params) { + if (!params) { + params = {} + } edges.Selector.prototype = edges.newComponent(params); return new edges.Selector(params); }, - Selector : function(params) { + Selector: function (params) { // field upon which to build the selector this.field = params.field; @@ -925,56 +946,62 @@ var edges = { this.category = params.category || "selector"; }, - newTemplate : function(params) { - if (!params) { params = {} } + newTemplate: function (params) { + if (!params) { + params = {} + } return new edges.Template(params); }, - Template : function(params) { - this.draw = function(edge) {} + Template: function (params) { + this.draw = function (edge) { + } }, - newNestedEdge : function(params) { - if (!params) { params = {}} + newNestedEdge: function (params) { + if (!params) { + params = {} + } params.category = params.category || "edge"; params.renderer = false; params.defaultRenderer = false; return edges.instantiate(edges.NestedEdge, params, edges.newComponent) }, - NestedEdge : function(params) { + NestedEdge: function (params) { this.constructOnInit = edges.getParam(params.constructOnInit, false); this.constructArgs = edges.getParam(params.constructArgs, {}); this.inner = false; - this.init = function(edge) { + this.init = function (edge) { this.edge = edge; if (this.constructOnInit) { this.construct_and_bind(); } }; - this.setConstructArg = function(key, value) { + this.setConstructArg = function (key, value) { this.constructArgs[key] = value; }; - this.getConstructArg = function(key, def) { + this.getConstructArg = function (key, def) { if (this.constructArgs.hasOwnProperty(key)) { return this.constructArgs[key]; } return def; }; - this.construct_and_bind = function() { + this.construct_and_bind = function () { this.construct(); if (this.inner) { this.inner.outer = this; } }; - this.construct = function() {}; + this.construct = function () { + }; - this.destroy = function() { + this.destroy = function () { if (this.inner) { this.inner.context.empty(); this.inner.context.hide(); @@ -982,12 +1009,12 @@ var edges = { this.inner = false; }; - this.sleep = function() { + this.sleep = function () { this.inner.sleep(); this.inner.context.hide(); }; - this.wake = function() { + this.wake = function () { if (this.inner) { this.inner.context.show(); this.inner.wake(); @@ -1002,8 +1029,10 @@ var edges = { // instantiate an object with the parameters and the (optional) // prototype - instantiate : function(clazz, params, protoConstructor) { - if (!params) { params = {} } + instantiate: function (clazz, params, protoConstructor) { + if (!params) { + params = {} + } if (protoConstructor) { clazz.prototype = protoConstructor(params); } @@ -1015,7 +1044,7 @@ var edges = { }, // call a method on the parent class - up : function(inst, fn, args) { + up: function (inst, fn, args) { var parent = new inst.__proto_constructor__(); parent[fn].apply(inst, args); }, @@ -1043,8 +1072,8 @@ var edges = { // results in a call to // this.function({one: arg1, two: arg2}) // - objClosure : function(obj, fn, args, context_params) { - return function() { + objClosure: function (obj, fn, args, context_params) { + return function () { if (args) { var params = {}; for (var i = 0; i < args.length; i++) { @@ -1086,11 +1115,11 @@ var edges = { // results in a call (only in the case that the event is a click), to // this.handler(element) // - eventClosure : function(obj, fn, conditional, preventDefault) { + eventClosure: function (obj, fn, conditional, preventDefault) { if (preventDefault === undefined) { preventDefault = true; } - return function(event) { + return function (event) { if (conditional) { if (!conditional(event)) { return; @@ -1106,7 +1135,7 @@ var edges = { ////////////////////////////////////////////////////////////////// // CSS normalising/canonicalisation tools - css_classes : function(namespace, field, renderer) { + css_classes: function (namespace, field, renderer) { var cl = namespace + "-" + field; if (renderer) { cl += " " + cl + "-" + renderer.component.id; @@ -1114,7 +1143,7 @@ var edges = { return cl; }, - css_class_selector : function(namespace, field, renderer) { + css_class_selector: function (namespace, field, renderer) { var sel = "." + namespace + "-" + field; if (renderer) { sel += sel + "-" + renderer.component.id; @@ -1122,7 +1151,7 @@ var edges = { return sel; }, - css_id : function(namespace, field, renderer) { + css_id: function (namespace, field, renderer) { var id = namespace + "-" + field; if (renderer) { id += "-" + renderer.component.id; @@ -1130,14 +1159,14 @@ var edges = { return id; }, - css_id_selector : function(namespace, field, renderer) { + css_id_selector: function (namespace, field, renderer) { return "#" + edges.css_id(namespace, field, renderer); }, ////////////////////////////////////////////////////////////////// // Event binding utilities - on : function(selector, event, caller, targetFunction, delay, conditional, preventDefault) { + on: function (selector, event, caller, targetFunction, delay, conditional, preventDefault) { if (preventDefault === undefined) { preventDefault = true; } @@ -1180,7 +1209,7 @@ var edges = { } }, - off : function(selector, event, caller) { + off: function (selector, event, caller) { // if the caller has an inner component (i.e. it is a Renderer), use the component's id // otherwise, if it has a namespace (which is true of Renderers or Templates) use that if (caller.component && caller.component.id) { @@ -1204,7 +1233,7 @@ var edges = { ////////////////////////////////////////////////////////////////// // Shared utilities - getUrlParams : function() { + getUrlParams: function () { var params = {}; var url = window.location.href; var fragment = false; @@ -1229,7 +1258,7 @@ var edges = { // if it looks like a JSON object in string form... // remove " (double quotes) at beginning and end of string to make it a valid // representation of a JSON object, or the parser will complain - val = val.replace(/^"/,"").replace(/"$/,""); + val = val.replace(/^"/, "").replace(/"$/, ""); val = JSON.parse(val); } params[key] = val; @@ -1244,7 +1273,7 @@ var edges = { return params; }, - escapeHtml : function(unsafe, def) { + escapeHtml: function (unsafe, def) { if (def === undefined) { def = ""; } @@ -1261,7 +1290,7 @@ var edges = { .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); - } catch(err) { + } catch (err) { return def; } }, @@ -1273,7 +1302,7 @@ var edges = { * @param path * @returns {boolean} */ - hasProp : function(obj, path) { + hasProp: function (obj, path) { var bits = path.split("."); var ctx = obj; for (var i = 0; i < bits.length; i++) { @@ -1293,7 +1322,7 @@ var edges = { * @param def * @returns {*} */ - objVal : function(path, rec, def) { + objVal: function (path, rec, def) { if (def === undefined) { def = false; } @@ -1320,8 +1349,10 @@ var edges = { * @param def * @returns {*} */ - objVals : function(path, rec, def) { - if (def === undefined) { def = false; } + objVals: function (path, rec, def) { + if (def === undefined) { + def = false; + } var bits = path.split("."); var contexts = [rec]; @@ -1357,22 +1388,22 @@ var edges = { return contexts; }, - getParam : function(value, def) { + getParam: function (value, def) { return value !== undefined ? value : def; }, - safeId : function(unsafe) { + safeId: function (unsafe) { return unsafe.replace(/&/g, "_") - .replace(//g, "_") - .replace(/"/g, "_") - .replace(/'/g, "_") - .replace(/\./gi,'_') - .replace(/\:/gi,'_') - .replace(/\s/gi,"_"); + .replace(//g, "_") + .replace(/"/g, "_") + .replace(/'/g, "_") + .replace(/\./gi, '_') + .replace(/\:/gi, '_') + .replace(/\s/gi, "_"); }, - numFormat : function(params) { + numFormat: function (params) { var reflectNonNumbers = edges.getParam(params.reflectNonNumbers, false); var prefix = edges.getParam(params.prefix, ""); var zeroPadding = edges.getParam(params.zeroPadding, false); @@ -1381,7 +1412,7 @@ var edges = { var decimalSeparator = edges.getParam(params.decimalSeparator, "."); var suffix = edges.getParam(params.suffix, ""); - return function(number) { + return function (number) { // ensure this is really a number var num = parseFloat(number); if (isNaN(num)) { @@ -1397,7 +1428,7 @@ var edges = { if (decimalPlaces !== false) { num = num.toFixed(decimalPlaces); } else { - num = num.toString(); + num = num.toString(); } // now "num" is a string containing the formatted number that we can work on @@ -1425,10 +1456,10 @@ var edges = { } }, - numParse : function(params) { + numParse: function (params) { var commaRx = new RegExp(",", "g"); - return function(num) { + return function (num) { num = num.trim(); num = num.replace(commaRx, ""); if (num === "") { @@ -1438,11 +1469,23 @@ var edges = { } }, - isEmptyObject: function(obj) { - for(var key in obj) { - if(obj.hasOwnProperty(key)) + isEmptyObject: function (obj) { + for (var key in obj) { + if (obj.hasOwnProperty(key)) return false; } return true; + }, + + error: { + NotImplementedError: function (params) { + edges.error.NotImplementedErrorInst.prototype = Object.create(Error.prototype); + edges.error.NotImplementedErrorInst.prototype.constructor = edges.error.NotImplementedErrorInst; + return edges.error.NotImplementedErrorInst.call(params); + }, + NotImplementedErrorInst: function (message) { + this.name = 'NotImplementedError'; + this.message = message || 'This method should be implemented by the derived class'; + }, } }; diff --git a/src/renderers/bs3.SelectedFiltersRenderer.js b/src/renderers/bs3.SelectedFiltersRenderer.js index 662a6c7..7fe39cd 100644 --- a/src/renderers/bs3.SelectedFiltersRenderer.js +++ b/src/renderers/bs3.SelectedFiltersRenderer.js @@ -65,7 +65,7 @@ $.extend(true, edges, { if (this.allowRemove) { var removeClass = edges.css_classes(ns, "remove", this); if (def.filter == "term" || def.filter === "terms") { - filters += ''; + filters += ''; filters += ''; filters += ""; } else if (def.filter === "range") { @@ -107,6 +107,7 @@ $.extend(true, edges, { // event handlers this.removeFilter = function (element) { + var sf = this.component; var el = this.component.jq(element); var field = el.attr("data-field"); var ft = el.attr("data-filter"); @@ -114,7 +115,10 @@ $.extend(true, edges, { var value = false; if (ft === "terms" || ft === "term") { - value = el.attr("data-value"); + // value = el.attr("data-value"); + values = sf.mustFilters[field].values; + idx = el.attr("data-value-idx") + value = values[idx].val } else if (ft === "range") { value = {};