diff --git a/source/Ox.UI/js/List/SortList.js b/source/Ox.UI/js/List/SortList.js new file mode 100644 index 00000000..c5b70daa --- /dev/null +++ b/source/Ox.UI/js/List/SortList.js @@ -0,0 +1,64 @@ +'use strict'; + +/*@ +Ox.SortList Sortable List + options Options object + items <[o]|[]> Items ({id: ..., title: ...}) + self Shared private variable + ([options[, self]]) -> SortList Object +@*/ + +Ox.SortList = function(options, self) { + + self = self || {}; + var that = Ox.Element({}, self) + .defaults({ + items: [], + scrollbarVisible: false + }) + .options(options || {}) + .update({ + items: function() { + self.items = getItems(); + self.$list.reloadList(); + that.triggerEvent('sort', { + ids: self.items.map(function(item) { + return item.id; + }) + }); + } + }); + + self.items = getItems(); + + self.$list = Ox.TableList({ + columns: [ + {id: 'title', visible: true} + ], + items: self.items, + max: 1, + scrollbarVisible: self.options.scrollbarVisible, + sort: [{key: 'position', operator: '+'}], + sortable: true, + unique: 'id' + }) + .bindEvent({ + move: function(data) { + self.options.items.sort(function(a, b) { + return data.ids.indexOf(a.id) - data.ids.indexOf(b.id); + }); + that.triggerEvent('sort', data); + } + }); + + function getItems() { + return self.options.items.map(function(item, position) { + return {id: item.id, title: item.title, position: position}; + }); + } + + that.setElement(self.$list); + + return that; + +}; \ No newline at end of file diff --git a/source/Ox.UI/js/Window/SortDialog.js b/source/Ox.UI/js/Window/SortDialog.js new file mode 100644 index 00000000..9357ab4c --- /dev/null +++ b/source/Ox.UI/js/Window/SortDialog.js @@ -0,0 +1,98 @@ +'use strict'; + +/*@ +Ox.SortDialog Dialog with Sortable List + options Options object + defaults <[o]|[]> Items ({id: ..., title: ...}) in default order + height Dialog height in px, or 0 for fit-all + items <[o]|[]> Items ({id: ..., title: ...}) + title Dialog title + width Dialog width in px + self Shared private variable + ([options[, self]]) -> SortDialog Object +@*/ + +Ox.SortDialog = function(options, self) { + + self = self || {}; + var that = Ox.Element({}, self) + .defaults({ + defaults: [], + height: 0, + items: [], + title: '', + width: 256 + }) + .options(options || {}); + + self.fitAll = !self.options.height; + self.hasDefaults = !!self.options.defaults.length; + self.height = self.fitAll + ? self.options.items.length * 16 + : self.options.height + + self.$list = Ox.SortList({ + items: self.options.items, + scrollbarVisible: !self.fitAll + }) + .bindEvent({ + sort: function(data) { + self.hasDefaults && updateDefaultsButton(); + that.triggerEvent('sort', data); + } + }); + + if (self.hasDefaults) { + self.$defaultsButton = Ox.Button({ + title: 'Restore Defaults' + }) + .bindEvent({ + click: function() { + self.options.items = Ox.clone(self.options.defaults); + self.$list.options({items: self.options.items}); + } + }); + } + + self.$doneButton = Ox.Button({ + title: 'Done' + }) + .bindEvent({ + click: function() { + self.$dialog.close(); + } + }); + + self.$dialog = Ox.Dialog({ + buttons: self.hasDefaults + ? [self.$defaultsButton, {}, self.$doneButton] + : [self.$doneButton], + content: self.$list, + fixedSize: true, + height: self.height, + removeOnClose: true, + title: self.options.title, + width: self.options.width + }); + + self.hasDefaults && updateDefaultsButton(); + + that.setElement(self.$dialog); + + function updateDefaultsButton() { + self.$defaultsButton.options({ + disabled: Ox.isEqual(self.options.items, self.options.defaults) + }); + } + + that.close = function() { + self.$dialog.close(); + }; + + that.open = function() { + self.$dialog.open(); + }; + + return that; + +}; \ No newline at end of file