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そしてここに私の解決策があります:

基本的な考え方は、入力が隠されたフォームセットを生成することです。そのうちの1つは、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 に答える