UNPKG

foam-framework

Version:
173 lines (159 loc) 4.38 kB
/** * @license * Copyright 2014 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ CLASS({ package: 'foam.ui', name: 'AutocompleteListView', extends: 'foam.ui.SimpleView', properties: [ { name: 'dao', postSet: function(oldValue, newValue) { oldValue && oldValue.unlisten(this.paint); newValue.listen(this.paint); this.data = ''; this.paint(); }, hidden: true }, { name: 'model', hidden: true }, { name: 'innerView', type: 'foam.ui.View', preSet: function(_, value) { if ( typeof value === "string" ) value = GLOBAL[value]; return value; }, defaultValueFn: function() { return this.model.listView; } }, { model_: 'ArrayProperty', name: 'objs' }, { model_: 'IntProperty', name: 'selection', defaultValue: 0, postSet: function(oldValue, newValue) { this.data = this.objs[newValue]; if ( this.$ ) { if ( this.$.children[oldValue] ) this.$.children[oldValue].className = 'autocompleteListItem'; this.$.children[newValue].className += ' autocompleteSelectedItem'; } } }, { model_: 'IntProperty', name: 'count', defaultValue: 20 }, { model_: 'IntProperty', name: 'left' }, { model_: 'IntProperty', name: 'top' }, ], methods: { initHTML: function() { this.SUPER(); this.$.style.display = 'none'; var self = this; this.propertyValue('left').addListener(function(v) { self.$.left = v; }); this.propertyValue('top').addListener(function(v) { self.$.top = v; }); }, nextSelection: function() { if ( this.objs.length === 0 ) return; var next = this.selection + 1; if ( next >= this.objs.length ) next = 0; this.selection = next; }, prevSelection: function() { if ( this.objs.length === 0 ) return; var next = this.selection - 1; if ( next < 0 ) next = this.objs.length - 1; this.selection = next; } }, templates: [ { name: 'toHTML', template: '<ul class="autocompleteListView" id="<%= this.id %>"></ul>' } ], listeners: [ { name: 'paint', isFramed: true, code: function() { if ( ! this.$ ) return; // TODO Determine if its worth double buffering the dom. var objs = []; var newSelection = 0; var value = this.data; var self = this; this.dao.limit(this.count).select({ put: function(obj) { objs.push(obj); if ( obj.id === value.id ) newSelection = objs.length - 1; }, eof: function() { // Clear old list self.$.innerHTML = ''; self.objs = objs; if ( objs.length === 0 ) { self.$.style.display = 'none'; return; } for ( var i = 0; i < objs.length; i++ ) { var obj = objs[i]; var view = self.innerView.create({}); var container = document.createElement('li'); container.onclick = (function(index) { return function(e) { self.selection = index; self.publish('selected'); }; })(i); container.className = 'autocompleteListItem'; self.$.appendChild(container); view.data = obj; container.innerHTML = view.toHTML(); view.initHTML(); } self.selection = newSelection; self.$.style.display = ''; } }); } } ] });