/*@ 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(i, value, focus) { Ox.print('add', i) self.$element.splice(i, 0, Ox.Element() .css({height: '16px', marginTop: self.options.label || i > 0 ? '8px' : 0}) .data({index: i})); if (i == 0) { self.$element[i].appendTo(that); } else { Ox.print(i, self.$element) self.$element[i].insertAfter(self.$element[i - 1]); } self.$input.splice(i, 0, Ox.Input({ value: value, width: self.options.width - 48 }) .css({float: 'left'}) .bindEvent({ change: function(data) { self.options.sort && data.value !== '' && sortInputs(); that.triggerEvent('change', {value: that.value()}); } }) .appendTo(self.$element[i])); focus && self.$input[i].focusInput(); self.$removeButton.splice(i, 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: ''}); that.triggerEvent('change', {value: that.value()}); } if (self.$input.length == 1) { self.$input[0].focusInput(); } else { removeInput(index); } } }) .appendTo(self.$element[i])); self.$addButton.splice(i, 0, Ox.Button({ disabled: i == self.options.max - 1, title: 'add', type: 'image' }) .css({float: 'left', marginLeft: '8px'}) .bind({ click: function() { addInput($(this).parent().data('index') + 1, '', true); } }) .appendTo(self.$element[i])); self.$input.length > 1 && self.$removeButton[0].options({title: 'remove'}); self.$input.length == self.options.max && self.$addButton.forEach(function($button) { $button.options({disabled: true}); }); updateIndices(); } function removeInput(i) { Ox.print('remove', i); ['input', 'removeButton', 'addButton', 'element'].forEach(function(element) { var key = '$' + element; self[key][i].removeElement(); self[key].splice(i, 1); }); self.$input.length == 1 && self.$removeButton[0].options({title: 'close'}); self.$input.length == self.options.max - 1 && self.$addButton.forEach(function($button) { $button.options({disabled: false}); }); updateIndices(); } 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 updateIndices() { self.$element.forEach(function($element, i) { Ox.print(i, $element) $element.data({index: i}); }); /* self.$input.forEach(function($input, i) { $input.options({value: i}); }); */ } 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; };