restructured js/itf folder to separate files

This commit is contained in:
sanj 2011-01-19 13:35:08 +05:30
parent a801b585f1
commit d2a6374551
9 changed files with 1529 additions and 1488 deletions

View File

@ -55,7 +55,13 @@ def api_api(request):
actions = globals().keys() actions = globals().keys()
actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions)) actions = map(lambda a: a[4:], filter(lambda a: a.startswith('api_'), actions))
actions.sort() 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): def api_apidoc(request):
''' '''

View File

@ -7,6 +7,7 @@ class BestPractice(ItfModel):
title = models.CharField(max_length=512) title = models.CharField(max_length=512)
story = models.TextField() story = models.TextField()
guideline = models.TextField(blank=True) guideline = models.TextField(blank=True)
guidelines = models.ManyToManyField("Guideline", null=True, blank=True)
law = models.TextField(blank=True) law = models.TextField(blank=True)
theatre = models.TextField(blank=True, help_text="Spotlight on Theatre text") theatre = models.TextField(blank=True, help_text="Spotlight on Theatre text")
quick_howto = models.TextField(blank=True) quick_howto = models.TextField(blank=True)
@ -75,3 +76,17 @@ class BestPracticeImage(models.Model):
def __unicode__(self): def __unicode__(self):
return self.caption 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

41
itf/static/js/itf/app.js Normal file
View File

@ -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);
});

View File

@ -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
*/
}

456
itf/static/js/itf/forms.js Normal file
View File

@ -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] + '<br/><br/>')
)
.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 + '!<br/><br/>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
});
};
}

File diff suppressed because it is too large Load Diff

137
itf/static/js/itf/query.js Normal file
View File

@ -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
});
}
};
})();

View File

@ -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 = $('<a />').attr("href", "/" + options.module.toLowerCase() + "/" + data.id).text(data.title);
var $item = $('<div />').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 = {};

View File

@ -19,6 +19,11 @@ if(typeof(console)=='undefined') {
<script type="text/javascript" src="/static/oxjs/build/js/ox.js"></script> <script type="text/javascript" src="/static/oxjs/build/js/ox.js"></script>
<script type="text/javascript" src="/static/oxjs/build/js/ox.ui.js"></script> <script type="text/javascript" src="/static/oxjs/build/js/ox.ui.js"></script>
<script type="text/javascript" src="/static/js/itf/itf.js"></script> <script type="text/javascript" src="/static/js/itf/itf.js"></script>
<script type="text/javascript" src="/static/js/itf/app.js"></script>
<script type="text/javascript" src="/static/js/itf/query.js"></script>
<script type="text/javascript" src="/static/js/itf/construct.js"></script>
<script type="text/javascript" src="/static/js/itf/widgets.js"></script>
<script type="text/javascript" src="/static/js/itf/forms.js"></script>
<script type="text/javascript" src="/static/js/bookmyshow.js"></script> <script type="text/javascript" src="/static/js/bookmyshow.js"></script>
</head> </head>
<body></body> <body></body>