UNPKG

foam-framework

Version:
190 lines (178 loc) 5.46 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: 'ListInputView', extends: 'foam.ui.AbstractDAOView', properties: [ { name: 'name' }, { name: 'dao', help: 'The DAO to fetch autocomplete objects from.', }, { name: 'property', help: 'The property model to map autocomplete objecst to values with.' }, { model_: 'ArrayProperty', name: 'searchProperties', help: 'The properties with which to construct the autocomplete query with.' }, { name: 'autocompleteView', postSet: function(oldValue, newValue) { oldValue && oldValue.unsubscribe('selected', this.selected); newValue.subscribe('selected', this.selected); } }, { name: 'placeholder', postSet: function(oldValue, newValue) { if ( this.$ && this.usePlaceholer ) this.$.placeholder = newValue; } }, { model_: 'BooleanProperty', name: 'usePlaceholder', defaultValue: true, postSet: function(_, newValue) { if ( this.$ ) this.$.placeholder = newValue ? this.placeholder : ''; } }, { name: 'data', help: 'The array value we are editing.', factory: function() { return []; } }, { name: 'domInputValue' } ], methods: { toHTML: function() { this.on('keydown', this.onKeyDown, this.id); this.on('keypress', this.onKeyPress, this.id); this.on('blur', this.framed(this.delay(200, this.framed(this.framed(this.onBlur)))), this.id); this.on('focus', this.onInput, this.id); return '<input name="' + this.name + '" type="text" id="' + this.id + '" class="listInputView">' + this.autocompleteView.toHTML(); }, initHTML: function() { this.SUPER(); if ( this.usePlaceholder && this.placeholder ) this.$.placeholder = this.placeholder; this.autocompleteView.initHTML(); this.domInputValue = DomValue.create(this.$, 'input'); this.domInputValue.addListener(this.onInput); }, pushValue: function(v) { this.data = this.data.concat(v); this.domInputValue.set(''); // Previous line doesn't trigger listeners. this.onInput(); }, popValue: function() { var a = this.data.slice(); a.pop(); this.data = a; } }, listeners: [ { name: 'selected', code: function() { if ( this.autocompleteView.data ) { this.pushValue( this.property.f(this.autocompleteView.data)); } this.scrollContainer = e || window; this.scrollContainer.addEventListener('scroll', this.onScroll, false); } }, { name: 'onInput', code: function() { var value = this.domInputValue.get(); if ( value.charAt(value.length - 1) === ',' ) { if ( value.length > 1 ) this.pushValue(value.substring(0, value.length - 1)); else this.domInputValue.set(''); return; } if ( value === '' ) { this.autocompleteView.dao = []; return; } var predicate = OR(); value = this.domInputValue.get(); for ( var i = 0; i < this.searchProperties.length; i++ ) { predicate.args.push(STARTS_WITH(this.searchProperties[i], value)); } value = this.data; if ( value.length > 0 ) { predicate = AND(NOT(IN(this.property, value)), predicate); } this.autocompleteView.dao = this.dao.where(predicate); } }, { name: 'onKeyDown', code: function(e) { if ( e.keyCode === 40 /* down */) { this.autocompleteView.nextSelection(); e.preventDefault(); } else if ( e.keyCode === 38 /* up */ ) { this.autocompleteView.prevSelection(); e.preventDefault(); } else if ( e.keyCode === 13 /* RET */ || e.keyCode === 9 /* TAB */ ) { if ( this.autocompleteView.data ) { this.pushValue( this.property.f(this.autocompleteView.data)); e.preventDefault(); } } else if ( e.keyCode === 8 && this.domInputValue.get() === '' ) { this.popValue(); } } }, { name: 'onKeyPress', documentation: 'Prevent shortcut keys from firing on <input> element', code: function(e) { e.stopPropagation(); } }, { name: 'onBlur', code: function(e) { var value = this.domInputValue.get(); if ( value.length > 0 ) { this.pushValue(value); } else { this.domInputValue.set(''); } this.autocompleteView.dao = []; } }, { name: 'onValueChange', code: function() { this.usePlaceholder = this.data.length == 0; } } ] });