Changement sur la base
This commit is contained in:
138
templates/rangefilter/date_filter.html
Normal file
138
templates/rangefilter/date_filter.html
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
{% load i18n rangefilter_compat %}
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}">
|
||||||
|
<style>
|
||||||
|
{% default_css_vars_if_needed %}
|
||||||
|
.admindatefilter .button, .admindatefilter input[type=submit], .admindatefilter input[type=button], .admindatefilter .submit-row input, .admindatefilter a.button,
|
||||||
|
.admindatefilter .button, .admindatefilter input[type=reset] {
|
||||||
|
background: var(--button-bg);
|
||||||
|
padding: 4px 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--button-fg);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.admindatefilter {
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
.admindatefilter p {
|
||||||
|
padding-left: 0px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.admindatefilter p.datetime {
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.admindatefilter .timezonewarning {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts a:first-child {
|
||||||
|
margin-right: 4px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.calendarbox {
|
||||||
|
z-index: 1100;
|
||||||
|
}
|
||||||
|
.clockbox {
|
||||||
|
z-index: 1100;
|
||||||
|
margin-left: -8em !important;
|
||||||
|
margin-top: 5em !important;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts {
|
||||||
|
font-size: 0;
|
||||||
|
float: right;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
.admindatefilter a {
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.calendarbox {
|
||||||
|
margin-left: -16em !important;
|
||||||
|
margin-top: 9em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.calendarbox {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% comment %}
|
||||||
|
Force load jsi18n, issues #5
|
||||||
|
https://github.com/django/django/blob/stable/1.10.x/django/contrib/admin/templates/admin/change_list.html#L7
|
||||||
|
{% endcomment %}
|
||||||
|
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||||
|
<script>
|
||||||
|
function datefilter_apply(event, qs_name){
|
||||||
|
event.preventDefault();
|
||||||
|
const $form = django.jQuery(event.target).closest('form');
|
||||||
|
const query_string = $form.find('input#'+qs_name).val();
|
||||||
|
const form_data = $form.serialize();
|
||||||
|
const amp = query_string === "?" ? "" : "&"; // avoid leading ?& combination
|
||||||
|
window.location = window.location.pathname + query_string + amp + form_data;
|
||||||
|
}
|
||||||
|
function datefilter_reset(event, qs_name){
|
||||||
|
const $form = django.jQuery(event.target).closest('form');
|
||||||
|
const query_string = $form.find('input#' + qs_name).val();
|
||||||
|
window.location = window.location.pathname + query_string;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
{% comment %}
|
||||||
|
// Code below makes sure that the DateTimeShortcuts.js is loaded exactly once
|
||||||
|
// regardless the presence of AdminDateWidget
|
||||||
|
// How it worked:
|
||||||
|
// - First Django loads the model formset with predefined widgets for different
|
||||||
|
// field types. If there's a date based field, then it loads the AdminDateWidget
|
||||||
|
// and it's required media to context under {{media.js}} in admin/change_list.html.
|
||||||
|
// (Note: it accumulates media in django.forms.widgets.Media object,
|
||||||
|
// which prevents duplicates, but the DateRangeFilter is not included yet
|
||||||
|
// since it's not model field related.
|
||||||
|
// List of predefined widgets is in django.contrib.admin.options.FORMFIELD_FOR_DBFIELD_DEFAULTS)
|
||||||
|
// - After that Django starts rendering forms, which have the {{form.media}}
|
||||||
|
// tag. Only then the DjangoRangeFilter.get_media is called and rendered,
|
||||||
|
// which creates the duplicates.
|
||||||
|
// How it works:
|
||||||
|
// - first step is the same, if there's a AdminDateWidget to be loaded then
|
||||||
|
// nothing changes
|
||||||
|
// - DOM gets rendered and if the AdminDateWidget was rendered then
|
||||||
|
// the DateTimeShortcuts.js is initiated which sets the window.DateTimeShortcuts.
|
||||||
|
// Otherwise, the window.DateTimeShortcuts is undefined.
|
||||||
|
// - The lines below check if the DateTimeShortcuts has been set and if not
|
||||||
|
// then the DateTimeShortcuts.js and calendar.js is rendered
|
||||||
|
//
|
||||||
|
// https://github.com/silentsokolov/django-admin-rangefilter/issues/9
|
||||||
|
//
|
||||||
|
// Django 2.1
|
||||||
|
// https://github.com/silentsokolov/django-admin-rangefilter/issues/21
|
||||||
|
{% endcomment %}
|
||||||
|
django.jQuery('document').ready(function () {
|
||||||
|
if (!('DateTimeShortcuts' in window)) {
|
||||||
|
django.jQuery.when(
|
||||||
|
{% for m in spec.form.js %}
|
||||||
|
django.jQuery.getScript('{{m}}'),
|
||||||
|
{% endfor %}
|
||||||
|
django.jQuery.Deferred(function( deferred ){
|
||||||
|
django.jQuery( deferred.resolve );
|
||||||
|
})
|
||||||
|
).done(function(){
|
||||||
|
django.jQuery('.datetimeshortcuts').remove();
|
||||||
|
DateTimeShortcuts.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% block quick-select-choices %}{% endblock %}
|
||||||
|
<div class="admindatefilter form-group">
|
||||||
|
|
||||||
|
{{ spec.form.as_p }}
|
||||||
|
{% for choice in choices %}
|
||||||
|
<input type="hidden" id="{{ choice.system_name }}-query-string" value="{{ choice.query_string }}">
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
94
templates/rangefilter/date_filter_1_8.html
Normal file
94
templates/rangefilter/date_filter_1_8.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
{% load i18n rangefilter_compat %}
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}">
|
||||||
|
<style>
|
||||||
|
.admindatefilter .button, .admindatefilter input[type=reset] {
|
||||||
|
padding: 3px 5px;
|
||||||
|
color: black;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
border-color: #ddd #aaa #aaa #ddd;
|
||||||
|
}
|
||||||
|
.admindatefilter {
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
.admindatefilter .timezonewarning {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts a:first-child {
|
||||||
|
margin-right: 4px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.calendarbox {
|
||||||
|
z-index: 1100;
|
||||||
|
margin-left: -16em !important;
|
||||||
|
margin-top: 9em !important;
|
||||||
|
}
|
||||||
|
.clockbox {
|
||||||
|
z-index: 1100;
|
||||||
|
margin-left: -8em !important;
|
||||||
|
margin-top: 5em !important;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts {
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
.admindatefilter a {
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
.admindatefilter br {
|
||||||
|
content: ""
|
||||||
|
}
|
||||||
|
.admindatefilter .vTimeField {
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
.admindatefilter .rangetime {
|
||||||
|
content: "";
|
||||||
|
width: 100px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: thin;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% comment %}
|
||||||
|
Force load jsi18n, issues #5
|
||||||
|
https://github.com/django/django/blob/stable/1.8.x/django/contrib/admin/templates/admin/change_list.html#L7
|
||||||
|
{% endcomment %}
|
||||||
|
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||||
|
<script>
|
||||||
|
function datefilter_apply(event, qs_name, form_name){
|
||||||
|
event.preventDefault();
|
||||||
|
var query_string = django.jQuery('input#'+qs_name).val();
|
||||||
|
var form_data = django.jQuery('#'+form_name).serialize();
|
||||||
|
amp = query_string == "?" ? "" : "&"; // avoid leading ?& combination
|
||||||
|
window.location = window.location.pathname + query_string + amp + form_data;
|
||||||
|
}
|
||||||
|
function datefilter_reset(qs_name){
|
||||||
|
var query_string = django.jQuery('input#'+qs_name).val();
|
||||||
|
window.location = window.location.pathname + query_string;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
django.jQuery('document').ready(function () {
|
||||||
|
if (!('DateTimeShortcuts' in window)) {
|
||||||
|
{% for m in spec.form.js %}
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.src = '{{m}}';
|
||||||
|
document.head.appendChild(script);
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<div class="admindatefilter">
|
||||||
|
<form method="GET" action="." id="{{ choices.0.system_name }}-form">
|
||||||
|
{{ spec.form }}
|
||||||
|
{% for choice in choices %}
|
||||||
|
<input type="hidden" id="{{ choice.system_name }}-query-string" value="{{ choice.query_string }}">
|
||||||
|
{% endfor %}
|
||||||
|
<div class="controls">
|
||||||
|
<input type="submit" class="button" value="{% trans "Search" %}" onclick="datefilter_apply(event, '{{ choices.0.system_name }}-query-string', '{{ choices.0.system_name }}-form')">
|
||||||
|
<input type="reset" class="button" value="{% trans "Reset" %}" onclick="datefilter_reset('{{ choices.0.system_name }}-query-string')">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
145
templates/rangefilter/date_filter_csp.html
Normal file
145
templates/rangefilter/date_filter_csp.html
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
{% load i18n rangefilter_compat %}
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}">
|
||||||
|
<style nonce="{{ spec.request.csp_nonce }}">
|
||||||
|
{% default_css_vars_if_needed %}
|
||||||
|
.admindatefilter .button, .admindatefilter input[type=submit], .admindatefilter input[type=button], .admindatefilter .submit-row input, .admindatefilter a.button,
|
||||||
|
.admindatefilter .button, .admindatefilter input[type=reset] {
|
||||||
|
background: var(--button-bg);
|
||||||
|
padding: 4px 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--button-fg);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.admindatefilter {
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
.admindatefilter p {
|
||||||
|
padding-left: 0px;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.admindatefilter p.datetime {
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
.admindatefilter .timezonewarning {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts a:first-child {
|
||||||
|
margin-right: 4px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.calendarbox {
|
||||||
|
z-index: 1100;
|
||||||
|
}
|
||||||
|
.clockbox {
|
||||||
|
z-index: 1100;
|
||||||
|
margin-left: -8em !important;
|
||||||
|
margin-top: 5em !important;
|
||||||
|
}
|
||||||
|
.admindatefilter .datetimeshortcuts {
|
||||||
|
font-size: 0;
|
||||||
|
float: right;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
.admindatefilter a {
|
||||||
|
color: #999;
|
||||||
|
position: absolute;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.calendarbox {
|
||||||
|
margin-left: -16em !important;
|
||||||
|
margin-top: 9em !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.calendarbox {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
Force load jsi18n, issues #5
|
||||||
|
https://github.com/django/django/blob/stable/1.10.x/django/contrib/admin/templates/admin/change_list.html#L7
|
||||||
|
{% endcomment %}
|
||||||
|
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" nonce="{{ spec.request.csp_nonce }}">
|
||||||
|
{% comment %}
|
||||||
|
// Code below makes sure that the DateTimeShortcuts.js is loaded exactly once
|
||||||
|
// regardless the presence of AdminDateWidget
|
||||||
|
// How it worked:
|
||||||
|
// - First Django loads the model formset with predefined widgets for different
|
||||||
|
// field types. If there's a date based field, then it loads the AdminDateWidget
|
||||||
|
// and it's required media to context under {{media.js}} in admin/change_list.html.
|
||||||
|
// (Note: it accumulates media in django.forms.widgets.Media object,
|
||||||
|
// which prevents duplicates, but the DateRangeFilter is not included yet
|
||||||
|
// since it's not model field related.
|
||||||
|
// List of predefined widgets is in django.contrib.admin.options.FORMFIELD_FOR_DBFIELD_DEFAULTS)
|
||||||
|
// - After that Django starts rendering forms, which have the {{form.media}}
|
||||||
|
// tag. Only then the DjangoRangeFilter.get_media is called and rendered,
|
||||||
|
// which creates the duplicates.
|
||||||
|
// How it works:
|
||||||
|
// - first step is the same, if there's a AdminDateWidget to be loaded then
|
||||||
|
// nothing changes
|
||||||
|
// - DOM gets rendered and if the AdminDateWidget was rendered then
|
||||||
|
// the DateTimeShortcuts.js is initiated which sets the window.DateTimeShortcuts.
|
||||||
|
// Otherwise, the window.DateTimeShortcuts is undefined.
|
||||||
|
// - The lines below check if the DateTimeShortcuts has been set and if not
|
||||||
|
// then the DateTimeShortcuts.js and calendar.js is rendered
|
||||||
|
//
|
||||||
|
// https://github.com/silentsokolov/django-admin-rangefilter/issues/9
|
||||||
|
//
|
||||||
|
// Django 2.1
|
||||||
|
// https://github.com/silentsokolov/django-admin-rangefilter/issues/21
|
||||||
|
|
||||||
|
// Make a promise out of script embed
|
||||||
|
{% endcomment %}
|
||||||
|
function embedScript(url) {
|
||||||
|
return new Promise(function pr(resolve, reject) {
|
||||||
|
var newScript = document.createElement("script");
|
||||||
|
newScript.type = "text/javascript";
|
||||||
|
newScript.src = url;
|
||||||
|
newScript.onload = resolve;
|
||||||
|
newScript.setAttribute("nonce", "{{ spec.request.csp_nonce }}");
|
||||||
|
document.head.appendChild(newScript);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
django.jQuery('document').ready(function () {
|
||||||
|
if (!('DateTimeShortcuts' in window)) {
|
||||||
|
var promiseList = [];
|
||||||
|
|
||||||
|
{% for m in spec.form.js %}
|
||||||
|
promiseList.push(embedScript("{{ m }}"));
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Promise.all(promiseList).then(function() {
|
||||||
|
django.jQuery('.datetimeshortcuts').remove();
|
||||||
|
window.DateTimeShortcuts.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="admindatefilter">
|
||||||
|
<form method="GET" action="." id="{{ choices.0.system_name }}-form">
|
||||||
|
{{ spec.form.as_p }}
|
||||||
|
{% for choice in choices %}
|
||||||
|
<input type="hidden" id="{{ choice.system_name }}-query-string" value="{{ choice.query_string }}">
|
||||||
|
{% endfor %}
|
||||||
|
<div class="controls">
|
||||||
|
<input type="submit" class="button" value="{% trans "Search" %}">
|
||||||
|
<input type="reset" class="button" value="{% trans "Reset" %}">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% comment %} JS not requiring template variables refactored as an iife {% endcomment %}
|
||||||
|
<script type="text/javascript" src="{% static 'rangefilter/iife.js' %}"></script>
|
@@ -0,0 +1,16 @@
|
|||||||
|
{% extends 'rangefilter/date_filter.html' %}
|
||||||
|
|
||||||
|
{% block quick-select-choices %}
|
||||||
|
{% comment %}
|
||||||
|
The following code under the <ul> tag belongs to admin/filter.html:
|
||||||
|
https://github.com/django/django/blob/stable/2.2.x/django/contrib/admin/templates/admin/filter.html#L3-L8
|
||||||
|
{% endcomment %}
|
||||||
|
<ul>
|
||||||
|
{% for choice in choices %}
|
||||||
|
<li{% if choice.selected %} class="selected"{% endif %}>
|
||||||
|
<a href="{{ choice.query_string|iriencode }}"
|
||||||
|
title="{{ choice.display }}">{{ choice.display }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
59
templates/rangefilter/numeric_filter.html
Normal file
59
templates/rangefilter/numeric_filter.html
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
{% load i18n rangefilter_compat %}
|
||||||
|
<h3>{{ title }}</h3>
|
||||||
|
<style>
|
||||||
|
{% default_css_vars_if_needed %}
|
||||||
|
.numericrangefilter .button, .numericrangefilter input[type=submit], .numericrangefilter input[type=button], .numericrangefilter .submit-row input, .numericrangefilter a.button,
|
||||||
|
.numericrangefilter .button, .numericrangefilter input[type=reset] {
|
||||||
|
background: var(--button-bg);
|
||||||
|
padding: 4px 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--button-fg);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.numericrangefilter {
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
.numericrangefilter p {
|
||||||
|
padding-left: 0px;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.numericrangefilter p input {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 70px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% comment %}
|
||||||
|
Force load jsi18n, issues #5
|
||||||
|
https://github.com/django/django/blob/stable/1.10.x/django/contrib/admin/templates/admin/change_list.html#L7
|
||||||
|
{% endcomment %}
|
||||||
|
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||||
|
<script>
|
||||||
|
function filter_apply(event, qs_name){
|
||||||
|
event.preventDefault();
|
||||||
|
const $form = django.jQuery(event.target).closest('form');
|
||||||
|
const query_string = $form.find('input#'+qs_name).val();
|
||||||
|
const form_data = $form.serialize();
|
||||||
|
const amp = query_string === "?" ? "" : "&"; // avoid leading ?& combination
|
||||||
|
window.location = window.location.pathname + query_string + amp + form_data;
|
||||||
|
}
|
||||||
|
function filter_reset(event, qs_name){
|
||||||
|
const $form = django.jQuery(event.target).closest('form');
|
||||||
|
const query_string = $form.find('input#' + qs_name).val();
|
||||||
|
window.location = window.location.pathname + query_string;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<div class="numericrangefilter">
|
||||||
|
<form method="GET" action="." id="{{ choices.0.system_name }}-form">
|
||||||
|
{{ spec.form.as_p }}
|
||||||
|
{% for choice in choices %}
|
||||||
|
<input type="hidden" id="{{ choice.system_name }}-query-string" value="{{ choice.query_string }}">
|
||||||
|
{% endfor %}
|
||||||
|
<div class="controls">
|
||||||
|
<input type="submit" class="button" value="{% trans "Search" %}" onclick="filter_apply(event, '{{ choices.0.system_name }}-query-string')">
|
||||||
|
<input type="reset" class="button" value="{% trans "Reset" %}" onclick="filter_reset(event, '{{ choices.0.system_name }}-query-string')">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
Reference in New Issue
Block a user