Django - 时间范围小部件
Posted
技术标签:
【中文标题】Django - 时间范围小部件【英文标题】:Django - Time range widget 【发布时间】:2012-08-26 09:49:10 【问题描述】:我想使用jQueryUI Slider 作为允许配置营业时间的小部件。
所以我做了这个模型:
WEEKDAYS = [
(1, _("Monday")),
(2, _("Tuesday")),
(3, _("Wednesday")),
(4, _("Thursday")),
(5, _("Friday")),
(6, _("Saturday")),
(7, _("Sunday")),
]
class OpeningHours(models.Model)
comp = models.ForeignKey('Company')
weekday = models.IntegerField(choices=WEEKDAYS, unique=True)
from_hour = models.TimeField()
to_hour = models.TimeField()
class Company(models.Model):
name = models.CharField(max_length=100)
logo = models.FileField(upload_to='company_logos')
我知道执行控制器的标记,例如:
<div class="slider-block">
<div class="slider-end">18:00</div>
<div class="slider"></div>
<div class="slider-start">08:00</div>
<div class="slider-day">Tue</div>
</div>
这给出了类似的东西(带有一些额外的 css/js)
但我无法将其实现为表单小部件
【问题讨论】:
你到底在纠结什么? 可能相关:***.com/questions/4707192/… 滑块未绑定到表单输入,因此您必须将回调添加到滑块stop
事件并相应地填充一些隐藏的输入,以便表单可以发布此数据。要呈现这样的东西及其所需的脚本,您需要制作一个自定义表单小部件并覆盖其render
方法以添加这个额外的 DIV、隐藏输入和脚本标记
将这一切变成一个单独的硬编码会容易得多。您所需要的只是将表单字段值作为隐藏输入,每当它更改时,都需要使用此滑块小部件中的值填充。
谢谢,我没有想到用javascript填充的隐藏输入。
【参考方案1】:
感谢@YujiTomita 提供 cmets,这是我的解决方案:
基本思想是生成一个带有隐藏输入的表单集,其中之一是调用一些 css/javascript。 并且 javascript 将填充这些值。
小部件
class OpeningHoursWidget(forms.HiddenInput):
class Media:
js = (
'https://ajax.googleapis.com/[...]jquery-ui.min.js',
'js/business_hours.js',
)
css = 'all': (
'https://ajax.googleapis.com/[...]jquery-ui.custom.css',
'css/business_hours.css',
)
表格
class UserOpeningHoursForm(forms.ModelForm):
class Meta:
model = OpeningHours
fields = ('weekday', 'from_hour', 'to_hour')
widgets =
'weekday': forms.HiddenInput(attrs='class': 'hours-weekday'),
'from_hour': OpeningHoursWidget(attrs='class': 'hours-start'),
'to_hour': forms.HiddenInput(attrs='class': 'hours-end'),
查看
UserOpeningHoursFormSet = formset_factory(UserOpeningHoursForm, extra=0)
obj['formset'] = UserOpeningHoursFormSet(initial=hours)
模板
<div id="slider-block-hidden">
<div class="slider-end"></div>
<div class="slider"></div>
<div class="slider-start"></div>
<div class="slider-day"></div>
</div>
formset.media
% for hours in formset %
<div class="slider-block">
hours
</div>
% endfor %
javascript(使用 jquery)
$(function()
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
$('.slider-block').each(function ()
start = $(this).find('.hours-start').val();
end = $(this).find('.hours-end').val();
day_id = $(this).find('.hours-weekday').val();
hidden_slider = $('#slider-block-hidden').clone();
$(this).append(hidden_slider.find('.slider-end').text(end));
$(this).append((slider = hidden_slider.find('.slider')));
$(this).append(hidden_slider.find('.slider-start').text(start));
$(this).append(hidden_slider.find('.slider-day').text(days[day_id]));
slider.slider(
orientation: "vertical",
range: true,
min: 0,
max: 1440,
step: 15,
values: [ ttm(start), ttm(end) ],
slide: function( event, ui )
$(this).siblings('.slider-start').text(mtt(ui.values[0]));
$(this).siblings('.slider-end').text(mtt(ui.values[1]));
);
);
);
ttm()
和 mtt()
是用于分钟时间转换/格式化的函数
css
#slider-block-hidden
display: none;
.slider-block
text-align: center;
display: inline-block;
margin: 10px;
.slider
margin: 10px;
height: 150px;
也许有一种方法可以对小部件的渲染进行子类化以避免大量的 javascript。
【讨论】:
以上是关于Django - 时间范围小部件的主要内容,如果未能解决你的问题,请参考以下文章
如何引用似乎超出范围的小部件 - 改编的 kivy/examples/demo/images