【问题标题】:Django - Time range widgetDjango - 时间范围小部件
【发布时间】: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)

但我无法将其实现为表单小部件

【问题讨论】:

  • 你到底在纠结什么?
  • 滑块未绑定到表单输入,因此您必须将回调添加到滑块stop 事件并相应地填充一些隐藏的输入,以便表单可以发布此数据。要呈现这样的东西及其所需的脚本,您需要制作一个自定义表单小部件并覆盖其render 方法以添加这个额外的 DIV、隐藏输入和脚本标记
  • 将这一切变成一个单独的硬编码会容易得多。您所需要的只是将表单字段值作为隐藏输入,每当它更改时,都需要使用此滑块小部件中的值填充。
  • 谢谢,我没有想到用javascript填充的隐藏输入。

标签: django jquery-ui jquery-ui-slider django-widget


【解决方案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。

【讨论】:

    猜你喜欢
    • 2022-07-08
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 2017-08-05
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多