auto generate forms

This commit is contained in:
Sanj 2011-02-01 20:43:30 +05:30
parent e416b308cd
commit 1fd9684064
13 changed files with 413 additions and 105 deletions

View File

@ -17,14 +17,17 @@ from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
from django.template import RequestContext from django.template import RequestContext
from django.conf import settings from django.conf import settings
from django.contrib.comments.forms import CommentForm
from django.contrib.comments.models import Comment
from django.contrib.comments.signals import comment_will_be_posted, comment_was_posted
from django.contrib.contenttypes.models import ContentType
from ox.utils import json from ox.utils import json
from ox.django.decorators import login_required_json from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from ox.django.http import HttpFileResponse from ox.django.http import HttpFileResponse
import ox import ox
from actions import actions from actions import actions
from user.models import get_user_json
def api(request): def api(request):
if request.META['REQUEST_METHOD'] == "OPTIONS": if request.META['REQUEST_METHOD'] == "OPTIONS":
@ -84,11 +87,7 @@ def api(request):
# return render_to_json_response(json_response({'actions': docs})) # return render_to_json_response(json_response({'actions': docs}))
#FIXME: REMOVE THIS FUNCTION WHEN THERE ARE REAL USERS!!!! def init(request):
def get_user_json(u):
return {'name': 'Guest', 'group': 'guest', 'preferences': {}}
def hello(request):
''' '''
return {'status': {'code': int, 'text': string}, return {'status': {'code': int, 'text': string},
'data': {user: object}} 'data': {user: object}}
@ -98,9 +97,15 @@ def hello(request):
if request.user.is_authenticated(): if request.user.is_authenticated():
response['data']['user'] = get_user_json(request.user) response['data']['user'] = get_user_json(request.user)
else: else:
response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'preferences': {}} response['data']['user'] = {'name': 'Guest', 'group': 'guest', 'level': 'guest', 'preferences': {}}
#FIXME: Get config definition out of here.
response['data']['config'] = {
'site': {
'name': 'India Theatre Forum'
}
}
return render_to_json_response(response) return render_to_json_response(response)
actions.register(hello) actions.register(init)
def error(request): def error(request):
''' '''
@ -157,17 +162,159 @@ actions.register(preview)
#FIXME: Generalize based on these two functions being the same. #FIXME: Generalize based on these two functions being the same.
def info(request): def info(request):
'''
id: object id
model: string, name of model
module: string, name of module
'''
data = json.loads(request.POST['data']) data = json.loads(request.POST['data'])
id = int(data['id']) id = int(data['id'])
model = getModel(data) model = getModel(data)
response = json_response({}) response = json_response({})
response['status'] = {'code': 200} response['status'] = {'code': 200}
obj = get_object_or_404(model, pk=id) obj = get_object_or_404(model, pk=id)
if model.hasComments:
response['commentForm'] = _get_comment_form_initial(request, obj)
response['comments'] = _get_comments(obj)
response['data'] = obj.info_dict() response['data'] = obj.info_dict()
response['template'] = getTemplate(data, "info") response['template'] = getTemplate(data, "info")
return render_to_json_response(response) return render_to_json_response(response)
actions.register(info) actions.register(info)
#obj: Django model instance - object for which to get comment form for.
#Returns dict with content_type, object_id, security_hash, etc.
#FIXME: put comments stuff somewhere
def _get_comment_form_initial(request, obj):
c = CommentForm(obj)
return c.initial
def _get_comments(obj):
ret = []
content_type = ContentType.objects.get_for_model(obj)
object_id = obj.id
qset = Comment.objects.filter(content_type=content_type, object_pk=object_id)
for q in qset:
ret.append({
'name': q.name,
# 'date': q.submit_date,
'comment': q.comment
})
return ret
@login_required_json
def addComment(request):
'''
id
module
model
comment
content_type
email
name
object_pk
security_hash
timestamp
'''
data = json.loads(request.POST['data'])
data.update({
'name': request.user.username,
'email': request.user.email
})
id = int(data['object_pk'])
model = getModel(data)
obj = get_object_or_404_json(model, pk=id)
cf = CommentForm(obj, data=data)
ret = json_response({})
if cf.is_valid():
comment = cf.get_comment_object()
comment.user = request.user
# Signal that the comment is about to be saved
responses = comment_will_be_posted.send(
sender = comment.__class__,
comment = comment,
request = request
)
for (receiver, response) in responses:
if response == False:
return CommentPostBadRequest(
"comment_will_be_posted receiver %r killed the comment" % receiver.__name__)
# Save the comment and signal that it was saved
comment.save()
comment_was_posted.send(
sender = comment.__class__,
comment = comment,
request = request
)
ret['data'] = {
id: comment.id
}
ret['status'] = {'code': 200}
else:
ret['status'] = {'code': 200}
ret['errors'] = cf.errors
return render_to_json_response(ret)
actions.register(addComment)
widgetMap = {
'TextInput': 'text',
'Textarea': 'textarea',
'Select': 'select'
}
def getAddItemForm(request):
response = json_response({})
data = json.loads(request.POST['data'])
model = getModel(data)
# import pdb; pdb.set_trace()
form = getForm(data)
form_fields = []
for field in form.base_fields:
name = field
this = form.base_fields[field]
widget = this.widget
widgetClassName = type(widget).__name__
if hasattr(widget, "choices"):
choices = []
for c in widget.choices:
choices.append({
'id': c[0],
'title': c[1]
})
else:
choices = False
js_widget = widgetMap.get(widgetClassName, "text")
form_fields.append({
'name': name,
'widget': js_widget,
'label': this.label,
'choices': choices
})
response['data']['form'] = form_fields
return render_to_json_response(response)
actions.register(getAddItemForm)
def addItem(request):
response = json_response({})
data = json.loads(request.POST['data'])
model = getModel(data)
form = getForm(data)
if form.is_valid():
m = model()
for field in form.base_fields:
m.__setattr__(field, form.cleaned_data[field])
m.save()
response['data'] = {'id': m.id}
else:
response['errors'] = form.errors
return render_to_json_response(response)
actions.register(addItem)
def getTemplate(data, tmpl_name): def getTemplate(data, tmpl_name):
path = join(settings.PROJECT_PATH, "templates", data['module'], data['model'], tmpl_name + ".html") path = join(settings.PROJECT_PATH, "templates", data['module'], data['model'], tmpl_name + ".html")
@ -177,6 +324,14 @@ def getModel(data):
module = __import__(data['module']) module = __import__(data['module'])
return module.models.__getattribute__(data['model']) return module.models.__getattribute__(data['model'])
#FIXME: BAAD Hack
def getForm(data):
module = __import__(data['module'] + ".forms")
model = getModel(data)
formStr = model.add_form
return module.forms.__getattribute__(formStr)
def get_api_doc(f): def get_api_doc(f):
f = 'api_' + f f = 'api_' + f

View File

@ -15,6 +15,7 @@ class ItfModel(models.Model):
fts_fields = [] fts_fields = []
fk_filters = [] fk_filters = []
sort_fields = [] sort_fields = []
hasComments = True
class Meta: class Meta:
abstract = True abstract = True
@ -110,3 +111,16 @@ def getField(fields, name):
return f return f
return False return False
def site_config():
with open(settings.SITE_CONFIG) as f:
site_config = json.load(f)
site_config['keys'] = {}
for key in site_config['itemKeys']:
site_config['keys'][key['id']] = key
site_config['_findKeys'] = {}
for key in site_config['findKeys']:
site_config['_findKeys'][key['id']] = key
return site_config

View File

@ -13,6 +13,8 @@ def index(request):
return html_snapshot(request) return html_snapshot(request)
return render_to_response('index.html', context) return render_to_response('index.html', context)
'''
def site_json(request): def site_json(request):
data = { data = {
'site': { 'site': {
@ -20,4 +22,4 @@ def site_json(request):
} }
} }
return render_to_json_response(data) return render_to_json_response(data)
'''

View File

@ -0,0 +1,7 @@
from django.forms import ModelForm
from models import BestPractice
class BestPracticeForm(ModelForm):
class Meta:
model = BestPractice

View File

@ -2,6 +2,8 @@ from django.db import models
from tagging.fields import TagField from tagging.fields import TagField
from django.core.paginator import Paginator, InvalidPage, EmptyPage from django.core.paginator import Paginator, InvalidPage, EmptyPage
from app.models import ItfModel from app.models import ItfModel
# from django.forms import
# import forms
class BestPractice(ItfModel): class BestPractice(ItfModel):
title = models.CharField(max_length=512) title = models.CharField(max_length=512)
@ -12,13 +14,14 @@ class BestPractice(ItfModel):
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)
tags = TagField(blank=True, help_text="Enter as many tags as you like, separated by commas.") tags = TagField(blank=True, help_text="Enter as many tags as you like, separated by commas.")
category = models.ForeignKey("BestPracticeCategory") category = models.ForeignKey("BestPracticeCategory", null=True)
added = models.DateTimeField(auto_now_add=True, null=True) added = models.DateTimeField(auto_now_add=True, null=True)
modified = models.DateTimeField(auto_now=True, null=True) modified = models.DateTimeField(auto_now=True, null=True)
fts_fields = ['title', 'story', 'guideline', 'law', 'theatre', 'quick_howto'] fts_fields = ['title', 'story', 'guideline', 'law', 'theatre', 'quick_howto']
fk_filters = ['category'] fk_filters = ['category']
sort_fields = ['title'] sort_fields = ['title']
add_form = "BestPracticeForm"
def __unicode__(self): def __unicode__(self):
return str(self.id) + ": " + self.title return str(self.id) + ": " + self.title
@ -103,3 +106,7 @@ class Glossary(models.Model):
def __unicode__(self): def __unicode__(self):
return self.term return self.term

View File

@ -16,6 +16,7 @@ LOGGING_OUTPUT_ENABLED = True
PROJECT_PATH = os.path.dirname(__file__) PROJECT_PATH = os.path.dirname(__file__)
PROJECT_ROOT = PROJECT_PATH PROJECT_ROOT = PROJECT_PATH
SITE_CONFIG = join(PROJECT_ROOT, 'itf.json')
CKEDITOR_MEDIA_PREFIX = "/static/ckeditor/" CKEDITOR_MEDIA_PREFIX = "/static/ckeditor/"
CKEDITOR_UPLOAD_PATH = join(PROJECT_PATH, "static/upload/images/") CKEDITOR_UPLOAD_PATH = join(PROJECT_PATH, "static/upload/images/")
@ -137,6 +138,7 @@ INSTALLED_APPS = (
'debug_toolbar', 'debug_toolbar',
'sorl.thumbnail', 'sorl.thumbnail',
'south', 'south',
'user',
'ckeditor', 'ckeditor',
) )

View File

@ -10,3 +10,11 @@
.itfPreviewTitle { .itfPreviewTitle {
font-weight: bold; font-weight: bold;
} }
.OxCommentWrapper {
margin-bottom: 4px;
}
.OxCommentsWrapper {
margin-top: 6px;
}

View File

@ -1,21 +1,16 @@
var app = new Ox.App({ var app = new Ox.App({
apiURL: '/api/', apiURL: '/api/',
init: 'hello', init: 'init',
config: 'site.json' //FIXME: shouldn't need this, get data with 'hello' or 'init'. 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) { app.launch(function(data) {
Ox.theme("classic"); Ox.theme("classic");
Ox.print(data); Ox.print(data);
app.$body = $('body'); app.$body = $('body');
app.$document = $(document); app.$document = $(document);
app.$window = $(window); app.$window = $(window);
app.$window.resize(function() { app.$window.resize(function() {
ITF.setSizes(); ITF.setSizes();
}); });
@ -37,6 +32,10 @@ app.launch(function(data) {
*/ */
var wrapper = app.construct.wrapper(); var wrapper = app.construct.wrapper();
app.$body.css({'opacity': 0}); app.$body.css({'opacity': 0});
//FIXME: user handling should be cleaner?
if (data.user.level != 'guest') {
ITF.login(data);
}
wrapper.appendTo(app.$body); wrapper.appendTo(app.$body);
ITF.setSizes(); ITF.setSizes();
app.$body.animate({ app.$body.animate({

View File

@ -472,9 +472,12 @@ BEGIN mainPanel
id: id id: id
}); });
var btnsWrapper = new Ox.Element().css({'textAlign': 'center', 'marginTop': '4px'});
var loginBtn = new Ox.Button({ var btnsWrapper = c.$btns = new Ox.Element().css({'textAlign': 'center', 'marginTop': '4px'});
var info = c.$info = new Ox.Element("span").appendTo(btnsWrapper);
var loginBtn = c.$loginBtn = new Ox.Button({
'id': 'loginBtn', 'id': 'loginBtn',
'title': 'Login', 'title': 'Login',
'size': 'large' 'size': 'large'
@ -482,7 +485,7 @@ BEGIN mainPanel
ui.accountDialog("login").open(); ui.accountDialog("login").open();
}).appendTo(btnsWrapper); }).appendTo(btnsWrapper);
var registerBtn = new Ox.Button({ var registerBtn = c.$registerBtn = new Ox.Button({
'id': 'registerBtn', 'id': 'registerBtn',
'title': 'Register', 'title': 'Register',
'size': 'large' 'size': 'large'
@ -490,62 +493,18 @@ BEGIN mainPanel
ui.accountDialog("register").open(); ui.accountDialog("register").open();
}).appendTo(btnsWrapper); }).appendTo(btnsWrapper);
btnsWrapper.appendTo(c); var logoutBtn = c.$logoutBtn = new Ox.Button({
/* 'id': 'logoutBtn',
var registerForm = (function() { 'title': 'Logout',
var u = ui.accountDialogOptions('register'); 'size': 'large'
var btns = u.buttons; }).bindEvent("click", function() {
var content = u.content; app.api.logout({}, function(data) {
var title = u.title; ui.accountLogoutDialog().open();
// 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); }).appendTo(btnsWrapper).hide();
btnsWrapper.appendTo(e);
return e;
})();
*/
// registerForm.appendTo(c);
/* btnsWrapper.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; return c;
}, },

View File

@ -1,6 +1,6 @@
/*
var $registerFormItems = (function() { var $registerFormItems = (function() {
var $username = new Ox.Input({ var $username = new Ox.Input({
'id': 'registerUsername', 'id': 'registerUsername',
@ -41,9 +41,14 @@ var $registerFormItems = (function() {
return [$username, $password, $email] return [$username, $password, $email]
})(); })();
*/
(function() {
var ui = { //FIXME: creating global for ui. This doesn't sound healthy.
ui = {
accountDialog: function(action) { accountDialog: function(action) {
var that = app.$ui.accountDialog = new Ox.Dialog($.extend({ var that = app.$ui.accountDialog = new Ox.Dialog($.extend({
height: 256, height: 256,
@ -152,7 +157,7 @@ var $registerFormItems = (function() {
}); });
} }
var items = { var items = {
'login': ['username', 'password'], 'login': ['usernameOrEmail', 'password'],
'register': ['newUsername', 'password', 'email'], 'register': ['newUsername', 'password', 'email'],
'reset': ['usernameOrEmail'], 'reset': ['usernameOrEmail'],
'resetAndLogin': ['oldUsername', 'newPassword', 'code'] 'resetAndLogin': ['oldUsername', 'newPassword', 'code']
@ -165,19 +170,19 @@ var $registerFormItems = (function() {
items: $items, items: $items,
submit: function(data, callback) { submit: function(data, callback) {
if (action == 'login') { if (action == 'login') {
pandora.api.login(data, function(result) { app.api.login(data, function(result) {
if (!result.data.errors) { if (!result.data.errors) {
app.$ui.accountDialog.close(); app.$ui.accountDialog.close();
login(result.data); ITF.login(result.data);
} else { } else {
callback([{id: 'password', message: 'Incorrect password'}]); callback([{id: 'password', message: 'Incorrect password'}]);
} }
}); });
} else if (action == 'register') { } else if (action == 'register') {
pandora.api.register(data, function(result) { app.api.register(data, function(result) {
if (!result.data.errors) { if (!result.data.errors) {
app.$ui.accountDialog.close(); app.$ui.accountDialog.close();
login(result.data); ITF.login(result.data);
ui.accountWelcomeDialog().open(); ui.accountWelcomeDialog().open();
} else { } else {
callback([{id: 'password', message: result.data.errors.toString()}]); // fixme callback([{id: 'password', message: result.data.errors.toString()}]); // fixme
@ -188,7 +193,7 @@ var $registerFormItems = (function() {
key = usernameOrEmail[0].id; key = usernameOrEmail[0].id;
data = {}; data = {};
data[key] = usernameOrEmail[1]; data[key] = usernameOrEmail[1];
pandora.api.requestToken(data, function(result) { app.api.requestToken(data, function(result) {
if (!result.data.errors) { if (!result.data.errors) {
app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username)); app.$ui.accountDialog.options(ui.accountDialogOptions('resetAndLogin', result.data.username));
} else { } else {
@ -196,10 +201,10 @@ var $registerFormItems = (function() {
} }
}); });
} else if (action == 'resetAndLogin') { } else if (action == 'resetAndLogin') {
pandora.api.resetPassword(data, function(result) { app.api.resetPassword(data, function(result) {
if (!result.data.errors) { if (!result.data.errors) {
app.$ui.accountDialog.close(); app.$ui.accountDialog.close();
login(result.data); ITF.login(result.data);
} else { } else {
callback([{id: 'code', message: 'Incorrect code'}]); callback([{id: 'code', message: 'Incorrect code'}]);
} }
@ -353,8 +358,8 @@ var $registerFormItems = (function() {
title: 'Logout' title: 'Logout'
}).bindEvent('click', function() { }).bindEvent('click', function() {
that.close(); that.close();
pandora.api.logout({}, function(result) { app.api.logout({}, function(result) {
logout(result.data); ITF.logout(result.data);
}); });
}) })
], ],
@ -433,7 +438,7 @@ function validateUser(key, existing) {
var string = key == 'username' ? 'username' : 'e-mail address'; var string = key == 'username' ? 'username' : 'e-mail address';
return function(value, callback) { return function(value, callback) {
var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value); var valid = key == 'username' ? !!value.length : Ox.isValidEmail(value);
valid ? pandora.api.findUser({ valid ? app.api.findUser({
key: key, key: key,
value: value, value: value,
operator: '=' operator: '='
@ -453,4 +458,4 @@ function validateUser(key, existing) {
}; };
} }
})();

View File

@ -1,6 +1,31 @@
var ITF = {}; var ITF = {};
ITF.login = function(data) {
app.user = data.user;
var box = app.$ui.loginBox;
box.slideUp("slow", function() {
box.$loginBtn.hide();
box.$registerBtn.hide();
box.$info.html("logged in as " + data.user.username + " ");
box.$logoutBtn.show();
box.slideDown();
});
}
ITF.logout = function(data) {
app.user = data.user;
var box = app.$ui.loginBox;
box.slideUp("slow", function() {
box.$logoutBtn.hide();
box.$info.html('');
box.$loginBtn.show();
box.$registerBtn.show();
box.slideDown();
});
// alert("logged out");
}
ITF.setSizes = function() { ITF.setSizes = function() {
var mp = app.$ui.middlePanel; var mp = app.$ui.middlePanel;
var winHeight = parseInt(mp.height()); var winHeight = parseInt(mp.height());
@ -18,6 +43,10 @@ ITF.setSizes = function() {
mmp.size(2, panelWidth); mmp.size(2, panelWidth);
mbp.size(0, panelWidth); mbp.size(0, panelWidth);
mbp.size(2, panelWidth); mbp.size(2, panelWidth);
//FIXME: FIX!
var listHeight = panelHeight - 22;
app.$ui.bestpracticesBox.$listContainer.css({'height': listHeight + "px"});
} }

View File

@ -51,13 +51,81 @@ Ox.ItfBox = function(options, self) {
$additionalButtons.appendTo($buttons); $additionalButtons.appendTo($buttons);
} }
var $maximizeBtn = new Ox.Button({ var $addBtn = new Ox.Button({
id: options.id + "Maximize", id: options.id + "AddItem",
style: 'symbol', style: 'symbol',
title: 'add', title: 'add',
type: 'image', type: 'image',
tooltip: 'Maximize' tooltip: 'Add'
}).appendTo($buttons); })
.appendTo($buttons)
.bindEvent("click", function() {
app.$ui[options.boxId].$loading.start();
app.api.getAddItemForm({
'module': that.options("module"),
'model': that.options("model")
}, function(response) {
app.$ui[options.boxId].$loading.stop();
var form = response.data.form;
var $content = new Ox.Element();
var $items = [];
for (var i=0; i<form.length; i++) {
var field = form[i];
switch (field.widget) {
case 'select':
// alert(field.label);
var $input = new Ox.Select({
'items': field.choices,
'label': field.label,
'id': field.name,
'width': 256
});
// $items.push($input);
break;
default:
// alert("default: " + field.label);
var $input = new Ox.Input({
'type': field.widget,
'id': field.name,
'label': field.label,
'labelWidth': 128,
'width': 384
});
$items.push($input);
}
// $items.push($input);
}
Ox.print("items", $items);
var $form = new Ox.Form({
'id': 'AddItem' + that.options("model"),
'items': $items,
'submit': function(data, callback) {
data['model'] = that.options("model");
data['module'] = that.options("module");
app.api.addItem(data, function(result) {
alert(JSON.stringify(result));
});
}
}).appendTo($content);
var d = new Ox.Dialog({
buttons: [
new Ox.Button({
'id': 'SubmitItem' + that.options("model"),
'size': 'medium',
'title': 'Submit'
}).bindEvent("click", function() { $form.submit(); }),
new Ox.Button({
'id': 'cancel',
'title': 'Cancel',
}).bindEvent("click", function() { d.close(); })
],
content: $content,
width: 600,
height: 500,
title: 'Add Best Practice'
}).open();
});
});
var $infoBtn = new Ox.Button({ var $infoBtn = new Ox.Button({
id: options.id + "InfoBtn", id: options.id + "InfoBtn",
@ -104,7 +172,7 @@ Ox.ItfBox = function(options, self) {
var $menuBtn = new Ox.Button({ var $menuBtn = new Ox.Button({
id: options.id + 'MenuBtn', id: options.id + 'MenuBtn',
style: 'symbol', style: 'symbol',
title: 'expand', title: 'collapse',
type: 'image', type: 'image',
tooltip: 'Show Menu' tooltip: 'Show Menu'
}).appendTo($buttons); }).appendTo($buttons);
@ -184,9 +252,9 @@ Ox.ItfBox = function(options, self) {
}); });
} }
var $listContainer = new Ox.Element() var $listContainer = that.$listContainer = new Ox.Element()
.appendTo(that) .appendTo(that)
.css({position: 'relative', height: '100%'}); .css({position: 'relative', height: '90%'});
var listOptions = $.extend(options, { var listOptions = $.extend(options, {
'width': 256, 'width': 256,
@ -215,7 +283,7 @@ Ox.ItfBox = function(options, self) {
operator: '-', operator: '-',
unique: false, unique: false,
visible: true, visible: true,
width: 230 width: 256
}, },
{ {
id: 'id', id: 'id',
@ -241,7 +309,11 @@ Ox.ItfBox = function(options, self) {
Ox.ItfList = function(options, self) { Ox.ItfList = function(options, self) {
var self = self || {}; var self = self || {};
var that = new Ox.TextList(options, self); var opts = $.extend({
'scrollbarVisible': false,
'hasComments': true
}, options);
var that = new Ox.TextList(opts, self);
that.bindEvent("select", function(e, data) { that.bindEvent("select", function(e, data) {
if (data.ids.length === 0) { if (data.ids.length === 0) {
app.$ui.previewBox.$content.html(''); app.$ui.previewBox.$content.html('');
@ -250,8 +322,8 @@ Ox.ItfList = function(options, self) {
app.$ui[options.boxId].$loading.start(); app.$ui[options.boxId].$loading.start();
// debugger; // debugger;
app.api.preview({ app.api.preview({
model: options.model, model: opts.model,
module: options.module, module: opts.module,
id: data.ids[0] id: data.ids[0]
}, function(response) { }, function(response) {
// alert(JSON.stringify(response.data.data)); // alert(JSON.stringify(response.data.data));
@ -263,14 +335,17 @@ Ox.ItfList = function(options, self) {
}); });
that.bindEvent("open", function(e, data) { that.bindEvent("open", function(e, data) {
// alert(JSON.stringify(data)); // alert(JSON.stringify(data));
app.$ui[options.boxId].$loading.start(); app.$ui[opts.boxId].$loading.start();
app.api.info({ app.api.info({
model: options.model, model: opts.model,
module: options.module, module: opts.module,
id: data.ids[0] id: data.ids[0]
}, function(response) { }, function(response) {
app.$ui[options.boxId].$loading.stop(); app.$ui[opts.boxId].$loading.stop();
var html = $.tmpl(response['template'], response['data']); var html = $.tmpl(response['template'], response['data']);
var content = new Ox.Element().append(html);
var commentForm = ITF.CommentForm(opts, response['commentForm']).appendTo(content);
var comments = _getComments(response['comments']).appendTo(content);
// alert(html); // alert(html);
var d = new Ox.Dialog({ var d = new Ox.Dialog({
buttons: [ buttons: [
@ -280,7 +355,7 @@ Ox.ItfList = function(options, self) {
}) })
.bindEvent("click", function() { d.close(); }) .bindEvent("click", function() { d.close(); })
], ],
content: new Ox.Element().append(html), 'content': content,
title: options.title + ": " + response.data.title, title: options.title + ": " + response.data.title,
width: 800, width: 800,
height: 500 height: 500
@ -292,6 +367,24 @@ Ox.ItfList = function(options, self) {
return that; return that;
} }
function _getComments(comments) {
var that = new Ox.Element().addClass("OxCommentsWrapper")
if (comments.length > 0) {
var title = new Ox.Element("h4").html("Comments:").appendTo(that);
for (var i=0; i<comments.length; i++) {
var comment = comments[i];
var $comment = new Ox.Element().addClass("OxCommentWrapper");
var $user = new Ox.Element().addClass("OxCommentsPostedBy").html("posted by " + comment.name).appendTo($comment);
var $commentBody = new Ox.Element().addClass("OxCommentBody").html("comment: " + comment.comment).appendTo($comment);
$comment.appendTo(that);
}
} else {
var $nocomments = new Ox.Element().addClass("OxNoComments").html("No comments on this yet..").appendTo(that);
}
return that;
}
Ox.ItfCalendar = function(options, self) { Ox.ItfCalendar = function(options, self) {
var self = self || {}; var self = self || {};
var that = new Ox.Element(options, self); var that = new Ox.Element(options, self);
@ -310,5 +403,31 @@ Ox.ItfPreview = function(options, self) {
return that; return that;
} }
ITF.CommentForm = function(options, formData) {
var that = new Ox.Element();
var title = new Ox.Element("h4").html("Add Comment:").appendTo(that);
var textarea = new Ox.Element("textarea")
.css({'width': '450px', 'height': '200px', 'display': 'block', 'marginBottom': '3px'})
.appendTo(that);
var submitBtn = new Ox.Button({
'id': 'commentFormSubmit',
'title': 'Submit',
'size': 'Large'
}).bindEvent("click", function() {
var data = $.extend({
'id': options.id,
'module': options.module,
'model': options.model,
'name': app.user.username,
'email': app.user.email,
'comment': textarea.val()
}, formData);
app.api.addComment(data, function(response) {
alert(JSON.stringify(response));
});
}).appendTo(that);
return that;
}
ITF.templates = {}; ITF.templates = {};

View File

@ -8,6 +8,8 @@ from django.views.generic.simple import direct_to_template
from django.contrib import admin from django.contrib import admin
admin.autodiscover() admin.autodiscover()
from api import actions
actions.autodiscover()
urlpatterns = patterns('', urlpatterns = patterns('',
# Example: # Example: