| <!-- The <query2-sk> custom element declaration. |
| |
| Starting from a serialized paramtools.ParamSet, this control allows the user |
| to build up a query, suitable for passing to query.New. |
| |
| Attributes: |
| current_query - The current query formatted as a URL formatted query string. |
| |
| Events: |
| 'query-change' |
| The 'query2-sk' element will produce 'query-change' events when the query |
| parameters chosen have changed. The event contains the current |
| selections formatted as a URL query, found in e.detail.q. |
| |
| 'query-change-delayed' |
| The same exact event as query-change, but with a 500ms delay after |
| the query stops changing. |
| |
| Methods: |
| setCurrentQuery(s) - Sets the query selections of the control, where 's' |
| is a URL formatted query string, as returned from current_query. |
| |
| setParamset(p) - A serialized paramtools.ParamSet, that is the source |
| of the options for the query. |
| |
| setKeyOrder(s) - An array of strings, the keys in the order they should |
| appear. All keys not in the key order will be present after and in |
| alphabetical order. |
| --> |
| |
| <link rel="stylesheet" href="/res/common/css/md.css"> |
| <link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html"> |
| <link rel="import" href="/res/imp/bower_components/paper-input/paper-input.html"> |
| <link rel="import" href="/res/imp/bower_components/iron-selector/iron-selector.html"> |
| |
| <link rel="import" href="query2-values-sk.html"> |
| |
| <dom-module id="query2-sk"> |
| <style include="iron-flex iron-flex-alignment iron-positioning"> |
| input { |
| margin: 0 1em; |
| } |
| |
| iron-selector { |
| cursor: pointer; |
| border: solid 1px #A6CEE3; |
| margin-top: 6px; |
| max-height: 600px; |
| overflow-y: auto; |
| } |
| |
| iron-selector div { |
| padding: 0.4em 1.2em; |
| background-color: white; |
| border: none; |
| outline: none; |
| line-height: 20px; |
| vertical-align: middle; |
| } |
| |
| iron-selector div:hover { |
| background-color: #A6CEE3; |
| } |
| |
| iron-selector div.iron-selected { |
| background: #eee; |
| } |
| |
| iron-selector div.iron-selected:hover { |
| background: #1F78B4; |
| color: white; |
| } |
| |
| </style> |
| <template> |
| <div class="horizontal layout"> |
| <div class="vertical layout"> |
| <div class="horizontal layout"> |
| <paper-input id="fast" label="Filter" on-input="_fastFilter"></paper-input> |
| <button on-tap="_clearFilter">Clear Filter</button> |
| </div> |
| <iron-selector id=keys size=12 |
| on-selected-items-changed="_keyChange" |
| attr-for-selected=value |
| > |
| <template is="dom-repeat" items="[[_keys]]"> |
| <div value="[[item]]">[[item]]</div> |
| </template> |
| </iron-selector> |
| <button on-tap="_clear">Clear Selections</button> |
| </div> |
| <query2-values-sk id=values on-query2-values-changed="_valuesChanged"></query2-values-sk> |
| </div> |
| </template> |
| </dom-module> |
| |
| <script> |
| Polymer({ |
| is: "query2-sk", |
| |
| properties: { |
| // The serialized form of _query. |
| current_query: { |
| type: String, |
| value: "", |
| reflectToAttribute: true, |
| notify: true, |
| observer: "_currentQueryChanged", |
| }, |
| |
| // A serialized paramtools.ParamSet, which we are building a query around. |
| // |
| // Might contain a subset of _originalParamset if filtering has been applied. |
| _paramset: { |
| type: Object, |
| value: function() { return {}; }, |
| }, |
| |
| // A serialized paramtools.ParamSet, which we are building a query around. |
| _originalParamset: { |
| type: Object, |
| value: function() { return {}; }, |
| }, |
| |
| // The keys of paramset. |
| _keys: { |
| type: Array, |
| value: function() { return []; }, |
| }, |
| |
| // The currently selected key from _keys. |
| _selectedKey: { |
| type: String, |
| value: "", |
| }, |
| |
| // The current set of user selections. |
| _query: { |
| type: Object, |
| value: function() { return {}; }, |
| }, |
| // The order for some or all of the keys. An array of strings. |
| _key_order: { |
| type: Array, |
| value: [], |
| }, |
| _delayedTimeout: { |
| type: Number, |
| value: null, |
| }, |
| }, |
| |
| setCurrentQuery: function(s) { |
| this._query = sk.query.toParamSet(s); |
| this._queryChanged(); |
| }, |
| |
| _currentQueryChanged: function(s) { |
| this.setCurrentQuery(s) |
| }, |
| |
| setParamset: function(paramset) { |
| this._originalParamset = paramset; |
| this._paramset = paramset; |
| this._recalcKeys(); |
| }, |
| |
| setKeyOrder: function(key_order) { |
| this._key_order = key_order; |
| }, |
| |
| _recalcKeys: function() { |
| var keys = Object.keys(this._paramset); |
| keys.sort(); |
| // Pull out all the keys that appear in _key_order to be pushed |
| // to the front of the list, store them in 'pre'. |
| var pre = []; |
| this._key_order.forEach(function(key) { |
| var index = keys.indexOf(key); |
| if (index != -1) { |
| pre.push(keys.splice(index, 1)[0]); |
| } |
| }.bind(this)); |
| keys = pre.concat(keys); |
| |
| var key = this.$.keys.selected; |
| |
| this.set("_keys", keys); |
| this.$.keys.selectedIndex = -1; |
| this.$.keys.selected = key; |
| this._keyChange(); |
| }, |
| |
| _fastFilter: function() { |
| var filters = this.$.fast.value.trim().toLowerCase().split(/\s+/); |
| |
| // Create a closure that returns true if the given label |
| // matches the filter. |
| var matches = function(s) { |
| s = s.toLowerCase(); |
| for (var i = 0; i < filters.length; i++) { |
| if (s.indexOf(filters[i]) >= 0) { |
| return true; |
| } |
| } |
| return false; |
| }; |
| |
| // Loop over this._originalParamset. |
| var filtered = {}; |
| Object.keys(this._originalParamset).forEach(function(paramkey) { |
| // If the param key matches, then all the values go over. |
| if (matches(paramkey)) { |
| filtered[paramkey] = this._originalParamset[paramkey]; |
| } else { |
| // Look for matches in the param values. |
| var valueMatches = []; |
| this._originalParamset[paramkey].forEach(function(paramvalue) { |
| if (matches(paramvalue)) { |
| valueMatches.push(paramvalue); |
| } |
| }.bind(this)); |
| if (valueMatches.length > 0) { |
| filtered[paramkey] = valueMatches; |
| } |
| } |
| }.bind(this)); |
| |
| this._paramset = filtered; |
| this._recalcKeys(); |
| }, |
| |
| _clearFilter: function() { |
| this._paramset = this._originalParamset; |
| this._recalcKeys(); |
| this.$.fast.value = ""; |
| }, |
| |
| _keyChange: function() { |
| var key = this.$.keys.selected; |
| this.$.values.setOptions(this._paramset[key], this._query[key]); |
| }, |
| |
| _valuesChanged: function(e) { |
| var key = this.$.keys.selected; |
| this._query[key] = e.detail; |
| this._queryChanged(); |
| }, |
| |
| _queryChanged: function() { |
| var prev_query = this.current_query; |
| this.current_query = sk.query.fromParamSet(this._query); |
| if (prev_query !== this.current_query) { |
| this.dispatchEvent(new CustomEvent('query-change', { |
| detail: {q: this.current_query}, |
| bubbles: true, |
| })); |
| clearTimeout(this._delayedTimeout); |
| this._delayedTimeout = setTimeout(function() { |
| this.dispatchEvent(new CustomEvent('query-change-delayed', { |
| detail: {q: this.current_query}, |
| bubbles: true, |
| })); |
| }.bind(this), 500); |
| } |
| }, |
| |
| _clear: function() { |
| this._query = {}; |
| this._recalcKeys(); |
| this._queryChanged(); |
| }, |
| |
| }); |
| </script> |