【问题标题】:Minimize the list filter in django-admin最小化 django-admin 中的列表过滤器
【发布时间】:2011-08-30 12:12:08
【问题描述】:

我很喜欢 django 管理视图的过滤功能 (list_filter)。

但是,对于具有很多字段的视图,我真的希望能够通过单击来最小化/扩展它,以节省屏幕空间,而且因为它有时实际上隐藏了一些东西。

有没有一种简单的方法来添加折叠按钮(一些我还没有找到的现有插件或类似的东西)?

【问题讨论】:

    标签: django django-admin django-admin-filters


    【解决方案1】:

    鉴于您现在在 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 版本)

    【讨论】:

    • 我希望在您单击“过滤器”部分时切换整个过滤器
    • 嘿,这正是我要找的,但我不知道这段 javascript 代码应该去哪里。它应该放入哪些文件?
    • @wobbily_col,Media 中的文件是相对于 STATIC 的。我所做的方法是创建一个“js/admin”目录,并使文件被加载“js/admin/list_filter_collapse.js”。
    【解决方案2】:

    我更改了 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);
    

    【讨论】:

    • 谢谢,您的 js 代码在 Django 1.9.9 上比其他代码运行得更好。能不能让fitter list默认折叠?
    【解决方案3】:

    为此,我写了一个可在bitbucket 上下载的小sn-ps。

    过滤器的状态存储在 cookie 中,所选过滤器保持可见。

    【讨论】:

      【解决方案4】:

      感谢@JJ 的想法。 我为整个窗口添加了切换,比 @abyx 的实现简单。

      1. 通过单击“过滤器”标题切换整个过滤器
      2. 通过单击列表标题切换每个列表

      这是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);
      

      【讨论】:

        【解决方案5】:

        对此进行了另一项更改,以便在您单击顶部 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);
        

        【讨论】:

          【解决方案6】:

          修改 fanlix 解决方案为:

          1. 在悬停时将光标显示为指针
          2. 默认折叠

          代码

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

          【讨论】:

            【解决方案7】:

            结合了 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);
            

            【讨论】:

              【解决方案8】:

              我为菜单折叠和单元素菜单折叠写了一个 sn-ps。

              这是 abyx 代码的一个分支,我刚刚对其进行了扩展。

              如果之前激活了过滤器,则与此相关的元素菜单将在打开时开始。

              过滤器菜单默认关闭。 希望这会有所帮助

              https://github.com/peppelinux/Django-snippets/tree/master/django-admin.js-snippets

              【讨论】:

              • 请将代码 sn-p 添加到您的答案中,不要只是链接到它。
              【解决方案9】:

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

              【讨论】:

                猜你喜欢
                • 2012-05-11
                • 2014-01-30
                • 2010-10-15
                • 2012-02-08
                • 2020-03-17
                • 2015-10-10
                • 1970-01-01
                • 2010-10-25
                • 2012-01-14
                相关资源
                最近更新 更多