diff --git a/examples/countries/css/example.css b/examples/countries/css/example.css new file mode 100644 index 00000000..a66d0161 --- /dev/null +++ b/examples/countries/css/example.css @@ -0,0 +1,24 @@ +.bar > .OxElement { + float: left; + margin: 4px 2px; +} +.bar > .OxElement.right { + float: right; +} +.bar > .OxElement:first-child { + margin-left: 4px; +} +.bar > .OxElement:last-child { + margin-right: 4px; +} +.flag { + border-radius: 32px; +} +.item { + padding: 16px; +} +.status { + margin-top: 3px; + font-size: 9px; + text-align: center; +} \ No newline at end of file diff --git a/examples/countries/index.html b/examples/countries/index.html new file mode 100644 index 00000000..bc87b115 --- /dev/null +++ b/examples/countries/index.html @@ -0,0 +1,13 @@ + + + + Countries + + + + + + + + + \ No newline at end of file diff --git a/examples/countries/js/example.js b/examples/countries/js/example.js new file mode 100644 index 00000000..13569f32 --- /dev/null +++ b/examples/countries/js/example.js @@ -0,0 +1,419 @@ +'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 + })); + } + +}); \ No newline at end of file