'use strict'; /*@ Ox.ArrayInput Array input @*/ Ox.ArrayInput = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ label: '', max: 0, sort: false, // fixme: this should probably be removed value: [], width: 256 }) .options(options || {}); if (self.options.value.length == 0) { self.options.value = ['']; } if (self.options.label) { self.$label = Ox.Label({ title: self.options.label, width: self.options.width }) .appendTo(that); } self.$element = []; self.$input = []; self.$removeButton = []; self.$addButton = []; self.options.value.forEach(function(value, i) { addInput(i, value); }); function addInput(index, value, focus) { Ox.Log('Form', 'add', index) self.$element.splice(index, 0, Ox.Element() .css({ height: '16px', marginTop: self.options.label || index > 0 ? '8px' : 0 }) .data({index: index})); if (index == 0) { self.$element[index].appendTo(that); } else { self.$element[index].insertAfter(self.$element[index - 1]); } self.$input.splice(index, 0, Ox.Input({ value: value, width: self.options.width - 48 }) .css({float: 'left'}) .bindEvent({ change: function(data) { self.options.sort && data.value !== '' && sortInputs(); self.options.value = that.value(); that.triggerEvent('change', { value: self.options.value }); } }) .appendTo(self.$element[index])); focus && self.$input[index].focusInput(); self.$removeButton.splice(index, 0, Ox.Button({ title: self.$input.length == 1 ? 'close' : 'remove', type: 'image' }) .css({float: 'left', marginLeft: '8px'}) .bind({ click: function() { var index = $(this).parent().data('index'); if (self.$input[index].value() !== '') { self.$input[index].options({value: ''}); self.options.value = that.value(); that.triggerEvent('change', { value: self.options.value }); } if (self.$input.length == 1) { self.$input[0].focusInput(); } else { removeInput(index); } } }) .appendTo(self.$element[index])); self.$addButton.splice(index, 0, Ox.Button({ disabled: index == self.options.max - 1, title: 'add', type: 'image' }) .css({float: 'left', marginLeft: '8px'}) .bind({ click: function() { var index = $(this).parent().data('index'); addInput(index + 1, '', true); } }) .appendTo(self.$element[index])); updateInputs(); } function removeInput(index) { Ox.Log('Form', 'remove', index); [ 'input', 'removeButton', 'addButton', 'element' ].forEach(function(element) { var key = '$' + element; self[key][index].remove(); self[key].splice(index, 1); }); updateInputs(); } function setWidths() { self.$label && self.$label.options({width: self.options.width}) self.$element.forEach(function($element, i) { $element.css({width: self.options.width + 'px'}); self.$input[i].options({width: self.options.width - 48}); }); } function sortInputs() { Ox.sort(self.$element, function($element) { return self.$input[$element.data('index')].value(); }).forEach(function($element) { $element.detach(); }); self.$element.forEach(function($element, i) { $element.data({index: i}).appendTo(that); }); } function updateInputs() { self.$element.forEach(function($element, i) { $element.data({index: i}); self.$removeButton[i].options({ title: self.$element.length == 1 ? 'close' : 'remove', }); self.$addButton[i].options({ disabled: self.$element.length == self.options.max }); }); } self.setOption = function(key, value) { if (key == 'value') { if (self.options.value.length == 0) { self.options.value = ['']; } while (self.$input.length) { removeInput(0); } self.options.value.forEach(function(value, i) { addInput(i, value); }); } else if (key == 'width') { setWidths(); } } that.setErrors = function(values) { self.$input.forEach(function($input) { values.indexOf($input.value()) > -1 && $input.addClass('OxError'); }); }; // fixme: can't we generally use options.value for this? that.value = function() { if (arguments.length == 0) { return Ox.map(self.$input, function($input) { var value = $input.value(); return value === '' ? null : value; }); } }; return that; };