From d2a6374551d89e94df3014132b740f1f9fb7bc0e Mon Sep 17 00:00:00 2001 From: sanj Date: Wed, 19 Jan 2011 13:35:08 +0530 Subject: [PATCH] restructured js/itf folder to separate files --- itf/api/views.py | 8 +- itf/bestpractices/models.py | 15 + itf/static/js/itf/app.js | 41 + itf/static/js/itf/construct.js | 563 ++++++++++++ itf/static/js/itf/forms.js | 456 ++++++++++ itf/static/js/itf/itf.js | 1487 -------------------------------- itf/static/js/itf/query.js | 137 +++ itf/static/js/itf/widgets.js | 305 +++++++ itf/templates/index.html | 5 + 9 files changed, 1529 insertions(+), 1488 deletions(-) create mode 100644 itf/static/js/itf/app.js create mode 100644 itf/static/js/itf/construct.js create mode 100644 itf/static/js/itf/forms.js create mode 100644 itf/static/js/itf/query.js create mode 100644 itf/static/js/itf/widgets.js diff --git a/itf/api/views.py b/itf/api/views.py index 3f40ffe..30c75ec 100644 --- a/itf/api/views.py +++ b/itf/api/views.py @@ -55,7 +55,13 @@ def api_api(request): actions = globals().keys() actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions)) actions.sort() - return render_to_json_response(json_response({'actions': actions})) + ret = {} + #FIXME: set cache to False for login, logout, etc. + for a in actions: + ret[a] = { + 'cache': True + } + return render_to_json_response(json_response({'actions': ret})) def api_apidoc(request): ''' diff --git a/itf/bestpractices/models.py b/itf/bestpractices/models.py index 3bbcecf..28844e4 100644 --- a/itf/bestpractices/models.py +++ b/itf/bestpractices/models.py @@ -7,6 +7,7 @@ class BestPractice(ItfModel): title = models.CharField(max_length=512) story = models.TextField() guideline = models.TextField(blank=True) + guidelines = models.ManyToManyField("Guideline", null=True, blank=True) law = models.TextField(blank=True) theatre = models.TextField(blank=True, help_text="Spotlight on Theatre text") quick_howto = models.TextField(blank=True) @@ -75,3 +76,17 @@ class BestPracticeImage(models.Model): def __unicode__(self): return self.caption +class Guideline(models.Model): + title = models.CharField(max_length=512) + text = models.TextField() + + def __unicode__(self): + return self.title + + +class Glossary(models.Model): + term = models.CharField(max_length=256) + definition = models.TextField() + + def __unicode__(self): + return self.term diff --git a/itf/static/js/itf/app.js b/itf/static/js/itf/app.js new file mode 100644 index 0000000..1bacaea --- /dev/null +++ b/itf/static/js/itf/app.js @@ -0,0 +1,41 @@ +var app = new Ox.App({ + apiURL: '/api/', + init: 'hello', + config: 'site.json' //FIXME: shouldn't need this, get data with 'hello' or 'init'. +}); + +/* +app.api.hell = function() { + setTimeout("app.api.hello()", 1000); +} +*/ +app.launch(function(data) { + Ox.theme("classic"); + Ox.print(data); + + app.$body = $('body'); + app.$document = $(document); + app.$window = $(window); +/* + app.user = data.user; + app.config = data.config; +*/ + +/* + //FIXME: should this be a nested structure as their representation on the page? + app.constructors = ['wrapper', 'headerPanel', 'mainPanel', 'leftPanel', 'cityPicker', 'calendarBox', 'currentEventsList', 'middlePanel', 'middleTopPanel', 'newsfeedBox', 'aboutBox', 'itfBox', 'middleBottomPanel', 'erangBox', 'scriptArchiveBox', 'bestPracticesBox', 'biblioBox', 'offersNeedsBox', 'surveysBox', 'rightPanel', 'searchBox', 'loginBox', 'previewBox', 'footerPanel'] +*/ + + app.$ui = {}; +/* + Ox.each(app.constructors, function(i, v) { + app.$ui[v] = app.construct[v](); + }); +*/ + var wrapper = app.construct.wrapper(); + app.$body.css({'opacity': 0}); + wrapper.appendTo(app.$body); + app.$body.animate({ + 'opacity': 1 + }, 2000); +}); diff --git a/itf/static/js/itf/construct.js b/itf/static/js/itf/construct.js new file mode 100644 index 0000000..5143b10 --- /dev/null +++ b/itf/static/js/itf/construct.js @@ -0,0 +1,563 @@ + +app.construct = { +/* +Structure: + wrapper + headerPanel + homeBox + searchBox + mainPanel + leftPanel + cityPicker + calendarBox + currentEventsList + middlePanel + middleTopPanel + newsfeedBox + aboutBox + itfBox + middleMiddlePanel + erangBox + scriptArchiveBox + bestPracticesBox + middleBottomPanel + biblioBox + offersNeedsBox + surveysBox + rightPanel + loginBox + previewBox + footerPanel +*/ + + + 'wrapper': function() { + var id = 'wrapper'; + // Constructs overall wrapper for the page, and should be appended to $(body) + return app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'vertical', + elements: [ + { + element: app.construct.headerPanel(), + size: 40 + }, + { + element: app.construct.mainPanel(), + }, + { + element: app.construct.footerPanel(), + size: 40 + } + ] + }); + }, + +/* +BEGIN headerPanel +*/ + 'headerPanel': function() { + var id = 'headerPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + orientation: 'horizontal', + id: id, + elements: [ + { + element: app.construct.homeBox(), + }, + { + element: app.construct.searchBox(), + size: 128 + + } + ] + }); + return p; + }, + + 'homeBox': function() { + var id = 'homeBox'; + var c = app.$ui.homeBox = new Ox.Element({ + id: id + }); + c.html("This is the header - maybe load from a template?"); + return c; + }, + + 'searchBox': function() { + var id = 'searchBox'; + var i = app.$ui.searchBox = new Ox.Input({ + 'id': id, + 'placeholder': 'Search' + }); + i.bindEvent("submit", function(val) { + Ox.print("Should be doing a search"); + }); + i.css({ + 'marginRight': '15px', + 'marginTop': '6px' + }); + return i; + }, + +/* +END headerPanel +*/ + +/* +BEGIN mainPanel +*/ + + 'mainPanel': function() { + var id = 'mainPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'horizontal', + elements: [ + { + element: app.construct.leftPanel(), + size: 256, + resizable: true, + resize: [0, 128, 256, 384] + }, + { + element: app.construct.middlePanel() +// resizable: true + }, + { + element: app.construct.rightPanel(), + size: 256, + resizable: true, + resize: [0, 128, 256, 384] + } + ] + }); + return p; + }, + + /* + BEGIN leftPanel + */ + 'leftPanel': function() { + var id = 'leftPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'vertical', + elements: [ + { + element: app.construct.cityPicker(), + size: 40 + }, + { + element: app.construct.calendarBox() + }, + { + element: app.construct.currentEventsList(), + size: 300 + } + ] + }); + return p; + }, + + 'cityPicker': function() { + var id = 'cityPicker'; + var i = app.$ui[id] = new Ox.Input({ + id: id, + placeholder: 'Chose Your City', + autocomplete: ['Mumbai', 'Gurgaon', 'Agra', 'Delhi', 'Bangalore', 'Calcutta', 'Hyderabad'], + autocompleteSelect: true, + autocompleteSelectHighlight: true, + autocompleteSelectSubmit: true, + autocompleteReplaceCorrect: true + }); + i.bindEvent("submit", function(event, data) { + Ox.print(data); +// alert(data.value); + }); + return i; + }, + + 'calendarBox': function() { + var id = 'calendarBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("somehow, the bookmyshow calendar goes here."); + return c; + }, + + 'currentEventsList': function() { + var id = 'currentEventsList'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("List of current events"); + return c; + }, + /* + END leftPanel + */ + + /* + BEGIN middlePanel + */ + 'middlePanel': function() { + var id = 'middlePanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + orientation: 'vertical', + id: id, + elements: [ + { + element: app.construct.middleTopPanel(), + size: 128, + resizable: true, + resize: [0, 64, 128, 196, 256], +// collapsible: true + }, + { + element: app.construct.middleMiddlePanel(), +// collapsible: true + }, + { + element: app.construct.middleBottomPanel(), + size: 128, + resizable: true, + resize: [0, 64, 128, 196, 256], +// collapsible: true + } + ] + }); + return p; + }, + + /* + BEGIN middleTopPanel + */ + 'middleTopPanel': function() { + var id = 'middleTopPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'horizontal', + elements: [ + { + element: app.construct.newsfeedBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + }, + { + element: app.construct.aboutBox() + }, + { + element: app.construct.itfBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + } + ] + }); + return p; + }, + + 'newsfeedBox': function() { + var id = 'newsfeedBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id, + title: 'ITF NewsFeed' + }); + for (var i=0; i<25; i++) { + var content = new Ox.Element().html('newsfeed content goes here'); + c.append(content); + } + return c; + }, + + 'aboutBox': function() { + var id = 'aboutBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id, + title: 'About' + }); + c.html("about goes here"); + return c; + }, + + 'itfBox': function() { + var id = 'itfBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("about itf goes here"); + return c; + }, + /* + END middleTopPanel + */ + + /* + BEGIN middleMiddlePanel + */ + + 'middleMiddlePanel': function() { + var id = 'middleMiddlePanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'horizontal', + elements: [ + { + element: app.construct.erangBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + }, + { + element: app.construct.scriptArchiveBox() + }, + { + element: app.construct.bestPracticesBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + } + ] + }); + return p; + }, + + 'erangBox': function() { + var id = 'erangBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("erang goes here"); + return c; + }, + + 'scriptArchiveBox': function() { + var id = 'scriptbankBox'; + var c = app.$ui[id] = new Ox.ItfBox({ + 'id': id, + 'title': 'Script Bank', + 'module': 'scriptbank', + 'model': 'Script', + 'info': 'Script Archives are great, etc.' + }); +// c.html("script archive goes here"); + return c; + }, + + 'bestPracticesBox': function() { + var id = 'bestpracticesBox'; + var title = "Best Practices"; + var module = "bestpractices"; + var model = "BestPractice"; + var info = "Some best practices lorem ipsum"; + var c = app.$ui[id] = new Ox.ItfBox({ + 'id': id, + 'title': 'Best Practices', + 'module': 'bestpractices', + 'model': 'BestPractice', + 'info': 'Some best practices lorem ipsum' +/* + 'preview': function(data, callback) { + var selectedId = data.ids[0]; + app.api.preview({ + 'model': model, + 'module': module, + 'data': {'id': selectedId} + }, callback); + } +*/ + }); +// c.html("best practices goes here"); + return c; + }, + + /* + END middleMiddlePanel + */ + + /* + BEGIN middleBottomPanel + */ + 'middleBottomPanel': function() { + var id = 'middleBottomPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'horizontal', + elements: [ + { + element: app.construct.biblioBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + }, + { + element: app.construct.offersNeedsBox() + }, + { + element: app.construct.surveysBox(), + size: 256, + resizable: true, + resize: [0,128,196,256,384,512] + } + ] + }); + return p; + }, + + 'biblioBox': function() { + var id = 'biblioBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("biblioBox here"); + return c; + }, + + 'offersNeedsBox': function() { + var id = 'offersNeedsBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("offers and needs here"); + return c; + }, + + 'surveysBox': function() { + var id = 'surveysBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("surveys go here"); + return c; + }, + + /* + END middleBottomPanel + */ + + /* + END middlePanel + */ + + /* + BEGIN rightPanel + */ + + 'rightPanel': function() { + var id = 'rightPanel'; + var p = app.$ui[id] = new Ox.SplitPanel({ + id: id, + orientation: 'vertical', + elements: [ + { + element: app.construct.loginBox(), + size: 256 + }, + { + element: app.construct.previewBox() + } + ] + }); + return p; + }, + + 'loginBox': function() { + var id = 'loginBox'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + +/* + var registerForm = (function() { + var u = ui.accountDialogOptions('register'); + var btns = u.buttons; + var content = u.content; + var title = u.title; + // debugger; + var e = new Ox.Element().html(title).append(content); + var btnsWrapper = new Ox.Element().css({'textAlign': 'center', 'marginTop': '4px'}); + var regBtn = btns[1][1].appendTo(btnsWrapper); + var loginBtn = new Ox.Button({ + id: 'loginBtn', + title: 'Login' + }).bindEvent("click", function() { + // app.$ui.accountDialog = new Ox.Element(); + var l = ui.accountDialogOptions("login"); + var loginContent = l.content; + var loginSubmitBtn = l.buttons[1][1]; + var loginTitle = l.title; + var d = new Ox.Dialog({ + id: 'loginDialog', + content: loginContent, + buttons: [ + new Ox.Button({ + id: 'cancel', + title: 'Cancel', + }).bindEvent("click", function() { d.close(); }), + loginSubmitBtn + ], + title: loginTitle + }); + d.open(); + }); + loginBtn.appendTo(btnsWrapper); + btnsWrapper.appendTo(e); + return e; + })(); + + + registerForm.appendTo(c); +*/ +/* + var $registerTitle = new Ox.Element().html("Register:").appendTo(c); + var registerForm = c.$form = new Ox.Form({ + id: "registerForm", + items: $registerFormItems, + submit: function(data, callback) { + alert(JSON.stringify(data)); + app.api.register(data, function(result) { + alert(JSON.stringify(result)); + }); + + } +*/ +// c.html("login goes here"); + return c; + }, + + 'previewBox': function() { + var id = 'previewBox'; + var c = app.$ui[id] = new Ox.ItfPreview({ + id: id + }); + c.$content.html("previews here"); + return c; + }, + + /* + END rightPanel + */ + +/* +END mainPanel +*/ + +/* +BEGIN footerPanel +*/ + 'footerPanel': function() { + var id = 'footerPanel'; + var c = app.$ui[id] = new Ox.Element({ + id: id + }); + c.html("footer goes here"); + return c; + } +/* +END footerPanel +*/ +} + diff --git a/itf/static/js/itf/forms.js b/itf/static/js/itf/forms.js new file mode 100644 index 0000000..4613bb0 --- /dev/null +++ b/itf/static/js/itf/forms.js @@ -0,0 +1,456 @@ + + + +var $registerFormItems = (function() { + var $username = new Ox.Input({ + 'id': 'registerUsername', + 'autovalidate': autovalidateUsername, + 'label': 'Username:', + 'labelWidth': 90, + 'validate': function(value, callback) { + callback({ + 'message': 'Missing Username', + 'valid': !!value.length + }); + }, + 'width': 256 + }); + var $password = new Ox.Input({ + 'id': 'registerPassword', + autovalidate: /.+/, + label: 'Password:', + labelWidth: 90, + 'type': 'password', + 'validate': function(value, callback) { + callback({ + 'message': 'Missing Password', + 'valid': !!value.length + }); + }, + width: 256 + }); + + var $email = new Ox.Input({ + id: 'registerEmail', + 'type': 'email', + autovalidate: autovalidateEmail, + label: 'E-Mail:', + labelWidth: 90, + width: 256 + }); + + return [$username, $password, $email] +})(); + + + var ui = { + accountDialog: function(action) { + var that = app.$ui.accountDialog = new Ox.Dialog($.extend({ + height: 256, + id: 'accountDialog', + minHeight: 256, + minWidth: 384, + width: 384 + }, ui.accountDialogOptions(action))) + .bindEvent({ + resize: function(event, data) { + var width = data.width - 32; + app.$ui.accountForm.items.forEach(function(item) { + item.options({width: width}); + }); + } + }); + return that; + }, + accountDialogOptions: function(action, value) { + Ox.print('ACTION', action) +// app.$ui.accountForm && app.$ui.accountForm.remove(); + var buttons = { + login: ['register', 'reset'], + register: ['login'], + reset: ['login'], + resetAndLogin: [] + }, + buttonTitle = { + login: 'Login', + register: 'Register', + reset: 'Reset Password', + resetAndLogin: 'Reset Password and Login' + }, + dialogText = { + login: 'To login to your account, please enter your username and password.', + register: 'To create a new account, please choose a username and password, and enter your e-mail address.', + reset: 'To reset your password, please enter either your username or your e-mail address.', + resetAndLogin: 'To login to your account, please choose a new password, and enter the code that we have just e-mailed to you.' + }, + dialogTitle = { + login: 'Login', + register: 'Register', + reset: 'Reset Password', + resetAndLogin: 'Reset Password' + }; + function button(type) { + if (type == 'cancel') { + return new Ox.Button({ + id: 'cancel' + Ox.toTitleCase(action), + title: 'Cancel' + }).bindEvent('click', function() { + app.$ui.accountDialog.close(); + }); + } else if (type == 'submit') { + return new Ox.Button({ + disabled: true, + id: 'submit' + Ox.toTitleCase(action), + title: buttonTitle[action] + }).bindEvent('click', function() { + app.$ui.accountForm.submit(); + }); + } else { + return new Ox.Button({ + id: type, + title: buttonTitle[type] + '...' + }).bindEvent('click', function() { + Ox.print('CLICK EVENT', type) + app.$ui.accountDialog.options(ui.accountDialogOptions(type)); + }); + } + } + return { + buttons: [ + $.map(buttons[action], function(type) { + return button(type); + }), + [button('cancel'), button('submit')] + ], + content: new Ox.Element('div') + .append( + new Ox.Element('div') + .addClass('OxText') + .html(dialogText[action] + '

') + ) + .append( + app.$ui.accountForm = ui.accountForm(action, value) + ), + keys: { + enter: 'submit' + Ox.toTitleCase(action), + escape: 'cancel' + Ox.toTitleCase(action) + }, + title: dialogTitle[action] + }; + }, + accountForm: function(action, value) { + if (app.$ui.accountForm) { + app.$ui.accountForm.items.forEach(function(item) { + if (item.options('id') == 'usernameOrEmail') { + Ox.print('REMOVING') + //Ox.Event.unbind('usernameOrEmailSelect') + //Ox.Event.unbind('usernameOrEmailSelectMenu') + //Ox.Event.unbind('usernameOrEmailInput') + } + Ox.print('REMOVING ITEM', item.options('id')); +// item.remove(); + }); + } + var items = { + 'login': ['username', 'password'], + 'register': ['newUsername', 'password', 'email'], + 'reset': ['usernameOrEmail'], + 'resetAndLogin': ['oldUsername', 'newPassword', 'code'] + }, + $items = $.map(items[action], function(v) { + return item(v, value); + }), + that = new Ox.Form({ + id: 'accountForm' + Ox.toTitleCase(action), + items: $items, + submit: function(data, callback) { + if (action == 'login') { + pandora.api.login(data, function(result) { + if (!result.data.errors) { + app.$ui.accountDialog.close(); + login(result.data); + } else { + callback([{id: 'password', message: 'Incorrect password'}]); + } + }); + } else if (action == 'register') { + pandora.api.register(data, function(result) { + if (!result.data.errors) { + app.$ui.accountDialog.close(); + login(result.data); + ui.accountWelcomeDialog().open(); + } else { + callback([{id: 'password', message: result.data.errors.toString()}]); // fixme + } + }); + } else if (action == 'reset') { + var usernameOrEmail = data.usernameOrEmail, + key = usernameOrEmail[0].id; + data = {}; + data[key] = usernameOrEmail[1]; + pandora.api.requestToken(data, function(result) { + if (!result.data.errors) { + app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username)); + } else { + callback([{id: 'usernameOrEmail', message: 'Unknown ' + (key == 'username' ? 'username' : 'e-mail address')}]) + } + }); + } else if (action == 'resetAndLogin') { + pandora.api.resetPassword(data, function(result) { + if (!result.data.errors) { + app.$ui.accountDialog.close(); + login(result.data); + } else { + callback([{id: 'code', message: 'Incorrect code'}]); + } + }) + } + } + }).bindEvent({ + submit: function(event, data) { + + }, + validate: function(event, data) { + Ox.print('FORM VALIDATE', data) + app.$ui.accountDialog[ + (data.valid ? 'enable' : 'disable') + 'Button' + ]('submit' + Ox.toTitleCase(action)); + } + }); + that.items = $items; + function item(type, value) { + if (type == 'code') { + return new Ox.Input({ + autovalidate: autovalidateCode, + id: 'code', + label: 'Code', + labelWidth: 120, + validate: function(value, callback) { + callback({ + message: 'Missing code', + valid: !!value.length + }); + }, + width: 352 + }); + } else if (type == 'email') { + return new Ox.Input({ + autovalidate: autovalidateEmail, + id: 'email', + label: 'E-Mail Address', + labelWidth: 90, + type: 'email', + validate: validateUser('email'), + width: 250 + }); + } else if (type == 'newPassword') { + return new Ox.Input({ + autovalidate: /.+/, + id: 'password', + label: 'New Password', + labelWidth: 90, + type: 'password', + validate: function(value, callback) { + callback({ + message: 'Missing password', + valid: value.length > 0 + }); + }, + width: 250 + }); + } else if (type == 'newUsername') { + return new Ox.Input({ + autovalidate: autovalidateUsername, + id: 'username', + label: 'Username', + labelWidth: 90, + validate: validateUser('username'), + width: 250 + }); + } else if (type == 'oldUsername') { + return new Ox.Input({ + disabled: true, + id: 'username', + label: 'Username', + labelWidth: 90, + value: value, + width: 250 + }); + } else if (type == 'password') { + return new Ox.Input({ + autovalidate: /.+/, + id: 'password', + label: 'Password', + labelWidth: 90, + type: 'password', + validate: function(value, callback) { + callback({ + message: 'Missing Password', + valid: value.length > 0 + }); + }, + width: 250 + }); + } else if (type == 'username') { + return new Ox.Input({ + autovalidate: autovalidateUsername, + id: 'username', + label: 'Username', + labelWidth: 90, + validate: validateUser('username', true), + width: 250 + }); + } else if (type == 'usernameOrEmail') { + return new Ox.FormElementGroup({ + id: 'usernameOrEmail', + elements: [ + app.$ui.usernameOrEmailSelect = new Ox.Select({ + id: 'usernameOrEmailSelect', + items: [ + {id: 'username', title: 'Username'}, + {id: 'email', title: 'E-Mail Address'}, + ], + overlap: 'right', + width: 120 + }) + .bindEvent({ + change: function(event, data) { + var selected = data.selected[0].id; + app.$ui.usernameOrEmailInput.options({ + autovalidate: selected == 'username' ? autovalidateUsername : autovalidateEmail, + validate: validateUser(selected, true), + value: '' + }).focus(); + } + }), + app.$ui.usernameOrEmailInput = new Ox.Input({ + autovalidate: autovalidateUsername, + id: 'usernameOrEmailInput', + validate: validateUser('username', true), + width: 232 + }) + ], + separators: [ + {title: '', width: 0} + ] + }); + } + } + return that; + }, + accountLogoutDialog: function() { + var that = new Ox.Dialog({ + buttons: [ + new Ox.Button({ + id: 'cancel', + title: 'Cancel' + }).bindEvent('click', function() { + that.close(); + app.$ui.mainMenu.getItem('loginlogout').toggleTitle(); + }), + new Ox.Button({ + id: 'logout', + title: 'Logout' + }).bindEvent('click', function() { + that.close(); + pandora.api.logout({}, function(result) { + logout(result.data); + }); + }) + ], + content: new Ox.Element('div').html('Are you sure you want to logout?'), + height: 160, + keys: {enter: 'logout', escape: 'cancel'}, + title: 'Logout', + width: 300 + }); + return that; + }, + accountWelcomeDialog: function() { + var that = new Ox.Dialog({ + buttons: [ + [ + new Ox.Button({ + id: 'preferences', + title: 'Preferences...' + }).bindEvent('click', function() { + that.close(); + }) + ], + [ + new Ox.Button({ + id: 'close', + title: 'Close' + }).bindEvent('click', function() { + that.close(); + }) + ] + ], + content: new Ox.Element('div').html('Welcome, ' + app.user.username + '!

Your account has been created.'), + height: 160, + keys: {enter: 'close', escape: 'close'}, + title: 'Welcome to ' + app.config.site.name, + width: 300 + }); + return that; + } + } + +//FIXME: move these somewhere. +function autovalidateCode(value, blur, callback) { + value = $.map(value.toUpperCase().split(''), function(v) { + return /[0-9A-Z]/(v) ? v : null; + }).join(''); + callback(value); +} + +function autovalidateEmail(value, blur, callback) { + value = $.map(value.toLowerCase().split(''), function(v, i) { + return /[0-9a-z\.\+\-_@]/(v) ? v : null; + }).join(''); + callback(value); +} + +function autovalidateUsername(value, blur, callback) { + var length = value.length; + value = $.map(value.toLowerCase().split(''), function(v, i) { + if (new RegExp('[0-9a-z' + ((i == 0 || (i == length - 1 && blur)) ? '' : '\-_') + ']')(v)) { + return v + } else { + return null; + } + }).join(''); + $.each(['--', '-_', '_-', '__'], function(i, v) { + while (value.indexOf(v) > -1) { + value = value.replace(new RegExp(v, 'g'), v[0]); + } + }) + callback(value); +} + +function validateUser(key, existing) { + existing = existing || false; + var string = key == 'username' ? 'username' : 'e-mail address'; + return function(value, callback) { + var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value); + valid ? pandora.api.findUser({ + key: key, + value: value, + operator: '=' + }, function(result) { + var valid = existing == !!result.data.users.length; + Ox.print(existing, result.data.users) + callback({ + message: existing ? + 'Unknown ' + string : + string[0].toUpperCase() + string.substr(1) + ' already exists', + valid: valid + }); + }) : callback({ + message: (!value.length ? 'Missing' : 'Invalid') + ' ' + string, + valid: false + }); + }; +} + + diff --git a/itf/static/js/itf/itf.js b/itf/static/js/itf/itf.js index 1627bc0..0daa4ef 100644 --- a/itf/static/js/itf/itf.js +++ b/itf/static/js/itf/itf.js @@ -1,40 +1,5 @@ var ITF = {}; -var app = new Ox.App({ - apiURL: '/api/', - init: 'hello', - config: 'site.json' //FIXME: shouldn't need this, get data with 'hello' or 'init'. -}); - -app.launch(function(data) { - Ox.theme("classic"); - Ox.print(data); - - app.$body = $('body'); - app.$document = $(document); - app.$window = $(window); -/* - app.user = data.user; - app.config = data.config; -*/ - -/* - //FIXME: should this be a nested structure as their representation on the page? - app.constructors = ['wrapper', 'headerPanel', 'mainPanel', 'leftPanel', 'cityPicker', 'calendarBox', 'currentEventsList', 'middlePanel', 'middleTopPanel', 'newsfeedBox', 'aboutBox', 'itfBox', 'middleBottomPanel', 'erangBox', 'scriptArchiveBox', 'bestPracticesBox', 'biblioBox', 'offersNeedsBox', 'surveysBox', 'rightPanel', 'searchBox', 'loginBox', 'previewBox', 'footerPanel'] -*/ - - app.$ui = {}; -/* - Ox.each(app.constructors, function(i, v) { - app.$ui[v] = app.construct[v](); - }); -*/ - var wrapper = app.construct.wrapper(); - app.$body.css({'opacity': 0}); - wrapper.appendTo(app.$body); - app.$body.animate({ - 'opacity': 1 - }, 2000); /* @@ -52,748 +17,7 @@ app.launch(function(data) { // $(body).append(app.$ui.wrapper); -}); -app.Query = (function() { - - function constructFind(query) { - Ox.print('cF', query) - return /*encodeURI(*/$.map(query.conditions, function(v, i) { - if (!Ox.isUndefined(v.conditions)) { - return '[' + constructFind(v) + ']'; - } else { - return v.value !== '' ? v.key + (v.key ? ':' : '') + constructValue(v.value, v.operator) : null; - } - }).join(query.operator)/*)*/; - } - - function constructValue(value, operator) { - operator = operator.replace('=', '^$'); - if (operator.indexOf('$') > -1) { - value = operator.substr(0, operator.length - 1) + value + '$' - } else { - value = operator + value; - } - return value; - } - - function mergeFind() { - } - - function parseFind(str) { - var find = { - conditions: [], - operator: '' - }, - subconditions = str.match(/\[.*?\]/g) || []; - $.each(subconditions, function(i, v) { - subconditions[i] = v.substr(1, v.length - 2); - str = str.replace(v, '[' + i + ']'); - }); - if (str.indexOf(',') > -1) { - find.operator = '&'; - } else if (str.indexOf('|') > -1) { - find.operator = '|'; - } - Ox.print('pF', str, find.operator) - find.conditions = $.map(find.operator === '' ? [str] : str.split(find.operator == '&' ? ',' : '|'), function(v, i) { - Ox.print('v', v) - var ret, kv; - if (v[0] == '[') { - Ox.print('recursion', subconditions) - ret = parseFind(subconditions[parseInt(v.substr(1, v.length - 2))]); - } else { - kv = ((v.indexOf(':') > - 1 ? '' : ':') + v).split(':'); - ret = $.extend({ - key: kv[0] - }, parseValue(kv[1])); - } - return ret; - }); - return find; - } - - function parseValue(str) { - var value = { - value: decodeURI(str), - operator: '' - }; - if (value.value[0] == '!') { - value.operator = '!' - value.value = value.value.substr(1); - } - if ('^<>'.indexOf(value.value[0]) > -1) { - value.operator += value.value[0]; - value.value = value.value.substr(1); - } - if (value.value.substr(-1) == '$') { - value.operator += '$'; - value.value = value.value.substr(0, value.value.length - 1); - } - value.operator = value.operator.replace('^$', '='); - return value; - } - - return { - - fromString: function(str) { - var query = Ox.unserialize(str), - sort = []; - if ('find' in query) { - app.user.ui.findQuery = parseFind(query.find); - Ox.print('user.ui.findQuery', app.user.ui.findQuery) - } - if ('sort' in query) { - sort = query.sort.split(',') - app.user.ui.sort = $.map(query.sort.split(','), function(v, i) { - var hasOperator = '+-'.indexOf(v[0]) > -1, - key = hasOperator ? query.sort.substr(1) : query.sort, - operator = hasOperator ? v[0].replace('+', '') : Ox.getObjectById(app.config.sortKeys, key).operator; - return { - key: key, - operator: operator - }; - }); - } - if ('view' in query) { - app.user.ui.listView = query.view; - } - }, - - toObject: function(groupId) { - Ox.print('tO', app.user.ui.findQuery.conditions) - // the inner $.merge() creates a clone - var conditions = $.merge($.merge([], app.user.ui.listQuery.conditions), app.user.ui.findQuery.conditions); - $.merge(conditions, app.ui.groups ? $.map(app.ui.groups, function(v, i) { - if (v.id != groupId && v.query.conditions.length) { - return v.query.conditions.length == 1 ? - v.query.conditions : v.query; - } - }) : []), - operator = conditions.length < 2 ? '' : ','; // fixme: should be & - Ox.print('>>', groupId, app.user.ui.find, conditions); - return { - conditions: conditions, - operator: operator - }; - }, - - toString: function() { - Ox.print('tS', app.user.ui.find) - return Ox.serialize({ - find: constructFind(app.Query.toObject()), - sort: app.user.ui.sort[0].operator + app.user.ui.sort[0].key, - view: app.user.ui.listView - }); - } - - }; - -})(); - - -var $registerFormItems = (function() { - var $username = new Ox.Input({ - 'id': 'registerUsername', - 'autovalidate': autovalidateUsername, - 'label': 'Username:', - 'labelWidth': 90, - 'validate': function(value, callback) { - callback({ - 'message': 'Missing Username', - 'valid': !!value.length - }); - }, - 'width': 256 - }); - var $password = new Ox.Input({ - 'id': 'registerPassword', - autovalidate: /.+/, - label: 'Password:', - labelWidth: 90, - 'type': 'password', - 'validate': function(value, callback) { - callback({ - 'message': 'Missing Password', - 'valid': !!value.length - }); - }, - width: 256 - }); - - var $email = new Ox.Input({ - id: 'registerEmail', - 'type': 'email', - autovalidate: autovalidateEmail, - label: 'E-Mail:', - labelWidth: 90, - width: 256 - }); - - return [$username, $password, $email] -})(); - - -app.construct = { -/* -Structure: - wrapper - headerPanel - homeBox - searchBox - mainPanel - leftPanel - cityPicker - calendarBox - currentEventsList - middlePanel - middleTopPanel - newsfeedBox - aboutBox - itfBox - middleMiddlePanel - erangBox - scriptArchiveBox - bestPracticesBox - middleBottomPanel - biblioBox - offersNeedsBox - surveysBox - rightPanel - loginBox - previewBox - footerPanel -*/ - - - 'wrapper': function() { - var id = 'wrapper'; - // Constructs overall wrapper for the page, and should be appended to $(body) - return app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'vertical', - elements: [ - { - element: app.construct.headerPanel(), - size: 40 - }, - { - element: app.construct.mainPanel(), - }, - { - element: app.construct.footerPanel(), - size: 40 - } - ] - }); - }, - -/* -BEGIN headerPanel -*/ - 'headerPanel': function() { - var id = 'headerPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - orientation: 'horizontal', - id: id, - elements: [ - { - element: app.construct.homeBox(), - }, - { - element: app.construct.searchBox(), - size: 128 - - } - ] - }); - return p; - }, - - 'homeBox': function() { - var id = 'homeBox'; - var c = app.$ui.homeBox = new Ox.Element({ - id: id - }); - c.html("This is the header - maybe load from a template?"); - return c; - }, - - 'searchBox': function() { - var id = 'searchBox'; - var i = app.$ui.searchBox = new Ox.Input({ - 'id': id, - 'placeholder': 'Search' - }); - i.bindEvent("submit", function(val) { - Ox.print("Should be doing a search"); - }); - i.css({ - 'marginRight': '15px', - 'marginTop': '6px' - }); - return i; - }, - -/* -END headerPanel -*/ - -/* -BEGIN mainPanel -*/ - - 'mainPanel': function() { - var id = 'mainPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'horizontal', - elements: [ - { - element: app.construct.leftPanel(), - size: 256, - resizable: true, - resize: [0, 128, 256, 384] - }, - { - element: app.construct.middlePanel() -// resizable: true - }, - { - element: app.construct.rightPanel(), - size: 256, - resizable: true, - resize: [0, 128, 256, 384] - } - ] - }); - return p; - }, - - /* - BEGIN leftPanel - */ - 'leftPanel': function() { - var id = 'leftPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'vertical', - elements: [ - { - element: app.construct.cityPicker(), - size: 40 - }, - { - element: app.construct.calendarBox() - }, - { - element: app.construct.currentEventsList(), - size: 300 - } - ] - }); - return p; - }, - - 'cityPicker': function() { - var id = 'cityPicker'; - var i = app.$ui[id] = new Ox.Input({ - id: id, - placeholder: 'Chose Your City', - autocomplete: ['Mumbai', 'Gurgaon', 'Agra', 'Delhi', 'Bangalore', 'Calcutta', 'Hyderabad'], - autocompleteSelect: true, - autocompleteSelectHighlight: true, - autocompleteSelectSubmit: true, - autocompleteReplaceCorrect: true - }); - i.bindEvent("submit", function(event, data) { - Ox.print(data); -// alert(data.value); - }); - return i; - }, - - 'calendarBox': function() { - var id = 'calendarBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("somehow, the bookmyshow calendar goes here."); - return c; - }, - - 'currentEventsList': function() { - var id = 'currentEventsList'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("List of current events"); - return c; - }, - /* - END leftPanel - */ - - /* - BEGIN middlePanel - */ - 'middlePanel': function() { - var id = 'middlePanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - orientation: 'vertical', - id: id, - elements: [ - { - element: app.construct.middleTopPanel(), - size: 128, - resizable: true, - resize: [0, 64, 128, 196, 256], -// collapsible: true - }, - { - element: app.construct.middleMiddlePanel(), -// collapsible: true - }, - { - element: app.construct.middleBottomPanel(), - size: 128, - resizable: true, - resize: [0, 64, 128, 196, 256], -// collapsible: true - } - ] - }); - return p; - }, - - /* - BEGIN middleTopPanel - */ - 'middleTopPanel': function() { - var id = 'middleTopPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'horizontal', - elements: [ - { - element: app.construct.newsfeedBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - }, - { - element: app.construct.aboutBox() - }, - { - element: app.construct.itfBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - } - ] - }); - return p; - }, - - 'newsfeedBox': function() { - var id = 'newsfeedBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id, - title: 'ITF NewsFeed' - }); - for (var i=0; i<25; i++) { - var content = new Ox.Element().html('newsfeed content goes here'); - c.append(content); - } - return c; - }, - - 'aboutBox': function() { - var id = 'aboutBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id, - title: 'About' - }); - c.html("about goes here"); - return c; - }, - - 'itfBox': function() { - var id = 'itfBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("about itf goes here"); - return c; - }, - /* - END middleTopPanel - */ - - /* - BEGIN middleMiddlePanel - */ - - 'middleMiddlePanel': function() { - var id = 'middleMiddlePanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'horizontal', - elements: [ - { - element: app.construct.erangBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - }, - { - element: app.construct.scriptArchiveBox() - }, - { - element: app.construct.bestPracticesBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - } - ] - }); - return p; - }, - - 'erangBox': function() { - var id = 'erangBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("erang goes here"); - return c; - }, - - 'scriptArchiveBox': function() { - var id = 'scriptbankBox'; - var c = app.$ui[id] = new Ox.ItfBox({ - 'id': id, - 'title': 'Script Bank', - 'module': 'scriptbank', - 'model': 'Script', - 'info': 'Script Archives are great, etc.' - }); -// c.html("script archive goes here"); - return c; - }, - - 'bestPracticesBox': function() { - var id = 'bestpracticesBox'; - var title = "Best Practices"; - var module = "bestpractices"; - var model = "BestPractice"; - var info = "Some best practices lorem ipsum"; - var c = app.$ui[id] = new Ox.ItfBox({ - 'id': id, - 'title': 'Best Practices', - 'module': 'bestpractices', - 'model': 'BestPractice', - 'info': 'Some best practices lorem ipsum' -/* - 'preview': function(data, callback) { - var selectedId = data.ids[0]; - app.api.preview({ - 'model': model, - 'module': module, - 'data': {'id': selectedId} - }, callback); - } -*/ - }); -// c.html("best practices goes here"); - return c; - }, - - /* - END middleMiddlePanel - */ - - /* - BEGIN middleBottomPanel - */ - 'middleBottomPanel': function() { - var id = 'middleBottomPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'horizontal', - elements: [ - { - element: app.construct.biblioBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - }, - { - element: app.construct.offersNeedsBox() - }, - { - element: app.construct.surveysBox(), - size: 256, - resizable: true, - resize: [0,128,196,256,384,512] - } - ] - }); - return p; - }, - - 'biblioBox': function() { - var id = 'biblioBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("biblioBox here"); - return c; - }, - - 'offersNeedsBox': function() { - var id = 'offersNeedsBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("offers and needs here"); - return c; - }, - - 'surveysBox': function() { - var id = 'surveysBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("surveys go here"); - return c; - }, - - /* - END middleBottomPanel - */ - - /* - END middlePanel - */ - - /* - BEGIN rightPanel - */ - - 'rightPanel': function() { - var id = 'rightPanel'; - var p = app.$ui[id] = new Ox.SplitPanel({ - id: id, - orientation: 'vertical', - elements: [ - { - element: app.construct.loginBox(), - size: 256 - }, - { - element: app.construct.previewBox() - } - ] - }); - return p; - }, - - 'loginBox': function() { - var id = 'loginBox'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - - var registerForm = (function() { - var u = ui.accountDialogOptions('register'); - var btns = u.buttons; - var content = u.content; - var title = u.title; - // debugger; - var e = new Ox.Element().html(title).append(content); - var btnsWrapper = new Ox.Element().css({'textAlign': 'center', 'marginTop': '4px'}); - var regBtn = btns[1][1].appendTo(btnsWrapper); - var loginBtn = new Ox.Button({ - id: 'loginBtn', - title: 'Login' - }).bindEvent("click", function() { - // app.$ui.accountDialog = new Ox.Element(); - var l = ui.accountDialogOptions("login"); - var loginContent = l.content; - var loginSubmitBtn = l.buttons[1][1]; - var loginTitle = l.title; - var d = new Ox.Dialog({ - id: 'loginDialog', - content: loginContent, - buttons: [ - new Ox.Button({ - id: 'cancel', - title: 'Cancel', - }).bindEvent("click", function() { d.close(); }), - loginSubmitBtn - ], - title: loginTitle - }); - d.open(); - }); - loginBtn.appendTo(btnsWrapper); - btnsWrapper.appendTo(e); - return e; - })(); - - - registerForm.appendTo(c); - -/* - var $registerTitle = new Ox.Element().html("Register:").appendTo(c); - var registerForm = c.$form = new Ox.Form({ - id: "registerForm", - items: $registerFormItems, - submit: function(data, callback) { - alert(JSON.stringify(data)); - app.api.register(data, function(result) { - alert(JSON.stringify(result)); - }); - - } -*/ -// c.html("login goes here"); - return c; - }, - - 'previewBox': function() { - var id = 'previewBox'; - var c = app.$ui[id] = new Ox.ItfPreview({ - id: id - }); - c.$content.html("previews here"); - return c; - }, - - /* - END rightPanel - */ - -/* -END mainPanel -*/ - -/* -BEGIN footerPanel -*/ - 'footerPanel': function() { - var id = 'footerPanel'; - var c = app.$ui[id] = new Ox.Element({ - id: id - }); - c.html("footer goes here"); - return c; - } -/* -END footerPanel -*/ -} @@ -801,720 +25,9 @@ END footerPanel Ox.Box - generic box element, with a bar, some help, search, a menu, etc. */ -Ox.ItfBox = function(options, self) { - var self = self || {}; - var that = new Ox.Element(options, self) - .defaults({ - 'title': '', - 'extraButtons': [] - }) - .options(options); - var title = self.options.title; - var $titlebar = new Ox.Bar({ - orientation: 'horizontal', - size: 18 - }) -// .dblclick(dblclickTitlebar) - .appendTo(that); - - - var $title = new Ox.Element() - .addClass('OxTitle') - .html(title/*.toUpperCase()*/) - .appendTo($titlebar); - - - var $search = new Ox.Input({ - 'placeholder': 'Search', - }) - .css({'width': '128px', 'marginLeft': 'auto', 'marginRight': 'auto'}) - .appendTo(that) - .hide() - .bindEvent("submit", function(value) { - app.$ui[options.boxId].$loading.start(); - $list.options("request", function(data, callback) { - app.$ui[options.boxId].$loading.stop(); - return app.api.find(getQueryParams(data), callback); - }); - }); - - - that.search = function(word) { - $search.options("value", word); - $search.triggerEvent("submit"); - } - - var $buttons = new Ox.Element().appendTo($title).css({'position': 'absolute', 'top': '1px', 'right': '1px'}); - - - - var $additionalButtons = self.options.extraButtons; - if ($additionalButtons.length > 0) { - $additionalButtons.appendTo($buttons); - } - var $infoBtn = new Ox.Button({ - id: options.id + "InfoBtn", - style: 'symbold', - title: 'info', - type: 'image', - tooltip: 'More info about ' + options.title - }) - .appendTo($buttons) - .bindEvent("click", function() { - var info = options.info; - var d = new Ox.Dialog({ - buttons: [ - new Ox.Button({ - id: 'cancel', - title: 'Close', - }) - .bindEvent("click", function() { d.close(); }) - ], - content: new Ox.Element().html(info), - title: options.title - }) - .open(); - }); - - var $searchBtn = new Ox.Button({ - id: options.id + 'SearchBtn', - style: 'symbol', - title: 'find', - type: 'image', - tooltip: 'Search' - }) - .bindEvent("click", function() { - if ($search.is(":visible")) { - $search.slideUp(); - } else { - $search.slideDown(); - $search.focus(); - } - }) - .appendTo($buttons); - - - var $menuBtn = new Ox.Button({ - id: options.id + 'MenuBtn', - style: 'symbol', - title: 'collapse', - type: 'image', - tooltip: 'Show Menu' - }).appendTo($buttons); - - that.$loading = new Ox.LoadingIcon().appendTo($buttons); - - var $menu = new Ox.Menu({ - id: options.id + 'Menu', - element: $menuBtn, - items: [ - { - id: 'SortBy', - title: 'Sort By', - items: [ - { - 'group': 'sortGroup', - 'min': 1, - 'max': 1, - items: [ - {'id': 'sort_added_descending', title: 'Added (Descending)', checked: true}, - {'id': 'sort_added_ascending', title: 'Added (Ascending)'}, - {'id': 'sort_title_ascending', title: 'Title (Ascending)'}, - {'id': 'sort_title_descending', title: 'Title (Descending)'}, - ] - } - ] - }, - {id: 'Test2', title: 'Menu Item 2'} - ] - }) - .bindEvent("change", function(e, data) { - if (data.id === 'sortGroup') { - var checked = data.checked[0]; - var checkedId = checked.id; - var checkedField = checkedId.split("_")[1]; - var operator = checkedId.split("_")[2] == "ascending" ? "+" : "-"; - $list.sortList(checkedField, operator); - } - }); - -// var $menu = new Ox.Menu({ -// id: options.id + 'Menu', -// element: $menuBtn, -// items: [ -// { -// 'group': 'sortGroup', -// 'min': 1, -// 'max': 1, -// items: [ -// {'id': 'sortTitleAscending', title: 'Title (Ascending)', checked: true}, -// {'id': 'sortTitleDescending', title: 'Title (Descending)'}, -// {'id': 'sortTitleAscendingFoo', title: 'Title (Ascending)'}, -// {'id': 'sortTitleDescendingFoo', title: 'Title (Descending)'}, -// ] -// } -// ] -// }, -// {id: 'Test2', title: 'Menu Item 2'} -// ] -// }) -// .bindEvent("change", function() { -// alert("foo"); -// }); - -// - - $menuBtn.bindEvent("click", function() { - $menu.showMenu(); - }); - - function getQueryParams(data) { -// Ox.print("SEARCHVAL", $search.val()); - return $.extend(data, { - 'search': $search.value() == 'Search' ? '' : $search.value(), - 'model': options.model, - 'module': options.module - }); - } - - var $listContainer = new Ox.Element() - .appendTo(that) - .css({position: 'relative', height: '100%'}); - - var listOptions = $.extend(options, { - 'width': 256, -// 'itemHeight': 16, -// 'itemWidth': 250, -// 'orientation': 'horizontal', - 'request': function(data, callback) { - return app.api.find(getQueryParams(data), callback) - }, - 'id': options.id + 'List', - 'boxId': options.id, - - -/* - 'construct': function(data) { - var $a = $('').attr("href", "/" + options.module.toLowerCase() + "/" + data.id).text(data.title); - var $item = $('
').addClass('OxTarget').append($a); - return $item; - }, -*/ - 'max': 1, - 'columns': [ - { - align: 'left', - id: 'title', - operator: '-', - unique: false, - visible: true, - width: 230 - }, - { - id: 'id', - visible: false, - unique: true - } - ], - 'sort': [ - { - key: 'added', - operator: '-' - } - ] - }); - - var $list = that.$list = new Ox.ItfList(listOptions) - .appendTo($listContainer); - - return that; -} - -Ox.ItfList = function(options, self) { - var self = self || {}; - var that = new Ox.TextList(options, self); - that.bindEvent("select", function(e, data) { - if (data.ids.length === 0) { - app.$ui.previewBox.$content.html(''); - return; - } - app.$ui[options.boxId].$loading.start(); -// debugger; - app.api.preview({ - model: options.model, - module: options.module, - id: data.ids[0] - }, function(response) { -// alert(JSON.stringify(response.data.data)); - app.$ui[options.boxId].$loading.stop(); - var html = $.tmpl(response['template'], response['data']); - app.$ui.previewBox.$content.html(html); - }); - }); - that.bindEvent("open", function(e, data) { -// alert(JSON.stringify(data)); - app.$ui[options.boxId].$loading.start(); - app.api.info({ - model: options.model, - module: options.module, - id: data.ids[0] - }, function(response) { - app.$ui[options.boxId].$loading.stop(); - var html = $.tmpl(response['template'], response['data']); -// alert(html); - var d = new Ox.Dialog({ - buttons: [ - new Ox.Button({ - id: 'cancel', - title: 'Close', - }) - .bindEvent("click", function() { d.close(); }) - ], - content: new Ox.Element().append(html), - title: options.title + ": " + response.data.title, - width: 800, - height: 500 - }) - .open(); -// alert(response); - }); - }); - return that; -} - -Ox.ItfCalendar = function(options, self) { - var self = self || {}; - var that = new Ox.Element(options, self); - var $titleBar = new Ox.Bar({ - 'size': 'small' - }).addClass('OxTitleBar').appendTo(that); - var $title = new Ox.Element().html("Calendar").appendTo($titleBar); - return that; -} - -Ox.ItfPreview = function(options, self) { - var self = self || {}; - var that = new Ox.Element(options, self); - that.$content = new Ox.Element().appendTo(that); - that.$loading = new Ox.LoadingIcon().appendTo(that); - return that; -} - -ITF.templates = {}; - - var ui = { - accountDialog: function(action) { - var that = new Ox.Dialog($.extend({ - height: 256, - id: 'accountDialog', - minHeight: 256, - minWidth: 384, - width: 384 - }, ui.accountDialogOptions(action))) - .bindEvent({ - resize: function(event, data) { - var width = data.width - 32; - app.$ui.accountForm.items.forEach(function(item) { - item.options({width: width}); - }); - } - }); - return that; - }, - accountDialogOptions: function(action, value) { - Ox.print('ACTION', action) -// app.$ui.accountForm && app.$ui.accountForm.remove(); - var buttons = { - login: ['register', 'reset'], - register: ['login'], - reset: ['login'], - resetAndLogin: [] - }, - buttonTitle = { - login: 'Login', - register: 'Register', - reset: 'Reset Password', - resetAndLogin: 'Reset Password and Login' - }, - dialogText = { - login: 'To login to your account, please enter your username and password.', - register: 'To create a new account, please choose a username and password, and enter your e-mail address.', - reset: 'To reset your password, please enter either your username or your e-mail address.', - resetAndLogin: 'To login to your account, please choose a new password, and enter the code that we have just e-mailed to you.' - }, - dialogTitle = { - login: 'Login', - register: 'Register', - reset: 'Reset Password', - resetAndLogin: 'Reset Password' - }; - function button(type) { - if (type == 'cancel') { - return new Ox.Button({ - id: 'cancel' + Ox.toTitleCase(action), - title: 'Cancel' - }).bindEvent('click', function() { - app.$ui.accountDialog.close(); - }); - } else if (type == 'submit') { - return new Ox.Button({ - disabled: true, - id: 'submit' + Ox.toTitleCase(action), - title: buttonTitle[action] - }).bindEvent('click', function() { - app.$ui.accountForm.submit(); - }); - } else { - return new Ox.Button({ - id: type, - title: buttonTitle[type] + '...' - }).bindEvent('click', function() { - Ox.print('CLICK EVENT', type) - app.$ui.accountDialog.options(ui.accountDialogOptions(type)); - }); - } - } - return { - buttons: [ - $.map(buttons[action], function(type) { - return button(type); - }), - [button('cancel'), button('submit')] - ], - content: new Ox.Element('div') - .append( - new Ox.Element('div') - .addClass('OxText') - .html(dialogText[action] + '

') - ) - .append( - app.$ui.accountForm = ui.accountForm(action, value) - ), - keys: { - enter: 'submit' + Ox.toTitleCase(action), - escape: 'cancel' + Ox.toTitleCase(action) - }, - title: dialogTitle[action] - }; - }, - accountForm: function(action, value) { - if (app.$ui.accountForm) { - app.$ui.accountForm.items.forEach(function(item) { - if (item.options('id') == 'usernameOrEmail') { - Ox.print('REMOVING') - //Ox.Event.unbind('usernameOrEmailSelect') - //Ox.Event.unbind('usernameOrEmailSelectMenu') - //Ox.Event.unbind('usernameOrEmailInput') - } - Ox.print('REMOVING ITEM', item.options('id')); -// item.remove(); - }); - } - var items = { - 'login': ['username', 'password'], - 'register': ['newUsername', 'password', 'email'], - 'reset': ['usernameOrEmail'], - 'resetAndLogin': ['oldUsername', 'newPassword', 'code'] - }, - $items = $.map(items[action], function(v) { - return item(v, value); - }), - that = new Ox.Form({ - id: 'accountForm' + Ox.toTitleCase(action), - items: $items, - submit: function(data, callback) { - if (action == 'login') { - pandora.api.login(data, function(result) { - if (!result.data.errors) { - app.$ui.accountDialog.close(); - login(result.data); - } else { - callback([{id: 'password', message: 'Incorrect password'}]); - } - }); - } else if (action == 'register') { - pandora.api.register(data, function(result) { - if (!result.data.errors) { - app.$ui.accountDialog.close(); - login(result.data); - ui.accountWelcomeDialog().open(); - } else { - callback([{id: 'password', message: result.data.errors.toString()}]); // fixme - } - }); - } else if (action == 'reset') { - var usernameOrEmail = data.usernameOrEmail, - key = usernameOrEmail[0].id; - data = {}; - data[key] = usernameOrEmail[1]; - pandora.api.requestToken(data, function(result) { - if (!result.data.errors) { - app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username)); - } else { - callback([{id: 'usernameOrEmail', message: 'Unknown ' + (key == 'username' ? 'username' : 'e-mail address')}]) - } - }); - } else if (action == 'resetAndLogin') { - pandora.api.resetPassword(data, function(result) { - if (!result.data.errors) { - app.$ui.accountDialog.close(); - login(result.data); - } else { - callback([{id: 'code', message: 'Incorrect code'}]); - } - }) - } - } - }).bindEvent({ - submit: function(event, data) { - - }, - validate: function(event, data) { - Ox.print('FORM VALIDATE', data) - app.$ui.accountDialog[ - (data.valid ? 'enable' : 'disable') + 'Button' - ]('submit' + Ox.toTitleCase(action)); - } - }); - that.items = $items; - function item(type, value) { - if (type == 'code') { - return new Ox.Input({ - autovalidate: autovalidateCode, - id: 'code', - label: 'Code', - labelWidth: 120, - validate: function(value, callback) { - callback({ - message: 'Missing code', - valid: !!value.length - }); - }, - width: 352 - }); - } else if (type == 'email') { - return new Ox.Input({ - autovalidate: autovalidateEmail, - id: 'email', - label: 'E-Mail Address', - labelWidth: 90, - type: 'email', - validate: validateUser('email'), - width: 250 - }); - } else if (type == 'newPassword') { - return new Ox.Input({ - autovalidate: /.+/, - id: 'password', - label: 'New Password', - labelWidth: 90, - type: 'password', - validate: function(value, callback) { - callback({ - message: 'Missing password', - valid: value.length > 0 - }); - }, - width: 250 - }); - } else if (type == 'newUsername') { - return new Ox.Input({ - autovalidate: autovalidateUsername, - id: 'username', - label: 'Username', - labelWidth: 90, - validate: validateUser('username'), - width: 250 - }); - } else if (type == 'oldUsername') { - return new Ox.Input({ - disabled: true, - id: 'username', - label: 'Username', - labelWidth: 90, - value: value, - width: 250 - }); - } else if (type == 'password') { - return new Ox.Input({ - autovalidate: /.+/, - id: 'password', - label: 'Password', - labelWidth: 90, - type: 'password', - validate: function(value, callback) { - callback({ - message: 'Missing Password', - valid: value.length > 0 - }); - }, - width: 250 - }); - } else if (type == 'username') { - return new Ox.Input({ - autovalidate: autovalidateUsername, - id: 'username', - label: 'Username', - labelWidth: 90, - validate: validateUser('username', true), - width: 250 - }); - } else if (type == 'usernameOrEmail') { - return new Ox.FormElementGroup({ - id: 'usernameOrEmail', - elements: [ - app.$ui.usernameOrEmailSelect = new Ox.Select({ - id: 'usernameOrEmailSelect', - items: [ - {id: 'username', title: 'Username'}, - {id: 'email', title: 'E-Mail Address'}, - ], - overlap: 'right', - width: 120 - }) - .bindEvent({ - change: function(event, data) { - var selected = data.selected[0].id; - app.$ui.usernameOrEmailInput.options({ - autovalidate: selected == 'username' ? autovalidateUsername : autovalidateEmail, - validate: validateUser(selected, true), - value: '' - }).focus(); - } - }), - app.$ui.usernameOrEmailInput = new Ox.Input({ - autovalidate: autovalidateUsername, - id: 'usernameOrEmailInput', - validate: validateUser('username', true), - width: 232 - }) - ], - separators: [ - {title: '', width: 0} - ] - }); - } - } - return that; - }, - accountLogoutDialog: function() { - var that = new Ox.Dialog({ - buttons: [ - new Ox.Button({ - id: 'cancel', - title: 'Cancel' - }).bindEvent('click', function() { - that.close(); - app.$ui.mainMenu.getItem('loginlogout').toggleTitle(); - }), - new Ox.Button({ - id: 'logout', - title: 'Logout' - }).bindEvent('click', function() { - that.close(); - pandora.api.logout({}, function(result) { - logout(result.data); - }); - }) - ], - content: new Ox.Element('div').html('Are you sure you want to logout?'), - height: 160, - keys: {enter: 'logout', escape: 'cancel'}, - title: 'Logout', - width: 300 - }); - return that; - }, - accountWelcomeDialog: function() { - var that = new Ox.Dialog({ - buttons: [ - [ - new Ox.Button({ - id: 'preferences', - title: 'Preferences...' - }).bindEvent('click', function() { - that.close(); - }) - ], - [ - new Ox.Button({ - id: 'close', - title: 'Close' - }).bindEvent('click', function() { - that.close(); - }) - ] - ], - content: new Ox.Element('div').html('Welcome, ' + app.user.username + '!

Your account has been created.'), - height: 160, - keys: {enter: 'close', escape: 'close'}, - title: 'Welcome to ' + app.config.site.name, - width: 300 - }); - return that; - } - } - -//FIXME: move these somewhere. -function autovalidateCode(value, blur, callback) { - value = $.map(value.toUpperCase().split(''), function(v) { - return /[0-9A-Z]/(v) ? v : null; - }).join(''); - callback(value); -} - -function autovalidateEmail(value, blur, callback) { - value = $.map(value.toLowerCase().split(''), function(v, i) { - return /[0-9a-z\.\+\-_@]/(v) ? v : null; - }).join(''); - callback(value); -} - -function autovalidateUsername(value, blur, callback) { - var length = value.length; - value = $.map(value.toLowerCase().split(''), function(v, i) { - if (new RegExp('[0-9a-z' + ((i == 0 || (i == length - 1 && blur)) ? '' : '\-_') + ']')(v)) { - return v - } else { - return null; - } - }).join(''); - $.each(['--', '-_', '_-', '__'], function(i, v) { - while (value.indexOf(v) > -1) { - value = value.replace(new RegExp(v, 'g'), v[0]); - } - }) - callback(value); -} - -function validateUser(key, existing) { - existing = existing || false; - var string = key == 'username' ? 'username' : 'e-mail address'; - return function(value, callback) { - var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value); - valid ? pandora.api.findUser({ - key: key, - value: value, - operator: '=' - }, function(result) { - var valid = existing == !!result.data.users.length; - Ox.print(existing, result.data.users) - callback({ - message: existing ? - 'Unknown ' + string : - string[0].toUpperCase() + string.substr(1) + ' already exists', - valid: valid - }); - }) : callback({ - message: (!value.length ? 'Missing' : 'Invalid') + ' ' + string, - valid: false - }); - }; -} - diff --git a/itf/static/js/itf/query.js b/itf/static/js/itf/query.js new file mode 100644 index 0000000..b6d341f --- /dev/null +++ b/itf/static/js/itf/query.js @@ -0,0 +1,137 @@ +app.Query = (function() { + + function constructFind(query) { + Ox.print('cF', query) + return /*encodeURI(*/$.map(query.conditions, function(v, i) { + if (!Ox.isUndefined(v.conditions)) { + return '[' + constructFind(v) + ']'; + } else { + return v.value !== '' ? v.key + (v.key ? ':' : '') + constructValue(v.value, v.operator) : null; + } + }).join(query.operator)/*)*/; + } + + function constructValue(value, operator) { + operator = operator.replace('=', '^$'); + if (operator.indexOf('$') > -1) { + value = operator.substr(0, operator.length - 1) + value + '$' + } else { + value = operator + value; + } + return value; + } + + function mergeFind() { + } + + function parseFind(str) { + var find = { + conditions: [], + operator: '' + }, + subconditions = str.match(/\[.*?\]/g) || []; + $.each(subconditions, function(i, v) { + subconditions[i] = v.substr(1, v.length - 2); + str = str.replace(v, '[' + i + ']'); + }); + if (str.indexOf(',') > -1) { + find.operator = '&'; + } else if (str.indexOf('|') > -1) { + find.operator = '|'; + } + Ox.print('pF', str, find.operator) + find.conditions = $.map(find.operator === '' ? [str] : str.split(find.operator == '&' ? ',' : '|'), function(v, i) { + Ox.print('v', v) + var ret, kv; + if (v[0] == '[') { + Ox.print('recursion', subconditions) + ret = parseFind(subconditions[parseInt(v.substr(1, v.length - 2))]); + } else { + kv = ((v.indexOf(':') > - 1 ? '' : ':') + v).split(':'); + ret = $.extend({ + key: kv[0] + }, parseValue(kv[1])); + } + return ret; + }); + return find; + } + + function parseValue(str) { + var value = { + value: decodeURI(str), + operator: '' + }; + if (value.value[0] == '!') { + value.operator = '!' + value.value = value.value.substr(1); + } + if ('^<>'.indexOf(value.value[0]) > -1) { + value.operator += value.value[0]; + value.value = value.value.substr(1); + } + if (value.value.substr(-1) == '$') { + value.operator += '$'; + value.value = value.value.substr(0, value.value.length - 1); + } + value.operator = value.operator.replace('^$', '='); + return value; + } + + return { + + fromString: function(str) { + var query = Ox.unserialize(str), + sort = []; + if ('find' in query) { + app.user.ui.findQuery = parseFind(query.find); + Ox.print('user.ui.findQuery', app.user.ui.findQuery) + } + if ('sort' in query) { + sort = query.sort.split(',') + app.user.ui.sort = $.map(query.sort.split(','), function(v, i) { + var hasOperator = '+-'.indexOf(v[0]) > -1, + key = hasOperator ? query.sort.substr(1) : query.sort, + operator = hasOperator ? v[0].replace('+', '') : Ox.getObjectById(app.config.sortKeys, key).operator; + return { + key: key, + operator: operator + }; + }); + } + if ('view' in query) { + app.user.ui.listView = query.view; + } + }, + + toObject: function(groupId) { + Ox.print('tO', app.user.ui.findQuery.conditions) + // the inner $.merge() creates a clone + var conditions = $.merge($.merge([], app.user.ui.listQuery.conditions), app.user.ui.findQuery.conditions); + $.merge(conditions, app.ui.groups ? $.map(app.ui.groups, function(v, i) { + if (v.id != groupId && v.query.conditions.length) { + return v.query.conditions.length == 1 ? + v.query.conditions : v.query; + } + }) : []), + operator = conditions.length < 2 ? '' : ','; // fixme: should be & + Ox.print('>>', groupId, app.user.ui.find, conditions); + return { + conditions: conditions, + operator: operator + }; + }, + + toString: function() { + Ox.print('tS', app.user.ui.find) + return Ox.serialize({ + find: constructFind(app.Query.toObject()), + sort: app.user.ui.sort[0].operator + app.user.ui.sort[0].key, + view: app.user.ui.listView + }); + } + + }; + +})(); + diff --git a/itf/static/js/itf/widgets.js b/itf/static/js/itf/widgets.js new file mode 100644 index 0000000..8ab6757 --- /dev/null +++ b/itf/static/js/itf/widgets.js @@ -0,0 +1,305 @@ + +Ox.ItfBox = function(options, self) { + var self = self || {}; + var that = new Ox.Element(options, self) + .defaults({ + 'title': '', + 'extraButtons': [] + }) + .options(options); + var title = self.options.title; + var $titlebar = new Ox.Bar({ + orientation: 'horizontal', + size: 18 + }) +// .dblclick(dblclickTitlebar) + .appendTo(that); + + + var $title = new Ox.Element() + .addClass('OxTitle') + .html(title/*.toUpperCase()*/) + .appendTo($titlebar); + + + var $search = new Ox.Input({ + 'placeholder': 'Search', + }) + .css({'width': '128px', 'marginLeft': 'auto', 'marginRight': 'auto'}) + .appendTo(that) + .hide() + .bindEvent("submit", function(value) { + app.$ui[options.boxId].$loading.start(); + $list.options("request", function(data, callback) { + app.$ui[options.boxId].$loading.stop(); + return app.api.find(getQueryParams(data), callback); + }); + }); + + + that.search = function(word) { + $search.options("value", word); + $search.triggerEvent("submit"); + } + + var $buttons = new Ox.Element().appendTo($title).css({'position': 'absolute', 'top': '1px', 'right': '1px'}); + + + + var $additionalButtons = self.options.extraButtons; + if ($additionalButtons.length > 0) { + $additionalButtons.appendTo($buttons); + } + var $infoBtn = new Ox.Button({ + id: options.id + "InfoBtn", + style: 'symbold', + title: 'info', + type: 'image', + tooltip: 'More info about ' + options.title + }) + .appendTo($buttons) + .bindEvent("click", function() { + var info = options.info; + var d = new Ox.Dialog({ + buttons: [ + new Ox.Button({ + id: 'cancel', + title: 'Close', + }) + .bindEvent("click", function() { d.close(); }) + ], + content: new Ox.Element().html(info), + title: options.title + }) + .open(); + }); + + var $searchBtn = new Ox.Button({ + id: options.id + 'SearchBtn', + style: 'symbol', + title: 'find', + type: 'image', + tooltip: 'Search' + }) + .bindEvent("click", function() { + if ($search.is(":visible")) { + $search.slideUp(); + } else { + $search.slideDown(); + $search.focus(); + } + }) + .appendTo($buttons); + + + var $menuBtn = new Ox.Button({ + id: options.id + 'MenuBtn', + style: 'symbol', + title: 'collapse', + type: 'image', + tooltip: 'Show Menu' + }).appendTo($buttons); + + that.$loading = new Ox.LoadingIcon().appendTo($buttons); + + var $menu = new Ox.Menu({ + id: options.id + 'Menu', + element: $menuBtn, + items: [ + { + id: 'SortBy', + title: 'Sort By', + items: [ + { + 'group': 'sortGroup', + 'min': 1, + 'max': 1, + items: [ + {'id': 'sort_added_descending', title: 'Added (Descending)', checked: true}, + {'id': 'sort_added_ascending', title: 'Added (Ascending)'}, + {'id': 'sort_title_ascending', title: 'Title (Ascending)'}, + {'id': 'sort_title_descending', title: 'Title (Descending)'}, + ] + } + ] + }, + {id: 'Test2', title: 'Menu Item 2'} + ] + }) + .bindEvent("change", function(e, data) { + if (data.id === 'sortGroup') { + var checked = data.checked[0]; + var checkedId = checked.id; + var checkedField = checkedId.split("_")[1]; + var operator = checkedId.split("_")[2] == "ascending" ? "+" : "-"; + $list.sortList(checkedField, operator); + } + }); + +// var $menu = new Ox.Menu({ +// id: options.id + 'Menu', +// element: $menuBtn, +// items: [ +// { +// 'group': 'sortGroup', +// 'min': 1, +// 'max': 1, +// items: [ +// {'id': 'sortTitleAscending', title: 'Title (Ascending)', checked: true}, +// {'id': 'sortTitleDescending', title: 'Title (Descending)'}, +// {'id': 'sortTitleAscendingFoo', title: 'Title (Ascending)'}, +// {'id': 'sortTitleDescendingFoo', title: 'Title (Descending)'}, +// ] +// } +// ] +// }, +// {id: 'Test2', title: 'Menu Item 2'} +// ] +// }) +// .bindEvent("change", function() { +// alert("foo"); +// }); + +// + + $menuBtn.bindEvent("click", function() { + $menu.showMenu(); + }); + + function getQueryParams(data) { +// Ox.print("SEARCHVAL", $search.val()); + return $.extend(data, { + 'search': $search.value() == 'Search' ? '' : $search.value(), + 'model': options.model, + 'module': options.module + }); + } + + var $listContainer = new Ox.Element() + .appendTo(that) + .css({position: 'relative', height: '100%'}); + + var listOptions = $.extend(options, { + 'width': 256, +// 'itemHeight': 16, +// 'itemWidth': 250, +// 'orientation': 'horizontal', + 'request': function(data, callback) { + return app.api.find(getQueryParams(data), callback) + }, + 'id': options.id + 'List', + 'boxId': options.id, + + +/* + 'construct': function(data) { + var $a = $('
').attr("href", "/" + options.module.toLowerCase() + "/" + data.id).text(data.title); + var $item = $('
').addClass('OxTarget').append($a); + return $item; + }, +*/ + 'max': 1, + 'columns': [ + { + align: 'left', + id: 'title', + operator: '-', + unique: false, + visible: true, + width: 230 + }, + { + id: 'id', + visible: false, + unique: true + } + ], + 'sort': [ + { + key: 'added', + operator: '-' + } + ] + }); + + var $list = that.$list = new Ox.ItfList(listOptions) + .appendTo($listContainer); + + return that; +} + + + + +Ox.ItfList = function(options, self) { + var self = self || {}; + var that = new Ox.TextList(options, self); + that.bindEvent("select", function(e, data) { + if (data.ids.length === 0) { + app.$ui.previewBox.$content.html(''); + return; + } + app.$ui[options.boxId].$loading.start(); +// debugger; + app.api.preview({ + model: options.model, + module: options.module, + id: data.ids[0] + }, function(response) { +// alert(JSON.stringify(response.data.data)); + app.$ui[options.boxId].$loading.stop(); + var html = $.tmpl(response['template'], response['data']); + app.$ui.previewBox.$content.html(html); + }); + }); + that.bindEvent("open", function(e, data) { +// alert(JSON.stringify(data)); + app.$ui[options.boxId].$loading.start(); + app.api.info({ + model: options.model, + module: options.module, + id: data.ids[0] + }, function(response) { + app.$ui[options.boxId].$loading.stop(); + var html = $.tmpl(response['template'], response['data']); +// alert(html); + var d = new Ox.Dialog({ + buttons: [ + new Ox.Button({ + id: 'cancel', + title: 'Close', + }) + .bindEvent("click", function() { d.close(); }) + ], + content: new Ox.Element().append(html), + title: options.title + ": " + response.data.title, + width: 800, + height: 500 + }) + .open(); +// alert(response); + }); + }); + return that; +} + +Ox.ItfCalendar = function(options, self) { + var self = self || {}; + var that = new Ox.Element(options, self); + var $titleBar = new Ox.Bar({ + 'size': 'small' + }).addClass('OxTitleBar').appendTo(that); + var $title = new Ox.Element().html("Calendar").appendTo($titleBar); + return that; +} + +Ox.ItfPreview = function(options, self) { + var self = self || {}; + var that = new Ox.Element(options, self); + that.$content = new Ox.Element().appendTo(that); + that.$loading = new Ox.LoadingIcon().appendTo(that); + return that; +} + +ITF.templates = {}; + diff --git a/itf/templates/index.html b/itf/templates/index.html index ac3a2fc..1d81f81 100755 --- a/itf/templates/index.html +++ b/itf/templates/index.html @@ -19,6 +19,11 @@ if(typeof(console)=='undefined') { + + + + +