Минимизировать фильтр списка в django-admin

Мне очень нравится функция фильтра django admin views (list_filter).

Но, в представлениях с большим количеством полей, мне бы очень хотелось свести к минимуму/расширить его с помощью щелчка, чтобы сохранить экранную недвижимость, а также потому, что она иногда на самом деле скрывает материал.

Есть ли простой способ добавить кнопку свернуть (какой-то уже существующий плагин я не нашел или что-то подобное)?

Ответ 1

Учитывая, что у вас теперь есть jQuery в django admin, легко привязать 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 в папке "js" внутри вашего STATIC_DIRS или STATIC_ROOT (в зависимости от версии Django)

Ответ 2

Я изменил ответ Jj, чтобы свернуть весь фильтр, нажав на заголовок 'filter', добавив его здесь для полноты, доступен gist здесь:

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

Ответ 3

Я написал небольшие фрагменты, загружаемые на bitbucket для этой цели.

Состояние фильтров сохраняется в файле cookie, и выбранные фильтры остаются видимыми.

enter image description here

Ответ 4

Благодаря идее @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);

Ответ 5

Сделано другое изменение, чтобы H3 были скрыты, а также списки фильтров, когда вы нажимаете на верхнюю часть H2. Это приведет к тому, что весь список фильтров будет удален, если вы нажмете верхний "Фильтры".

Это содержимое файла 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

Измененное решение фанликса:

  • Показать курсор в качестве указателя при наведении курсора
  • Складывать по умолчанию

код

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

Я написал фрагменты для сглаживания меню и сглаживания одного элемента.

Это вилка из кода abyx, я только что расширил ее.

Если фильтр был ранее активирован, меню элементов, связанное с этим, начнется как открытое.

Меню фильтра начинает закрываться по умолчанию. Надеюсь, что это поможет

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

Ответ 9

Фрагмент Джузеппе Де Марко работает лучше всего. Поэтому я добавляю его фрагмент кода для легкого доступа. Это даже решает проблему (минусы), рассмотренную выше 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);