'use strict'; Ox.load(['Geo', 'UI'], function() { var items = Ox.COUNTRIES.map(function(country) { return Ox.extend({}, country, { flag: Ox.getFlagByCountryCode(country.code, 256), icon: Ox.getFlagByCountryCode(country.code, 16), region: country.continent + ', ' + country.region }); }), columns = [ { format: function(value) { return $('').attr({src: value}).css({ width: '14px', height: '14px', borderRadius: '2px', margin: '0 0 0 -3px' }) }, id: 'icon', operator: '+', title: 'Flag', titleImage: 'flag', visible: true, width: 16 }, { id: 'code', operator: '+', title: 'Code', unique: true, visible: true, width: 64 }, { id: 'name', operator: '+', removable: false, title: 'Name', visible: true, width: 256 }, { format: function(value) { return value.split(', ')[0]; }, id: 'continent', operator: '+', title: 'Continent', visible: true, width: 96 }, { format: function(value) { return value.split(', ')[1]; }, id: 'region', operator: '+', title: 'Region', visible: true, width: 160 }, { align: 'right', format: function(value) { return Ox.formatArea(value); }, id: 'area', operator: '-', title: 'Area', visible: true, width: 112 }, { format: function(value) { return Ox.formatDegrees(value, 'lat'); }, align: 'right', id: 'lat', operator: '-', title: 'Latitude', visible: true, width: 80 }, { format: function(value) { return Ox.formatDegrees(value, 'lng'); }, align: 'right', id: 'lng', operator: '+', title: 'Longitude', visible: true, width: 80 }, { align: 'right', format: function(value) { return Ox.formatDegrees(value, 'lat'); }, id: 'south', operator: '-', title: 'South', width: 80 }, { align: 'right', format: function(value) { return Ox.formatDegrees(value, 'lat'); }, id: 'north', operator: '-', title: 'North', width: 80 }, { align: 'right', format: function(value) { return Ox.formatDegrees(value, 'lng'); }, id: 'west', operator: '-', title: 'West', width: 80 }, { align: 'right', format: function(value) { return Ox.formatDegrees(value, 'lng'); }, id: 'east', operator: '-', title: 'East', width: 80 }, ], itemSize = 288 + Ox.UI.SCROLLBAR_SIZE, state = { find: '', include: { dependency: false, disputed: false, dissolved: false, exception: false }, selected: [], sort: [{key: 'name', operator: '+'}], view: 'grid' }, query = getQuery(), $toolbar = Ox.Bar({size: 24}).addClass('bar'), $view = Ox.ButtonGroup({ buttons: [ {id: 'grid', title: 'grid'}, {id: 'list', title: 'list'} ], selectable: true, type: 'image', value: state.view }) .bindEvent({change: view}) .appendTo($toolbar), $sort = Ox.Select({ items: [ {id: 'name', title: 'Sort by Name'}, {id: 'code', title: 'Sort by Code'}, {id: 'continent', title: 'Sort by Continent'}, {id: 'region', title: 'Sort by Region'}, {id: 'area', title: 'Sort by Area'}, {id: 'lat', title: 'Sort by Latitude'}, {id: 'lng', title: 'Sort by Longitude'} ], width: 128 }) .bindEvent({change: sort}) [state.view == 'grid' ? 'show' : 'hide']() .appendTo($toolbar), $order = Ox.Button({ title: state.sort[0].operator == '+' ? 'up' : 'down', type: 'image' }) .bindEvent({click: order}) [state.view == 'grid' ? 'show' : 'hide']() .appendTo($toolbar), $find = Ox.Input({ changeOnKeypress: true, clear: true, placeholder: 'Find', width: 192 }) .addClass('right') .bindEvent({change: find}) .appendTo($toolbar), $include = Ox.MenuButton({ items: [ {id: 'dependency', title: 'Include dependencies'}, {id: 'disputed', title: 'Include disputed countries'}, {id: 'dissolved', title: 'Include dissolved countries'}, {id: 'exception', title: 'Include other entities'} ].map(function(item) { return Ox.extend(item, {checked: false}); }), type: 'image' }) .addClass('right') .bindEvent({change: include}) .appendTo($toolbar), $list = { grid: Ox.IconList({ borderRadius: 16, fixedRatio: 1, item: function(data, sort, size) { var key = sort[0].key == 'name' ? 'code' : sort[0].key, column = Ox.getObjectById(columns, key), info = (column.format || Ox.identity)(data[key]); return { height: size, id: data.id, info: info, title: data.name, url: data.flag, width: size }; }, items: items, keys: ['flag', 'name'], max: 1, pageLength: 1000, query: query, selected: state.selected, size: 128, sort: Ox.clone(state.sort), unique: 'code' }) .bindEvent({ init: init, select: select }), list: Ox.TextList({ columns: columns, columnsMovable: true, columnsRemovable: true, columnsVisible: true, items: items, max: 1, pageLength: 1000, query: query, scrollbarVisible: true, sort: Ox.clone(state.sort) }) .bindEvent({ init: init, select: select }) }, $statusbar = Ox.Bar({size: 16}), $status = Ox.Element().addClass('status').appendTo($statusbar), $listPanel = Ox.SplitPanel({ elements: [ {element: $toolbar, size: 24}, {element: $list[state.view]}, {element: $statusbar, size: 16} ], orientation: 'vertical' }), $titlebar = Ox.Bar({size: 24}).addClass('bar'), $title = Ox.Label({ width: itemSize - 28 }) .hide() .appendTo($titlebar), $deselect = Ox.Button({ title: 'close', type: 'image' }) .bindEvent({ click: function() { $list[state.view].options({selected: []}); select({ids: []}); } }) .hide() .appendTo($titlebar), $item = Ox.Element().addClass('item'), $itemPanel = Ox.SplitPanel({ elements: [ {element: $titlebar, size: 24}, {element: $item}, {element: Ox.Bar({size: 16}), size: 16} ], orientation: 'vertical' }), $mainPanel = Ox.SplitPanel({ elements: [ {element: $listPanel}, {element: $itemPanel, size: itemSize} ], orientation: 'horizontal' }) .appendTo(Ox.$body); function find() { state.find = $find.options('value'); query = getQuery(); $status.html('Loading...'); $list[state.view].options({query: query}); } function getQuery() { var query = { conditions: [{key: 'name', operator: '=', value: state.find}], operator: '&' }; Ox.forEach(state.include, function(value, key) { !value && query.conditions.push( {key: key, operator: '=', value: void 0} ); }); return query; } function include(data) { state.include[data.id] = data.checked; find(); } function init(data) { $status.html( (data.items || 'No') + ' countr' + (data.items == 1 ? 'y' : 'ies') ); } function order(data) { state.sort[0].operator = state.sort[0].operator == '+' ? '-' : '+'; $order.options({title: state.sort[0].operator == '+' ? 'up' : 'down'}); $list[state.view].options({sort: Ox.clone(state.sort)}); } function select(data) { Ox.print('SELECT', data) var id = data.ids[0]; if (id) { state.selected = [id]; data = $list[state.view].value(id); Ox.print(state.view, 'DATA:', data, id) $title.options({title: data.name}).show(); $deselect.show(); showItem(); } else { state.selected = []; $title.hide(); $deselect.hide(); $item.empty(); } } function showItem() { var code = state.selected[0]; $item.empty(); if (state.view == 'grid') { Ox.TreeList({ data: Ox.getCountryByCode(code), scrollbarVisible: true, width: itemSize }) .appendTo($item); } else { Ox.Element('') .addClass('flag') .attr({src: Ox.getFlagByCountryCode(code, 256)}) .appendTo($item); } } function sort(data) { state.sort = [{ key: data.value, operator: Ox.getObjectById(columns, data.value).operator }]; $order.options({title: state.sort[0].operator == '+' ? 'up' : 'down'}); $list[state.view].options({sort: state.sort}); } function view(data) { state.view = data.value; $sort[state.view == 'grid' ? 'show' : 'hide'](); $order[state.view == 'grid' ? 'show' : 'hide'](); $listPanel.replaceElement(1, $list[state.view].options({ selected: state.selected })); } });