Login

Facebook event selector field

Author:
jokull
Posted:
August 19, 2009
Language:
Python
Version:
1.1
Score:
0 (after 0 ratings)

Ripped this out of a project I'm working on. The field renders as two <select> elements representing the two-level hierarchy organized events Facebook uses. Returns the id's Facebook wants.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from django.utils.translation import ugettext as _
from django.forms import MultiValueField
from django.forms.widgets import Widget, Select
from django.utils.safestring import mark_safe
from django.utils import simplejson

"""    
var categorySelect = function(el, target, tree){
  var list = tree[el.getValue()];
  target.setTextValue('');
  for (var key = 0; key < list.length; key++){
    var option = document.createElement('option');
    option.setValue(list[key][0]);
    option.setTextValue(list[key][1]);
    target.appendChild(option);
  }
};

"""

class CategorySelect(Widget):
    
    category_name = '%s_category'
    
    def __init__(self, choice_tree, attrs=None):
        self.attrs = attrs or {}
        category_choices = []
        choices_map = {}
        for cat_id, cat_label, subcats in choice_tree:
            category_choices += ((cat_id, cat_label),)
            choices_map[cat_id] = subcats
        self.category_choices = category_choices
        self.choices_map = choices_map
    
    def value_from_datadict(self, data, files, name):
        cat_value = data.get(self.category_name % name, '')
        subcat_value = data.get(name, '')
        return cat_value, subcat_value
    
    def render(self, name, value, attrs={}):
        # Value is id of the bottom choice.
        category_value = None
        choices = ()
        if value:
            for cat_id, subcats in self.choices_map.items():
                for subcat_id, subcat_label in subcats:
                    if str(subcat_id) == str(value):
                        category_value = str(cat_id)
                        choices = subcats
                        break
        else:
            category_value = self.category_choices[0][1]
            choices = self.choices_map.values()[0]
        output = []
        category_id = 'id_%s_category' % name
        category_attrs = {
            'id': category_id,
            'onchange': 'categorySelect(this, document.getElementById(\'id_%s\'), %s);' % \
                    (name, simplejson.dumps(self.choices_map))
        }
        output.append(Select().render(self.category_name % name, category_value, category_attrs, self.category_choices))
        output.append(Select().render(name, value, attrs, choices))
        
        return mark_safe(u'\n'.join(output))


class CategoryField(MultiValueField):
    
    FACEBOOK_EVENT_SUBCATEGORIES = [
        _('Birthday Party'), 
        _('Cocktail Party'), 
        _('Club Party'), 
        _('Potluck'), 
        _('Fraternity/Sorority Party'), 
        _('Business Meeting'), 
        _('Barbecue'), 
        _('Card Night'), 
        _('Dinner Party'), 
        _('Holiday Party'), 
        _('Night of Mayhem'), 
        _('Movie/TV Night'), 
        _('Drinking Games'), 
        _('Bar Night'), 
        _('LAN Party'), 
        _('Brunch'), 
        _('Mixer'), 
        _('Slumber Party'), 
        _('Erotic Party'), 
        _('Benefit'), 
        _('Goodbye Party'), 
        _('House Party'), 
        _('Reunion'), 
        _('Fundraiser'), 
        _('Protest'), 
        _('Rally'), 
        _('Class'), 
        _('Lecture'), 
        _('Office Hours'), 
        _('Workshop'), 
        _('Club/Group Meeting'), 
        _('Convention'), 
        _('Dorm/House Meeting'), 
        _('Informational Meeting'), 
        _('Audition'), 
        _('Exhibit'), 
        _('Jam Session'), 
        _('Listening Party'), 
        _('Opening'), 
        _('Performance'), 
        _('Preview'), 
        _('Recital'), 
        _('Rehearsal'), 
        _('Pep Rally'), 
        _('Pick-Up'), 
        _('Sporting Event'), 
        _('Sports Practice'), 
        _('Tournament'), 
        _('Camping Trip'), 
        _('Daytrip'), 
        _('Group Trip'), 
        _('Roadtrip'), 
        _('Carnival'), 
        _('Ceremony'), 
        _('Festival'), 
        _('Flea Market'), 
        _('Retail')]

    FACEBOOK_EVENTS = (
        (_('Party'),       (0,23)),
        (_('Causes'),     (23,27)),
        (_('Education'),  (27,31)),
        (_('Meetings'),   (31,36)),
        (_('Music/Arts'), (36,45)),
        (_('Sports'),     (45,48)),
        (_('Trips'),      (48,53)),
        (_('Other'),      (53,-1))
        )
    
    def __init__(self, *args, **kwargs):
        super(CategoryField, self).__init__(widget=CategorySelect(self.get_facebook_event_tree()), *args, **kwargs)
    
    def get_facebook_event_tree(self):
        # Output a tree structure, more easily handled by client side code
        results = []
        for i, category in enumerate(self.FACEBOOK_EVENTS):
            category_label, slices = category
            s1, s2 = slices
            subcats = zip(range(*slices), self.FACEBOOK_EVENT_SUBCATEGORIES[s1:s2])
            results += ((i, category_label, subcats),)
        return results
    
    def clean(self, value):
        try:
            if [int(b) for b in value if b]:
                return value
        except ValueError:
            raise forms.ValidationError(_('You must select a category and subcategory for your event.'))
        return [None, None]

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.