Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

from django.forms.widgets import Input, MultiWidget, FileInput 

from django.core.validators import EMPTY_VALUES 

from django.utils.safestring import mark_safe 

from django.core.files.uploadedfile import UploadedFile 

 

try: 

    unicode 

except NameError: 

    unicode = str 

 

__all__ = ['RadioInput', 'URLInput', 'MutuallyExclusiveRadioWidget', 

           'FileOrURLWidget'] 

 

 

class RadioInput(Input): 

    input_type = 'radio' 

 

 

# for compatiblity with older Django verisons 

class URLInput(Input): 

    input_type = 'url' 

 

 

class MutuallyExclusiveRadioWidget(MultiWidget): 

    def render(self, name, value, attrs=None): 

        if self.is_localized: 

            for widget in self.widgets: 

                widget.is_localized = self.is_localized 

        # value is a list of values, each corresponding to a widget 

        # in self.widgets. 

        if not isinstance(value, list): 

            value = self.decompress(value) 

        output = [] 

        final_attrs = self.build_attrs(attrs) 

        id_ = final_attrs.get('id', None) 

        nonempty_widget = 0 

        for i, widget in enumerate(self.widgets): 

            try: 

                widget_value = value[i] 

            except IndexError: 

                widget_value = None 

            else: 

                if widget_value not in EMPTY_VALUES: 

                    nonempty_widget = i 

            if id_: 

                final_attrs = dict(final_attrs, id='%s_%s' % (id_, i)) 

            output.append(widget.render( 

                name + '_%s' % i, widget_value, final_attrs)) 

        return mark_safe(unicode( 

            self.format_output(nonempty_widget, name, output))) 

 

    def format_output(self, nonempty_widget, name, rendered_widgets): 

        radio_widgets = [RadioInput().render( 

            name + '_radio', '', {})] * len(rendered_widgets) 

        if nonempty_widget is not None: 

            radio_widgets[nonempty_widget] = RadioInput().render( 

                name + '_radio', '', {'checked': ''}) 

        tpl = """ 

<span id="{name}_container" class="mutually-exclusive-widget" 

    style="display:inline-block"> 

    {widgets} 

</span>""" 

 

        return tpl.format(name=name, widgets='<br>'.join( 

            '<span>{0}</span>'.format(x + y) 

            for x, y in zip(radio_widgets, rendered_widgets))) 

 

    def decompress(self, value): 

        """ 

        If initialized with single compressed value we don't know what to do. 

        just so it doesn't 'splode, return empty list of right length 

        """ 

        return [''] * len(self.widgets) 

 

    class Media: 

        js = ('mutually_exclusive_widget.js',) 

 

 

class FileOrURLWidget(MutuallyExclusiveRadioWidget): 

    def __init__(self, attrs=None): 

        url_attrs = dict(placeholder='Enter URL') 

        if attrs is not None: 

            url_attrs.update(attrs) 

        widgets = (FileInput(attrs=attrs), URLInput(attrs=url_attrs)) 

        super(FileOrURLWidget, self).__init__(widgets, attrs) 

 

    def decompress(self, value): 

        if isinstance(value, UploadedFile): 

            return [value, ''] 

        else: 

            return ['', value] 

 

    def value_from_datadict(self, data, files, name): 

        # We want to accept a value via the name itself to support use in 

        # tastypie resources. 

        if name in data: 

            return self.decompress(data[name]) 

        elif name in files: 

            return self.decompress(files[name]) 

        else: 

            return super(FileOrURLWidget, self).value_from_datadict( 

                data, files, name)