Skip to content

Commit

Permalink
added a LinkWidget as well as docs and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Feb 18, 2009
1 parent 2f15e95 commit 88d7072
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
6 changes: 5 additions & 1 deletion docs/ref/filters.txt
Expand Up @@ -86,7 +86,11 @@ argument.
``widget`` ``widget``
~~~~~~~~~~ ~~~~~~~~~~


The django.form Widget class which will represent the ``Filter``. The django.form Widget class which will represent the ``Filter``. In addition
to the widgets that are included with Django that you can use there are
additional ones that django-filte provides which may be useful:
* ``filter.widgets.LinkWidget`` -- this displays the options in a mannner
similar to the way the Django Admin does, as a series of links.


``action`` ``action``
~~~~~~~~~~ ~~~~~~~~~~
Expand Down
23 changes: 23 additions & 0 deletions filter/tests.py
Expand Up @@ -3,6 +3,7 @@
>>> from django.core.management import call_command >>> from django.core.management import call_command
>>> import filter >>> import filter
>>> from filter import FilterSet >>> from filter import FilterSet
>>> from filter.widgets import LinkWidget
>>> from filter.models import User, Comment, Book, STATUS_CHOICES >>> from filter.models import User, Comment, Book, STATUS_CHOICES
>>> call_command('loaddata', 'test_data', verbosity=0) >>> call_command('loaddata', 'test_data', verbosity=0)
Expand Down Expand Up @@ -275,5 +276,27 @@
>>> f= F({'price_0': '15', 'price_1': 'lt'}) >>> f= F({'price_0': '15', 'price_1': 'lt'})
>>> f.qs >>> f.qs
[<Book: Ender's Game>] [<Book: Ender's Game>]
>>> class F(FilterSet):
... status = filter.ChoiceFilter(widget=LinkWidget, choices=STATUS_CHOICES)
... class Meta:
... model = User
... fields = ['status']
>>> f = F()
>>> f.qs
[<User: alex>, <User: aaron>, <User: jacob>]
>>> print f.form
<tr><th><label for="id_status">Status:</label></th><td><ul id="id_status">
<a href="?status=0">Regular</a>
<a href="?status=1">Admin</a>
</ul></td></tr>
>>> f = F({'status': '1'})
>>> f.qs
[<User: alex>]
>>> print f.form
<tr><th><label for="id_status">Status:</label></th><td><ul id="id_status">
<a href="?status=0">Regular</a>
<a href="?status=1">Admin</a>
</ul></td></tr>
"""} """}


48 changes: 48 additions & 0 deletions filter/widgets.py
@@ -1,4 +1,52 @@
from itertools import chain
from urllib import urlencode

from django import forms from django import forms
from django.forms.widgets import flatatt
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe

class LinkWidget(forms.Widget):
def __init__(self, attrs=None, choices=()):
super(LinkWidget, self).__init__(attrs)

self.choices = list(choices)

def value_from_datadict(self, data, files, name):
value = super(LinkWidget, self).value_from_datadict(data, files, name)
self.data = data
return value

def render(self, name, value, attrs=None, choices=()):
if value is None:
value = ''
final_attrs = self.build_attrs(attrs)
output = [u'<ul%s>' % flatatt(final_attrs)]
options = self.render_options(choices, [value], name)
if options:
output.append(options)
output.append('</ul>')
return mark_safe(u'\n'.join(output))

def render_options(self, choices, selected_choices, name):
def render_option(option_value, option_label):
option_value = force_unicode(option_value)
data = self.data.copy()
data[name] = option_value
try:
url = data.urlencode()
except AttributeError:
url = '?%s' % urlencode(data)
return '<a href="%s">%s</a>' % (url, option_label)
selected_choices = set(force_unicode(v) for v in selected_choices)
output = []
for option_value, option_label in chain(self.choices, choices):
if isinstance(option_label, (list, tuple)):
for option in option_label:
output.append(render_option(*option))
else:
output.append(render_option(option_value, option_label))
return u'\n'.join(output)


class RangeWidget(forms.MultiWidget): class RangeWidget(forms.MultiWidget):
def __init__(self, attrs=None): def __init__(self, attrs=None):
Expand Down

0 comments on commit 88d7072

Please sign in to comment.