Я готовлю массивы с опциями для filter_selectSource Tablesorter в Python / Django.Потому что изначально, для меня это работало очень странно, когда я переключился на фильтрацию на стороне сервера.Параметры раскрывающегося списка отображались только в том случае, если я набрал один символ в одном из фильтров поиска, а затем каждый раз, когда показывались варианты выбора, доступные на шаг раньше.И тогда я решил попытаться сделать большую часть работы на стороне сервера
Players.views
def skaters_averages_json(request, page, sort_col, filt_col, rookie_filt):
start = utils.PAGE_SIZE_2*(page - 1)
end = start + utils.PAGE_SIZE_2
skaters = Skater.objects.select_related('team')
filtering = utils.filter_columns(filt_col)
if filtering:
skaters = utils.apply_filters(skaters, filtering)
if utils.rookie_filter(rookie_filt):
skaters = skaters.filter(rookie=True)
sorting = utils.sorting_columns(sort_col)
one_page_slice = utils.sort_table(sorting, skaters)[start:end]
skaters_json = json.loads(serializers.serialize('json', one_page_slice,
use_natural_foreign_keys=True))
domain = request.get_host()
total_rows = skaters.count()
data = utils.process_json(domain, skaters_json, total_rows, page)
data['filter_select'] = {
**utils.filter_select_opts(skaters, 3, 'position_abbr'),
**utils.filter_select_opts(skaters, 4, 'team__abbr'),
**utils.filter_select_opts(skaters, 5, 'nation_abbr'),
}
return JsonResponse(data, safe=False)
Players.utils
def filter_select_opts(skaters_query, col_number, field_name):
uniques = list(skaters_query.values_list(field_name, flat=True).distinct())
return {col_number: sorted(uniques, key=lambda x: (x is None, x))}
Так что мойJSONResponse выглядит следующим образом.
Страница 1
{
"total": 41,
"rows": [
[row 1],
...
[row 25]
],
"filter_select": {
"3": [
"C",
"D",
"LW",
"RW"
],
"4": [
"ANA",
"BOS",
"BUF",
"CAR",
"CBJ",
"CGY",
"CHI",
"COL",
"DAL",
"EDM",
"FLA",
"MIN",
"MTL",
"NJD",
"NSH",
"NYI",
"PHI",
"PIT",
"SJS",
"TOR",
"VAN",
"VGK",
"WPG"
],
"5": [
"FIN"
]
}
}
Страница 2
{
"total": 41,
"rows": [
[row 26],
...
[row 41]
],
"filter_select": {
"3": [
"C",
"D",
"LW",
"RW"
],
"4": [
"ANA",
"BOS",
"BUF",
"CAR",
"CBJ",
"CGY",
"CHI",
"COL",
"DAL",
"EDM",
"FLA",
"MIN",
"MTL",
"NJD",
"NSH",
"NYI",
"PHI",
"PIT",
"SJS",
"TOR",
"VAN",
"VGK",
"WPG"
],
"5": [
"FIN"
]
}
}
На второй странице ответа примененного фильтра показаны те же значения для filter_select
Нокогда я смотрю на те же страницы после того, как он обработан filter_selectSource
, он показывает только опции, доступные на текущей видимой странице.Есть ли способ переопределить это поведение?
Прочитать документы для filter_selectSource и getOptions .Не могу найти то, что я хочу.
external.js
let selectOptions;
$("#tab1")
.tablesorter({
headers: {
0: {sorter: false, filter: false},
1: {filter: false},
2: {filter: false},
},
widgets: ['filter'],
widgetOptions : {
filter_selectSource: selectOptions,
filter_reset: '.reset',
filter_external : '.select',
}
})
.tablesorterPager({
container: $(".pager-s"),
size: 25,
output: '{page} / {totalPages}',
savePages: false,
fixedHeight: false,
ajaxUrl: 'http://127.0.0.1:8000/skaters_averages_json/{page+1}/{sort:col}/{filter:fcol}',
customAjaxUrl: function(table, url) {
if ($("#tab1").data('filter_value')) {
return url += '/rookie_filter=' + $("#tab1").data('filter_value');
};
return url += '/rookie_filter=';
},
ajaxObject: {
success: function(data) {
selectOptions = data['filter_select'];
$("#tab1").trigger("updateAll");
console.log(selectOptions);
},
dataType: 'json',
type: 'GET'
},
});
$('.rookie-filter').on('change', function(){
let checked = $(this).is(":checked");
$("#tab1").data('filter_value', checked).trigger('pagerUpdate', 1);
if (checked) {
$(this).attr('title', 'Show all players')
} else {
$(this).attr('title', 'Show rookies only')
};
});
$('.reset').on('click', function(){
$('.rookie-filter').prop('checked', false);
$("#tab1").data('filter_value', $(this).is(":checked")).trigger('pagerUpdate');
});
$('table').bind("sortEnd", function(){
$(this).trigger('pageSet', 1);
});
Я также записываю selectOptions
во внешний файл .js, чтобы убедиться, что получаю то, что ожидается.
ОБНОВЛЕНИЕ.Я пытался заставить его работать с buildSelect
, как предложил @Mottie в комментарии.Как оказалось, filter_selectSource
actall didn't accept my variable in
filter_selectSource: selectOptions , the only line that makes a difference is
$ ("# tab1"). Trigger ("updateAll") in
ajaxObject`.Затем Tablesorter автоматически отображает параметры, доступные на текущей странице.
Итак, сейчас я борюсь за запуск обновлений для строки фильтра.Я могу загрузить ожидаемые параметры для одного столбца за раз, но таблица не работает из-за ошибки too much recursion
.$('body').trigger(filter_event)
в каждом filter_selectSource
, вызывающем огромное количество обновлений таблицы.Но без этого опции для выпадающих меню пусты.Я пытался связать это обновление для различных событий .Как filterInit
.Не работал для меняПосмотрите на мой обновленный скрипт ниже.Любые предложения о том, как заставить его обновить строку фильтра, не повторяя его несколько раз?
$("#tab1").data('statType', 'tot');
let pos = [];
let team = [];
let nation = [];
let filter_event = jQuery.Event("load_filter_select");
$("#tab1")
.tablesorter({
headers: {
0: {sorter: false, filter: false},
1: {filter: false},
2: {filter: false},
},
widgets: ['filter'],
widgetOptions : {
filter_selectSource: {
3 : function(table, column, onlyAvail) {
result = pos;
$.tablesorter.filter.buildSelect(table, column, result, true);
$('body').trigger(event);
},
4 : function(table, column) {
result = team;
$.tablesorter.filter.buildSelect(table, column, result, true);
$('body').trigger(filter_event);
},
5 : function(table, column) {
result = nation;
$.tablesorter.filter.buildSelect(table, column, result, true);
$('body').trigger(filter_event);
},
},
filter_reset: '.reset',
filter_external : '.select',
}
})
.tablesorterPager({
container: $(".pager-s"),
size: 25,
output: '{page} / {totalPages}',
savePages: false,
fixedHeight: false,
ajaxUrl: 'http://127.0.0.1:8000/skaters_averages_json?/{page+1}/{sort:col}/{filter:fcol}',
customAjaxUrl: function(table, url) {
urlParts = url.split('?');
url = urlParts[0] + `/${$("#tab1").data('statType')}` + urlParts[1];
if ($("#tab1").data('filter_value')) {
return url += '/rookie_filter=' + $("#tab1").data('filter_value');
};
return url += '/rookie_filter=';
},
ajaxObject: {
success: function(data) {
pos = data['filter_select'][3];
team = data['filter_select'][4];
nation = data['filter_select'][5];
$('body').trigger(filter_event);
},
dataType: 'json',
type: 'GET'
},
});
$('body').on('load_filter_select', function(){
$("#tab1").trigger('update');
});