foam-framework
Version:
MVC metaprogramming framework
173 lines (159 loc) • 4.38 kB
JavaScript
/**
* @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 = '';
}
});
}
}
]
});