Foo bar baz.
foo: // this is some code
blockquote
/* */ 'use strict'; /* We have to load the Geo module to get Ox.COUNTRIES */ Ox.load({UI: {}, Geo: {}}, function() { var countries = Ox.COUNTRIES.filter(function(country) { /* We filter out some types of countries that we're not interested in. */ return !country.disputed && !country.dissolved && !country.exception && country.code.length == 2 }).map(function(country) { /* For independent countries, the dependency property is undefined. We want an empty array though, so that the type of this column gets correctly detected as array. */ country.dependency = country.dependency || []; /* When sorting the list by region, we want the regions to be grouped by continent. To get this sort order, we set the value for region to 'Continent, Region'. Later, a format function for the region column will remove the continent part again. */ country.region = country.continent + ', ' + country.region; return country; }), api = Ox.api(countries, {sort: ['+name'], unique: 'code'}), $list = Ox.TextList({ columns: [ { /* The format function of a column has a second argument which contains the values of all columns. This allows us to format a value dependent on other values. In this case, we want to display a flag, and while our items don't have a flag property, the Geo module allows us to derive it from the name property. The flag image needs a tooltip (which is why we can't use an $('') here), and gets some CSS adjustments. */ format: function(value, data) { return Ox.Element({ element: '', tooltip: '' }) .attr({ src: Ox.getFlagByGeoname(data.name, 16) }) .css({ width: '14px', height: '14px', marginLeft: '-3px' }) }, /* As the actual key for the column, we use the country code, not the country name, since we still want to display the name in its own column. */ id: 'flagURL', operator: '+', removable: false, /* We want the column title to be a flag symbol, so we specify this as the titleImage. We can pick anything from the collection of symbols that comes with Ox.UI. The column still needs a textual title that will be displayed in the menu that allows to show or hide specific columns. */ title: 'Flag', titleImage: 'flag', /* The country code is the unique key of our country table. In consequence, whenever the list fires a select event, it will reference this value as the item's id. */ unique: true, visible: true, width: 16 }, { id: 'code', operator: '+', title: 'Code', unique: true, visible: true, width: 64 }, { id: 'name', /* The operator indicates that we want the default sort order of this column to be ascending. */ operator: '+', /* As it wouldn't make much sense to display the list without the name column, we make it non-removable. */ removable: false, title: 'Name', visible: true, width: 256 }, { id: 'continent', operator: '+', title: 'Continent', visible: true, width: 96 }, { /* To tweak the sort order for this column, we had changed the value for region to 'Continent, Region'. The format function now reverts that change. */ format: function(value) { return value.split(', ')[1]; }, id: 'region', operator: '+', title: 'Region', visible: true, width: 160 }, { /* As the value is a number, it should be right-aligned. */ align: 'right', /* To get from square meters to something human-readable, we use one of the built-in format functions. */ 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 }, /* For the next four columns, which seem less important, we omit the 'visible' option, which defaults to false. They can still be made visible, they're just not visible by default. */ { 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 }, { /* The dependency property is an array of country names, for each of which we want to display a flag. So we use a similar constuction as above, and wrap the images in a $('') element. */ format: function(value) { var ret = ''; if (value) { var ret = $('').css({marginLeft: '-4px'}); value.forEach(function(country) { Ox.Element({ element: '', tooltip: country }) .attr({ src: Ox.getFlagByGeoname(country, 16) }) .css({ width: '14px', height: '14px', margin: '1px' }) .appendTo(ret); }); } return ret; }, id: 'dependency', operator: '+', title: 'Dependency of', visible: true, width: 112 } ], /* This allows the user to move the columns around */ columnsMovable: true, /* This enables the UI to show or hide specific columns */ columnsRemovable: true, /* This makes sure the column titles get displayed */ columnsVisible: true, items: api, /* Pagination is useful when a list is so big that only parts of it can be requested or displayed. Since this is not the case here, we set the page length to a sufficiently large number. */ pageLength: Ox.COUNTRIES.length, scrollbarVisible: true, /* We have to specify the default sort order. */ sort: [{key: 'name', operator: '+'}] }) .bindEvent({ /* The init event of a list fires when the items function has returned the total number of items. If we're dealing with a remote API, a complex query, a huge dataset or a range request for paginated results according to a non-trivial sort order, this may happen quite a bit before any items are returned. Here, we simply display the number of items in the status bar. */ init: function(data) { $status.html( (data.items || 'No') + ' countr' + (data.items == 1 ? 'y' : 'ies') ); } }), /* We want the user to be able to pick if dependent countries are included in the list or not. So we add a checkbox, and bind the find function to its change event. */ $include = Ox.Checkbox({ title: 'Include Dependencies', value: true }) .css({float: 'left', margin: '4px'}) .bindEvent({ change: find }), /* We want a search field with find-as-you-type, so we use an input element and set its changeOnKeypress option to true. */ $find = Ox.Input({ changeOnKeypress: true, placeholder: 'Find', width: 192 }) .css({float: 'right', margin: '4px'}) .bindEvent({ change: find }), /* ... */ $toolbar = Ox.Bar({size: 24}).append($include).append($find), $status = $('').css({ marginTop: '2px', fontSize: '9px', textAlign: 'center' }), $statusbar = Ox.Bar({size: 16}).append($status), $panel = Ox.SplitPanel({ elements: [ {element: $toolbar, size: 24}, {element: $list}, {element: $statusbar, size: 16} ], orientation: 'vertical' }) .appendTo(Ox.$body); function find() { /* The find function is bound to the change events of the $include checkbox and the $find input field. In both cases, the value will be passed, but since we need both values, we disregard it and query both elements for their value. If the $include box is not checked, we add a second condition that matches only independent countries. */ var conditions = [ {key: 'name', operator: '=', value: $find.options('value')}, ]; !$include.options('value') && conditions.push( {key: 'dependency', operator: '=', value: void 0} ); /* ... */ api({ keys: [], query: {conditions: conditions, operator: '&'} }, function(result) { $list.options({ items: Ox.api( result.data.items, {sort: '+name', unique: 'code'} ) }); }); } });