diff options
Diffstat (limited to 'servo/forms/base.py')
-rw-r--r-- | servo/forms/base.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/servo/forms/base.py b/servo/forms/base.py new file mode 100644 index 0000000..83e2cd4 --- /dev/null +++ b/servo/forms/base.py @@ -0,0 +1,172 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013, First Party Software +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +import json +from django import forms +from django.forms.utils import flatatt +from django.utils.html import format_html +from django.utils.safestring import mark_safe + + +class NullCharField(forms.CharField): + def clean(self, value): + cleaned = super(NullCharField, self).clean(value) + return cleaned if len(cleaned) else None + + +class FullTextArea(forms.CharField): + widget = forms.Textarea(attrs={'class': 'span12'}) + + +class SearchField(forms.CharField): + widget = forms.TextInput(attrs={ + 'class': 'search-query', + 'autocomplete': 'off', + 'placeholder': '', + }) + + +class ChoiceField(forms.ChoiceField): + def __init__(self, *args, **kwargs): + super(ChoiceField, self).__init__(*args, **kwargs) + self.widget.attrs['class'] = 'span12' + + +class TextInput(forms.TextInput): + def __init__(self, *args, **kwargs): + super(TextInput, self).__init__(*args, **kwargs) + self.attrs['class'] = 'span12' + + +class AutocompleteCharField(forms.CharField): + widget = forms.TextInput(attrs={ + 'class' : "input typeahead", + 'data-provide' : "typeahead" + }) + + def __init__(self, values, *args, **kwargs): + super(AutocompleteCharField, self).__init__(*args, **kwargs) + + if not type(values) is str: + values = json.dumps(list(values)) + + self.widget.attrs['data-source'] = values + + +class AutocompleteTextarea(forms.Textarea): + def __init__(self, rows=8, choices=None): + super(AutocompleteTextarea, self).__init__() + self.attrs = { + 'rows': rows, + 'class': "span12 autocomplete", + 'data-source': json.dumps(choices) + } + + +class BaseForm(forms.Form): + required_css_class = "required" + + +class BaseModelForm(forms.ModelForm): + required_css_class = "required" + + +class SearchFieldInput(forms.TextInput): + + def render(self, name, value, attrs=None): + + field = super(SearchFieldInput, self).render(name, value, attrs) + final_attrs = self.build_attrs(attrs, name=name) + + output = format_html(u''' + <div class="input-group"> + {1} + <span class="input-group-btn"> + <button class="btn btn-default" type="button"><i class="glyphicon glyphicon-search"></i></button> + </span> + </div> + ''', flatatt(final_attrs), field) + + return mark_safe(output) + + +class DatepickerInput(forms.DateInput): + def __init__(self, *args, **kwargs): + kwargs['format'] = "%Y-%m-%d" + super(DatepickerInput, self).__init__(*args, **kwargs) + + def render(self, name, value, attrs=None): + + date_format = "yyyy-MM-dd" + + if "format" not in self.attrs: + attrs['format'] = date_format + + if "data-format" not in self.attrs: + attrs['data-format'] = date_format + + field = super(DatepickerInput, self).render(name, value, attrs) + final_attrs = self.build_attrs(attrs, name=name) + + output = format_html(u''' + <div class="input-append date datepicker" data-provide="datepicker" {0}> + {1} + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + ''', flatatt(final_attrs), field) + + return mark_safe(output) + + +class DateTimePickerInput(forms.DateTimeInput): + def __init__(self, *args, **kwargs): + kwargs['format'] = "%Y-%m-%d %H:%M" + super(DateTimePickerInput, self).__init__(*args, **kwargs) + + def render(self, name, value, attrs=None): + + date_format = "yyyy-MM-dd hh:mm" + + if "data-format" not in self.attrs: + attrs['data-format'] = date_format + if "class" not in self.attrs: + attrs['class'] = 'input-medium' + + field = super(DateTimePickerInput, self).render(name, value, attrs) + final_attrs = self.build_attrs(attrs, name=name) + + output = format_html(u''' + <div class="input-append date datetimepicker" {0}> + {1} + <span class="add-on"> + <i data-time-icon="icon-time" data-date-icon="icon-calendar"></i> + </span> + </div> + ''', flatatt(final_attrs), field) + + return mark_safe(output) |