// vim: et:ts=4:sw=4:sts=4:ft=js /*@ Ox.ListMap ListMap Object () -> ListMap Object (options) -> ListMap Object (options, self) -> ListMap Object options Options object addPlace height labels places selected width self shared private variable @*/ Ox.ListMap = function(options, self) { var self = self || {}, that = Ox.Element({}, self) .defaults({ addPlace: null, height: 256, labels: false, places: null, selected: [], width: 256 }) .addClass('OxListMap') .options(options || {}) .css({ width: self.options.width + 'px', height: self.options.height + 'px' }); self.columns = [ { addable: false, // fixme: implement id: 'id', unique: true, visible: false }, { format: function(value) { return $('') .attr({ // fixme: not the right place to do this src: Ox.PATH + 'Ox.Geo/png/icons/16/' + (value || 'NTHH') + '.png' }) .css({ width: '14px', height: '14px', marginLeft: '-3px', marginTop: 0 }); /* .css({ width: '21px', height: '14px' }) .load(function() { var $this = $(this); Ox.print($this.width() / $this.height()) $this.css({ width: Math.round(14 * $this.width() / $this.height()) + 'px', height: '14px', padding: '1px 0 0 1px' }); }); */ }, id: 'countryCode', resizable: false, // fixme: implement title: '', visible: true, width: 16 }, { editable: true, id: 'name', operator: '+', removable: false, title: 'Name', visible: true, width: 144 }, { editable: false, format: function(value) { return value.join('; '); }, id: 'alternativeNames', removable: false, operator: '+', title: 'Alternative Names', visible: true, width: 144 }, { editable: true, id: 'geoname', removable: false, operator: '+', sort: function(v) { return v.split(', ').reverse().join(', ') }, title: 'Geoname', visible: true, width: 192 }, { align: 'right', format: {type: 'area', args: [0]}, id: 'area', operator: '-', title: 'Area', visible: true, width: 128 }, { align: 'right', format: toFixed, id: 'lat', operator: '+', title: 'Latitude', visible: true, width: 96 }, { align: 'right', format: toFixed, id: 'lng', operator: '+', title: 'Longitude', visible: true, width: 96 }, { align: 'right', format: toFixed, id: 'south', operator: '+', title: 'South', visible: false, width: 96 }, { align: 'right', id: 'west', operator: '+', title: 'West', visible: false, width: 96 }, { align: 'right', format: toFixed, id: 'north', operator: '+', title: 'North', visible: false, width: 96 }, { align: 'right', format: toFixed, id: 'east', operator: '+', title: 'East', visible: false, width: 96 }, { id: 'user', operator: '+', title: 'User', visible: false, width: 96 }, { format: 'date', id: 'created', operator: '-', title: 'Date Created', visible: false, width: 96, }, { format: 'date', id: 'modified', operator: '-', title: 'Date Modified', visible: false, width: 96, }, { align: 'right', id: 'matches', operator: '-', title: 'Matches', visible: false, width: 96, } ]; self.$listToolbar = Ox.Bar({ size: 24 }); self.$findElement = Ox.FormElementGroup({ elements: [ self.$findSelect = Ox.Select({ items: [ {id: 'all', title: 'Find: All'}, {id: 'name', title: 'Find: Name'}, {id: 'geoname', title: 'Find: Geoname'}, {id: 'country', title: 'Find: Country'} ], overlap: 'right', width: 128 }), self.$findInput = Ox.Input({ clear: true, width: 192 }) ] }) .css({float: 'right', margin: '4px'}) .appendTo(self.$listToolbar) self.$list = Ox.TextList({ columns: self.columns, columnsRemovable: true, columnsVisible: true, items: Ox.clone(self.options.places), pageLength: 100, scrollbarVisible: true, sort: [ {key: 'name', operator: '+'} ] }) .bindEvent({ 'delete': removeItem, init: initList, load: function() { that.triggerEvent('loadlist'); }, open: openItem, select: selectItem }); self.$listStatusbar = Ox.Bar({ size: 16 }); self.$status = Ox.Element() .css({paddingTop: '2px', margin: 'auto', fontSize: '9px', textAlign: 'center'}) .html(self.options.places.length + ' Place' + (self.options.places.length == 1 ? '' : 's')) .appendTo(self.$listStatusbar); self.$placeTitlebar = Ox.Bar({ size: 24 }); self.$placeTitle = $('
') .hide() .appendTo(self.$placeTitlebar.$element) self.$placeTitleFlag = $('') .addClass('OxFlag') .attr({ src: Ox.PATH + 'Ox.Geo/png/icons/16/NTHH.png' }) .css({float: 'left', margin: '4px 0 0 4px'}) .appendTo(self.$placeTitle); self.$placeTitleName = Ox.Label({ title: '', width: 228 }) .css({float: 'left', margin: '4px'}) .appendTo(self.$placeTitle); self.$placeFormItems = Ox.merge([ Ox.Input({ id: 'name', label: 'Name', labelWidth: 64, width: 240 }).bindEvent({ change: function(data) { Ox.getObjectById(self.options.places, self.selectedPlace).name = data.value; self.$list.value(self.selectedPlace, 'name', data.value); self.$map.value(self.selectedPlace, 'name', data.value); } }), Ox.Input({ id: 'geoname', label: 'Geoname', labelWidth: 64, width: 240 }).bindEvent({ change: function(data) { Ox.getObjectById(self.options.places, self.selectedPlace).geoname = data.value; self.$list.value(self.selectedPlace, 'geoname', data.value); self.$map.value(self.selectedPlace, 'geoname', data.value); self.$placeTitleName.options({ title: data.value }); } }), Ox.ArrayInput({ id: 'alternativeNames', label: 'Alternative Names', max: 10, //sort: true, values: [], width: 240 }).bindEvent({ change: function(data) { Ox.print('CHANGE........', data) } }), ], ['South', 'West', 'North', 'East', 'Latitude', 'Longitude'].map(function(v) { var id = ( v == 'Latitude' ? 'lat' : v == 'Longitude' ? 'lng' : v ).toLowerCase(), max = ['Latitude', 'South', 'North'].indexOf(v) > -1 ? Ox.MAX_LATITUDE : 180; return Ox.Input({ decimals: 8, disabled: ['Latitude', 'Longitude'].indexOf(v) > -1, id: id, label: v, labelWidth: 80, min: -max, max: max, type: 'float', width: 240 }).bindEvent({ focus: function() { Ox.print('---- FOCUS ----') } }); }), [ self.$areaInput = Ox.Input({ disabled: true, id: 'area', label: 'Area', labelWidth: 80, textAlign: 'right', width: 240 }) ]); self.$placeForm = Ox.Form({ items: self.$placeFormItems, width: 240 }) .css({margin: '8px'}) .hide(); self.$placeStatusbar = Ox.Bar({ size: 24 }); self.$placeButton = Ox.Button({ title: 'New Place', width: 96 }) .css({float: 'left', margin: '4px 2px 4px 4px'}) .bindEvent({ click: function() { var title = self.$placeButton.options('title'); if (title == 'New Place') { self.$map.newPlace(); self.$placeButton.options({title: 'Add Place'}) } else if (title == 'Add Place') { var place = self.$placeForm.values(); place.id = self.selectedPlace.substr(1); // fixme: safe? self.options.places.push(place); self.$map.addPlace(place); self.$list.options({items: Ox.clone(self.options.places)}); self.$list.options({selected: [place.id]}); //self.$list.addItem(place); self.$placeButton.options({title: 'Remove Place'}) } else if (title == 'Remove Place') { var index = Ox.getPositionById(self.options.places, self.selectedPlace); self.options.places.splice(index, 1); self.$list.options({items: Ox.clone(self.options.places)}); self.$map.removePlace(); self.$placeButton.options({title: 'Add Place'}); } Ox.print('PLACES.LENGTH', self.options.places.length) Ox.print('ITEMS.LENGTH', self.$list.options('items').length) } }) .appendTo(self.$placeStatusbar); self.$revertButton = Ox.Button({ title: 'Revert', width: 96 }) .css({float: 'right', margin: '4px 4px 4px 2px'}) .hide() .appendTo(self.$placeStatusbar); /* self.mapResize = [ Math.round(self.options.width * 0.25), Math.round(self.options.width * 0.5), Math.round(self.options.width * 0.75) ]; */ if (Ox.isArray(self.options.places)) { init(self.options.places) } else { self.options.places({}, function(result) { Ox.print('$$$$', result.data.items) self.options.places({ keys: self.columns.map(function(column) { return column.id }), range: [0, result.data.items] }, function(result) { Ox.print('DATA', result) init(result.data.items); }); }); } function init(places) { //Ox.print('PLACES', places) self.$map = Ox.Map({ clickable: true, editable: true, findPlaceholder: 'Find on Map', height: self.options.height, places: places, //statusbar: true, toolbar: true, width: self.options.width - 514,//self.mapResize[1], zoombar: true }) .bindEvent({ addplace: function(event, data) { that.triggerEvent('addplace', data); }, changeplace: function(event, data) { self.$placeForm.values(Ox.map(data, function(val, key) { // fixme: no size key anymore return key == 'size' ? Ox.formatArea(val) : val; })).show(); }, geocode: function(event, data) { that.triggerEvent('geocode', data); }, resize: function() { self.$map.resizeMap(); // fixme: don't need event }, selectplace: selectPlace }); that.$element.replaceWith( that.$element = Ox.SplitPanel({ elements: [ { element: Ox.SplitPanel({ elements: [ { element: self.$listToolbar, size: 24 }, { element: self.$list }, { element: self.$listStatusbar, size: 16 } ], orientation: 'vertical' }), resizable: true, resize: [256, 384, 512], size: 256 }, { element: self.$map, }, { collapsible: true, element: Ox.SplitPanel({ elements: [ { element: self.$placeTitlebar, size: 24 }, { element: self.$placeForm }, { element: self.$placeStatusbar, size: 24 } ], orientation: 'vertical' }) .bindEvent({ resize: function(foo, size) { self.$placeTitleName.options({width: size - 28}); // fixme: pass width through form self.$placeFormItems.forEach(function($item) { $item.options({width: size - 16}); }); } }), resizable: true, resize: [204, 256, 384], size: 256 } ], orientation: 'horizontal' }).$element ); } function initList(event, data) { self.$status.html(data.items + ' place' + (data.items == 1 ? '' : 's')) } function openItem(event, data) { selectItem(event, data); self.$map.zoomToPlace(data.ids[0]); } function removeItem(event, data) { var id = data.ids[0]; that.triggerEvent('removeplace', {id: id}); self.$map.removePlace(id); } function selectItem(event, data) { Ox.print('selectItem', data.ids[0]) var id = data.ids.length ? data.ids[0] : null; self.$map.options({selected: id}); id && self.$map.panToPlace(); } function selectPlace(place) { var country = place.id ? Ox.getCountryByGeoname(place.geoname) : '', code = country ? country.code : 'NTHH'; if (place.id) { isResult = place.id[0] == '_'; self.selectedPlace = place.id; place.id[0] != '_' && self.$list.options({ selected: place.id ? [place.id] : [] }); self.$placeTitleFlag.attr({ src: Ox.PATH + 'Ox.Geo/png/icons/16/' + code + '.png' }); self.$placeTitleName.options({title: place.geoname || ''}); self.$placeTitle.show(); Ox.print('>>>>', place) self.$placeForm.values(Ox.map(place, function(val, key) { return key == 'size' ? Ox.formatArea(val) : val; })).show(); self.$placeButton.options({title: isResult ? 'Add Place' : 'Remove Place'}); self.$revertButton.options({disabled: true}).show(); } else { self.selectedPlace = null; self.$placeTitle.hide(); self.$placeForm.hide(); self.$placeButton.options({title: 'New Place'}); self.$revertButton.hide(); } } function toFixed(val) { return Ox.isNumber(val) ? val.toFixed(8) : val; // fixme: why can a string be passed ?? } /*@ setOption setOption @*/ self.setOption = function(key, value) { Ox.print('ONCHANGE') if (key == 'height' || key == 'width') { Ox.print('ONCHANGE...') self.$map.options({ height: self.options.height, width: self.options.width }) } else if (key == 'selected') { self.$list.options({selected: value}); } } /*@ focusList focusList @*/ that.focusList = function() { self.$list.gainFocus(); return that; } /*@ reloadList reloadList @*/ that.reloadList = function() { self.$list.reloadList(); return that; } /*@ resizeMap resizeMap @*/ that.resizeMap = function() { Ox.print('Ox.ListMap.resizeMap()') self.$map.resizeMap(); return that; }; return that; };