2012-08-31 6 views
2

Je voudrais utiliser jQueryUI Slider comme widget permettant de configurer les heures d'ouverture.Django - Widget intervalle de temps

Je l'ai fait des modèles:

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') 

Je sais que le balisage pour faire les contrôleurs tels que:

<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> 

Ce qui donne quelque chose de similaire (avec quelques css/js additionnels)

enter image description here

Mais je suis incapable de l'implémenter comme un m widget de

+0

Avec quoi traitez-vous exactement? – XORcist

+0

Peut-être lié: http://stackoverflow.com/questions/4707192/django-how-to-build-a-custom-form-widget – XORcist

+1

Le curseur n'est pas lié à une entrée de formulaire, vous devrez donc ajouter des rappels à l'événement slider 'stop' et remplissent certaines entrées cachées en conséquence afin qu'un formulaire puisse publier ces données. Pour rendre une telle chose et le script requis pour cela, vous devrez créer un widget de formulaire personnalisé et remplacer sa méthode 'render' pour ajouter cette DIV supplémentaire, entrée cachée, et le balisage de script –

Répondre

2

Merci @YujiTomita pour commentaires et voici ma solution:

L'idée de base est de générer un formset avec des entrées cachées, l'une qui appelle une css/javascript.
Et javascript va remplir les valeurs.

widget de

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', 
     )} 

forme

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'}), 
     } 

vue

UserOpeningHoursFormSet = formset_factory(UserOpeningHoursForm, extra=0) 
obj['formset'] = UserOpeningHoursFormSet(initial=hours) 

t Emplate

<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 (avec 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() et mtt() sont des fonctions de conversions minutes en temps/formatage

css
#slider-block-hidden { 
    display: none; 
} 

.slider-block { 
    text-align: center; 
    display: inline-block; 
    margin: 10px; 
} 

.slider { 
    margin: 10px; 
    height: 150px; 
} 

Peut-être qu'il y aurait un moyen de rendre le widget de sous-classe pour éviter beaucoup de javascript.