From a801b585f1029af128c6300069c9134ffcebebcb Mon Sep 17 00:00:00 2001 From: sanj Date: Fri, 14 Jan 2011 17:39:03 +0530 Subject: [PATCH] mockup of register / login --- itf/static/js/itf/itf.js | 520 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 517 insertions(+), 3 deletions(-) diff --git a/itf/static/js/itf/itf.js b/itf/static/js/itf/itf.js index 4f702e2..1627bc0 100644 --- a/itf/static/js/itf/itf.js +++ b/itf/static/js/itf/itf.js @@ -192,6 +192,48 @@ app.Query = (function() { })(); +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: @@ -662,7 +704,61 @@ BEGIN mainPanel var c = app.$ui[id] = new Ox.Element({ id: id }); - c.html("login goes here"); + + 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; }, @@ -748,9 +844,9 @@ Ox.ItfBox = function(options, self) { $search.triggerEvent("submit"); } - var $buttons = new Ox.Element().appendTo($title).css({'position': 'absolute', 'top': '1px', 'right': '16px'}); + var $buttons = new Ox.Element().appendTo($title).css({'position': 'absolute', 'top': '1px', 'right': '1px'}); + - that.$loading = new Ox.LoadingIcon().appendTo($buttons); var $additionalButtons = self.options.extraButtons; if ($additionalButtons.length > 0) { @@ -806,6 +902,8 @@ Ox.ItfBox = function(options, self) { tooltip: 'Show Menu' }).appendTo($buttons); + that.$loading = new Ox.LoadingIcon().appendTo($buttons); + var $menu = new Ox.Menu({ id: options.id + 'Menu', element: $menuBtn, @@ -1004,3 +1102,419 @@ Ox.ItfPreview = function(options, self) { 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 + }); + }; +} +