2

我想使用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)

在此处输入图像描述

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

4

1 回答 1

2

感谢@YujiTomita 的评论,这是我的解决方案:

基本思想是生成一个带有隐藏输入的表单集,其中之一是调用一些 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。

于 2012-09-03T07:09:21.980 回答