【发布时间】:2011-08-30 12:12:08
【问题描述】:
我很喜欢 django 管理视图的过滤功能 (list_filter)。
但是,对于具有很多字段的视图,我真的希望能够通过单击来最小化/扩展它,以节省屏幕空间,而且因为它有时实际上隐藏了一些东西。
有没有一种简单的方法来添加折叠按钮(一些我还没有找到的现有插件或类似的东西)?
【问题讨论】:
标签: django django-admin django-admin-filters
我很喜欢 django 管理视图的过滤功能 (list_filter)。
但是,对于具有很多字段的视图,我真的希望能够通过单击来最小化/扩展它,以节省屏幕空间,而且因为它有时实际上隐藏了一些东西。
有没有一种简单的方法来添加折叠按钮(一些我还没有找到的现有插件或类似的东西)?
【问题讨论】:
标签: django django-admin django-admin-filters
鉴于您现在在 django admin 中拥有 jQuery,很容易将 slideToggle() 绑定到列表过滤器中的标题。
这似乎足以让 Javascript 工作:
// Fancier version https://gist.github.com/985283
;(function($){ $(document).ready(function(){
$('#changelist-filter').children('h3').each(function(){
var $title = $(this);
$title.click(function(){
$title.next().slideToggle();
});
});
});
})(django.jQuery);
然后在你要激活的ModelAdmin子类中设置Media内部类:
class MyModelAdmin(admin.ModelAdmin):
list_filter = ['bla', 'bleh']
class Media:
js = ['js/list_filter_collapse.js']
确保将 list_filter_collapse.js 文件放在 STATIC_DIRS 或 STATIC_ROOT 内的“js”文件夹中(取决于您的 Django 版本)
【讨论】:
我更改了 Jj 的答案以在单击“过滤器”标题时折叠整个过滤器,为了完整起见,将其添加到此处,提供要点here:
(function($){
ListFilterCollapsePrototype = {
bindToggle: function(){
var that = this;
this.$filterTitle.click(function(){
that.$filterContent.slideToggle();
that.$list.toggleClass('filtered');
});
},
init: function(filterEl) {
this.$filterTitle = $(filterEl).children('h2');
this.$filterContent = $(filterEl).children('h3, ul');
$(this.$filterTitle).css('cursor', 'pointer');
this.$list = $('#changelist');
this.bindToggle();
}
}
function ListFilterCollapse(filterEl) {
this.init(filterEl);
}
ListFilterCollapse.prototype = ListFilterCollapsePrototype;
$(document).ready(function(){
$('#changelist-filter').each(function(){
var collapser = new ListFilterCollapse(this);
});
});
})(django.jQuery);
【讨论】:
为此,我写了一个可在bitbucket 上下载的小sn-ps。
过滤器的状态存储在 cookie 中,所选过滤器保持可见。
【讨论】:
感谢@JJ 的想法。 我为整个窗口添加了切换,比 @abyx 的实现简单。
这是js文件内容:
;(function($){ $(document).ready(function(){
$('#changelist-filter > h3').each(function(){
var $title = $(this);
$title.click(function(){
$title.next().slideToggle();
});
});
var toggle_flag = true;
$('#changelist-filter > h2').click(function () {
toggle_flag = ! toggle_flag;
$('#changelist-filter > ul').each(function(){
$(this).toggle(toggle_flag);
});
});
});
})(django.jQuery);
【讨论】:
对此进行了另一项更改,以便在您单击顶部 H2 时隐藏 H3 以及过滤器列表。如果您单击顶部的“过滤器”,这将清除整个过滤器列表。
这是js文件内容
;(function($){ $(document).ready(function(){
$('#changelist-filter > h3').each(function(){
var $title = $(this);
$title.click(function(){
$title.next().slideToggle();
});
});
var toggle_flag = true;
$('#changelist-filter > h2').click(function () {
toggle_flag = ! toggle_flag;
$('#changelist-filter').find('> ul, > h3').each(function(){
$(this).toggle(toggle_flag);
});
});
});
})(django.jQuery);
【讨论】:
修改 fanlix 解决方案为:
(function($){ $(document).ready(function(){
$('#changelist-filter > h3').each(function(){
var $title = $(this);
$title.next().toggle();
$title.css("cursor","pointer");
$title.click(function(){
$title.next().slideToggle();
});
});
var toggle_flag = false;
$('#changelist-filter > h2').css("cursor","pointer");
$('#changelist-filter > h2').click(function () {
toggle_flag = ! toggle_flag;
$('#changelist-filter > ul').each(function(){
$(this).slideToggle(toggle_flag);
});
});
});
})(django.jQuery);
【讨论】:
结合了 Tim 和 maGo 的方法,并进行了一些调整:
优点:
缺点:
代码:
(function($){ $(document).ready(function(){
// Start with a filter list showing only its h3 subtitles; clicking on any
// displays that filter's content; clicking again collapses the list:
$('#changelist-filter > h3').each(function(){
var $title = $(this);
$title.next().toggle();
$title.css("cursor","pointer");
$title.click(function(){
$title.next().slideToggle();
});
});
// Add help after title:
$('#changelist-filter > h2').append("<span style='font-size: 80%; color: grey;'> (click to hide/unhide)</span>");
// Make title clickable to hide entire filter:
var toggle_flag = true;
$('#changelist-filter > h2').click(function () {
toggle_flag = ! toggle_flag;
$('#changelist-filter').find('> h3').each(function(){
$(this).toggle(toggle_flag);
});
});
});
})(django.jQuery);
【讨论】:
我为菜单折叠和单元素菜单折叠写了一个 sn-ps。
这是 abyx 代码的一个分支,我刚刚对其进行了扩展。
如果之前激活了过滤器,则与此相关的元素菜单将在打开时开始。
过滤器菜单默认关闭。 希望这会有所帮助
https://github.com/peppelinux/Django-snippets/tree/master/django-admin.js-snippets
【讨论】:
Giuseppe De Marco 的 sn-p 效果最好。所以我在这里添加他的代码 sn-p 以便于访问。它甚至解决了上面 joelg 讨论的问题(缺点):
// Copied from
// https://github.com/peppelinux/Django-snippets/tree/master/django-admin.js-snippets
(function($){
var element_2_collapse = '#changelist-filter';
var element_head = 'h2'
var filter_title = 'h3'
// this is needed for full table resize after filter menu collapse
var change_list = '#changelist'
ListFilterCollapsePrototype = {
bindToggle: function(){
var that = this;
this.$filterTitle.click(function(){
// check if some ul is collapsed
// open it before slidetoggle all together
$(element_2_collapse).children('ul').each(function(){
if($(this).is(":hidden"))
{
$(this).slideToggle();
}
})
// and now slidetoggle all
that.$filterContentTitle.slideToggle();
that.$filterContentElements.slideToggle();
that.$list.toggleClass('filtered');
});
},
init: function(filterEl) {
this.$filterTitle = $(filterEl).children(element_head);
this.$filterContentTitle = $(filterEl).children(filter_title);
this.$filterContentElements = $(filterEl).children('ul');
$(this.$filterTitle).css('cursor', 'pointer');
this.$list = $(change_list );
// header collapse
this.bindToggle();
// collapsable childrens
$(element_2_collapse).children(filter_title).each(function(){
var $title = $(this);
$title.click(function(){
$title.next().slideToggle();
});
$title.css('border-bottom', '1px solid grey');
$title.css('padding-bottom', '5px');
$title.css('cursor', 'pointer');
});
}
}
function ListFilterCollapse(filterEl) {
this.init(filterEl);
}
ListFilterCollapse.prototype = ListFilterCollapsePrototype;
$(document).ready(function(){
$(element_2_collapse).each(function(){
var collapser = new ListFilterCollapse(this);
});
// close them by default
$(element_2_collapse+' '+element_head).click()
// if some filter was clicked it will be visible for first run only
// selezione diverse da Default
$(element_2_collapse).children(filter_title).each(function(){
lis = $(this).next().children('li')
lis.each(function(cnt) {
if (cnt > 0)
{
if ($(this).hasClass('selected')) {
$(this).parent().slideDown();
$(this).parent().prev().slideDown();
// if some filters is active every filters title (h3)
// should be visible
$(element_2_collapse).children(filter_title).each(function(){
$(this).slideDown();
})
$(change_list).toggleClass('filtered');
}
}
})
});
});
})(django.jQuery);
【讨论】: