- Author:
- pawnhearts
- Posted:
- January 8, 2010
- Language:
- JavaScript
- Version:
- Not specified
- Score:
- 1 (after 1 ratings)
You have some tree-like structure in your models, for example:
class MyModel(models.Model):
parent = models.ForeignKey('self', verbose_name=u'Parent', \
null=True, blank=True, related_name='children')
name = models.CharField(u'Раздел', max_lengtch=255)
position = PositiveSmallIntegerField(u'Позиция', default=0)
class Meta:
ordering = ('position',)
To see it as a tree in admin's object list(you also can sort items, move to another parents by drag-n-drop; and rename them) add this to admin.py:
class MyModelAdmin(admin.ModelAdmin):
ordering = ('position',)
list_display = ('pk','name','parent','position')
raw_id_fields =('parent',)
list_per_page = 900 #we sould have all objects on one page
list_editable = ('name','position','parent')
def parent_id(self,obj):
return obj.parent and obj.parent.id or '0'
class Meta:
model = MyModel
class Media:
js = [settings.MEDIA_URL + s for s in ('lib/jquery-1.3.2.min.js',
'lib/jquery.tree.min.js',
'lib/plugins/jquery.tree.contextmenu.js',
'lib/mymodel_admin.js',)]
css = {
'all':(settings.MEDIA_URL+'css/nestedsortablewidget.css',)
}
mymodel_admin.js is the code listed here, if you have different title field(not "name"), change var title_column in javascript, list_display and list_editable.
jstree can be obtained here: jstree
screenshot is in my blog
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | var oldparent;
var title_column='name';
$(document).ready(function() {
if (!$('#changelist').length)
return false;
var allcats = $('#changelist tbody tr th').map(function(i, el) {
return [[document.forms[0]['form-' + i + '-' + title_column].value, $(el).find('a')[0].innerHTML, document.forms[0]['form-' + i + '-parent'].value, i]]
});
function build_tree(par) {
return allcats.filter(function(i) {
return this[2] == par;
}).map(function(i, el) {
var node = {
attributes: {
"id": 'n' + el[1],
"pk": el[1],
"alt": el[3]
},
data: {
title: el[0],
attributes: {
href: el[1] + '/'
}
}
};
var chld = build_tree(el[1]);
if (chld.length)
node.children = chld;
return node;
}).get();
}
var treeheight = $('#changelist').innerHeight();
$('#changelist').hide();
var treediv = document.createElement('div');
treediv.style.cssText = 'position:relative;width:100%;';
treediv.className = 'module';
treediv.id = 'treediv';
$(treediv).insertAfter('#changelist');
var savediv = document.createElement('div');
savediv.style.cssText = 'clear:both;width:100%;height:32px;';
var btn = document.createElement('input');
btn.className = 'default';
btn.type = 'submit';
btn.value = $('#changelist input[type=submit]:last')[0].value;
btn.onclick = function() {
document.forms[0].submit();
return false;
}
$(savediv).append(btn);
$(savediv).append(btn);
$(savediv).insertAfter('#changelist');
$('#changelist input[name=_save]')[0].type = 'text';
$(function() {
$("#treediv").tree({
ui: {
theme_name: 'apple'
},
plugins: {
contextmenu: {
items: {
remove: false,
create: {
label: "Create",
icon: "create",
visible: function(NODE, TREE_OBJ) {
if (NODE.length != 1)
return 0;
return TREE_OBJ.check("creatable", NODE);
},
action: function(NODE, TREE_OBJ) {
location.href = 'add/?parent=' + $(NODE).attr('pk')
},
separator_after: true
},
rename: {
label: "Rename",
icon: "rename",
visible: function(NODE, TREE_OBJ) {
if (NODE.length != 1)
return false;
return TREE_OBJ.check("renameable", NODE);
},
action: function(NODE, TREE_OBJ) {
TREE_OBJ.rename(NODE);
}
},
edit: {
label: "Modify",
icon: "rename",
visible: function(NODE, TREE_OBJ) {
if (NODE.length != 1)
return false;
return TREE_OBJ.check("renameable", NODE);
},
action: function(NODE, TREE_OBJ) {
location.href = $(NODE).attr('pk') + '/';
}
}
}
}
},
callback: {
onmove: function(NODE, REF_NODE, TYPE, TREE_OBJ, RB) {
document.forms[0]['form-' + $(NODE).attr('alt') + '-parent'].value = ((TREE_OBJ.parent(NODE) != -1) ? TREE_OBJ.parent(NODE).attr('pk') : '');
TREE_OBJ.children(oldparent).map(function(i, el) {
document.forms[0]['form-' + $(el).attr('alt') + '-position'].value = i;
});
TREE_OBJ.children(TREE_OBJ.parent(NODE)).map(function(i, el) {
document.forms[0]['form-' + $(el).attr('alt') + '-position'].value = i;
});
},
beforemove: function(NODE, REF_NODE, TYPE, TREE_OBJ) {
oldparent = TREE_OBJ.parent(NODE);
return true;
},
ondblclk: function(NODE, TREE_OBJ) {
location.href = $(NODE).attr('pk');
},
onload: function(TREE_OBJ) {
TREE_OBJ.open_all();
},
onrename: function(NODE, TREE_OBJ, RB) {
document.forms[0]['form-' + $(NODE).attr('alt') + '-' + title_column].value = TREE_OBJ.get_text(NODE);
},
onselect: function(NODE, TREE_OBJ) {
}
},
data: {
type: "json",
opts: {
static: build_tree('')
}
}
});
});
});
|
More like this
- Django Collapsed Stacked Inlines by applecat 1 year, 9 months ago
- Django Collapsed Stacked Inlines by mkarajohn 3 years, 10 months ago
- Dynamically adding forms to a formset. OOP version. by halfnibble 9 years, 6 months ago
- Convert multiple select for m2m to multiple checkboxes in django admin form by abidibo 11 years, 7 months ago
- Django admin inline ordering - javascript only implementation by ojhilt 11 years, 11 months ago
Comments
Please login first before commenting.