UNPKG

foam-framework

Version:
205 lines (186 loc) 5.03 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: 'MultiLineStringArrayView', extends: 'foam.ui.View', properties: [ { model_: 'StringProperty', name: 'name' }, { model_: 'StringProperty', name: 'type', defaultValue: 'text' }, { model_: 'IntProperty', name: 'displayWidth', defaultValue: 30 }, { model_: 'BooleanProperty', name: 'onKeyMode', defaultValue: true }, { model_: 'BooleanProperty', name: 'autocomplete', defaultValue: true }, { name: 'data' }, 'autocompleter', { model_: 'ArrayProperty', subType: 'foam.ui.MultiLineStringArrayView.RowView', name: 'inputs' } ], models: [ { model_: 'Model', name: 'RowView', extends: 'foam.ui.View', properties: [ 'field', { name: 'tagName', defaultValue: 'div' } ], methods: { toInnerHTML: function() { this.children = [this.field]; return this.field.toHTML() + '<input type="button" id="' + this.on('click', (function(){ this.publish('remove'); }).bind(this)) + '" class="multiLineStringRemove" value="X">'; } } } ], methods: { toHTML: function() { var toolbar = ToolbarView.create({ data: this }); toolbar.addActions([this.model_.ADD]); this.children = [toolbar]; return '<div id="' + this.id + '"><div></div>' + toolbar.toHTML() + '</div>'; }, initHTML: function() { this.SUPER(); this.data$.addListener(this.update); this.update(); }, row: function() { // TODO: Find a better way to copy relevant values as this is unsustainable. var view = this.model_.RowView.create({ field: this.X.TextFieldView.create({ name: this.name, type: this.type, displayWidth: this.displayWidth, onKeyMode: this.onKeyMode, autocomplete: this.autocomplete, autocompleter: this.autocompleter }, this.Y) }); return view; }, setValue: function(value) { this.value = value; } }, listeners: [ { name: 'update', code: function() { if ( ! this.$ ) return; var inputs = this.inputs; var inputElement = this.$.firstElementChild; var newViews = []; var data = this.data; // Add/remove rows as necessary. if ( inputs.length > data.length ) { for ( var i = data.length; i < inputs.length; i++ ) { inputs[i].$.remove(); this.removeChild(inputs[i]); } inputs.length = data.length; } else { var extra = ""; for ( i = inputs.length; i < data.length; i++ ) { var view = this.row(); // TODO: This seems ridiculous. this.addChild(view); newViews.push(view); inputs.push(view); view.subscribe('remove', this.onRemove); view.field.data$.addListener(this.onInput); extra += view.toHTML(); } if ( extra ) inputElement.insertAdjacentHTML('beforeend', extra); } // Only update the value for a row if it does not match. for ( i = 0; i < data.length; i++ ) { if ( inputs[i].field.data !== data[i] ) inputs[i].field.data = data[i]; } this.inputs = inputs; for ( i = 0; i < newViews.length; i++ ) newViews[i].initHTML(); } }, { name: 'onRemove', code: function(src) { var inputs = this.inputs; for ( var i = 0; i < inputs.length; i++ ) { if ( inputs[i] === src ) { this.data = this.data.slice(0, i).concat(this.data.slice(i+1)); break; } } } }, { name: 'onInput', code: function(e) { if ( ! this.$ ) return; var inputs = this.inputs; var newdata = []; for ( var i = 0; i < inputs.length; i++ ) { newdata.push(inputs[i].field.data); } this.data = newdata; } } ], actions: [ { name: 'add', label: 'Add', code: function() { this.data = this.data.pushF(''); } } ] });