#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2010-2013 Étienne Loks # Copyright (C) 2007 skam # (http://djangosnippets.org/snippets/233/) # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # See the file COPYING for details. from django import forms from django.conf import settings from django.core.urlresolvers import resolve, reverse from django.db.models import fields from django.forms.widgets import flatatt from django.template import Context, loader from django.utils.encoding import smart_unicode from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.simplejson import JSONEncoder from django.utils.translation import ugettext_lazy as _ import models class DeleteWidget(forms.CheckboxInput): def render(self, name, value, attrs=None): final_attrs = flatatt(self.build_attrs(attrs, name=name, value='1')) output = [''] output.append(u"%s" % (final_attrs, _("Delete"))) output.append('') return mark_safe('\n'.join(output)) class SquareMeterWidget(forms.TextInput): def render(self, name, value, attrs=None): if not value: value = u"" final_attrs = flatatt(self.build_attrs(attrs, name=name, value=value)) dct = {'final_attrs':final_attrs, 'unit':settings.SURFACE_UNIT_LABEL, 'id':attrs['id'], "safe_id":attrs['id'].replace('-', '_')} t = loader.get_template('blocks/SquareMeterWidget.html') rendered += t.render(Context(dct)) return mark_safe(rendered) AreaWidget = forms.TextInput if settings.SURFACE_UNIT == 'square-metre': global AreaWidget AreaWidget = SquareMeterWidget class JQueryDate(forms.TextInput): def __init__(self, *args, **kwargs): super(JQueryDate, self).__init__(*args, **kwargs) if 'class' not in self.attrs: self.attrs['class'] = '' self.attrs['class'] = 'date-pickup' def render(self, name, value=None, attrs=None): rendered = super(JQueryDate, self).render(name, value, attrs) # use window.onload to be sure that datepicker don't interfere # with autocomplete fields rendered += """ """ % {"name":name, "country":settings.COUNTRY} return rendered class JQueryAutoComplete(forms.TextInput): def __init__(self, source, associated_model=None, options={}, attrs={}, new=False): """ Source can be a list containing the autocomplete values or a string containing the url used for the request. """ self.options = None self.attrs = {} self.source = source self.associated_model = associated_model if len(options) > 0: self.options = JSONEncoder().encode(options) self.attrs.update(attrs) self.new = new def render_js(self, field_id): if isinstance(self.source, list): source = JSONEncoder().encode(self.source) elif isinstance(self.source, str) or isinstance(self.source, unicode): source = "'%s'" % escape(self.source) else: try: source = "'" + unicode(self.source) + "'" except: raise ValueError('source type is not valid') options = 'source : ' + source options += ''', select: function( event, ui ) { if(ui.item){ $('#id_%s').val(ui.item.id); } else { $('#id_%s').val(null); } }, minLength: 2 ''' % (field_id, field_id) if self.options: options += ',%s' % self.options js = u'$(\'#id_select_%s\').autocomplete({%s});\n' % (field_id, options) js += u'''$(\'#id_select_%s\').live('click', function(){ $('#id_%s').val(null); $('#id_select_%s').val(null); });''' % (field_id, field_id, field_id) return js def render(self, name, value=None, attrs=None): attrs_hidden = self.build_attrs(attrs, name=name) attrs_select = self.build_attrs(attrs) if value: val = escape(smart_unicode(value)) attrs_hidden['value'] = val attrs_select['value'] = val if self.associated_model: try: attrs_select['value'] = unicode( self.associated_model.objects.get(pk=value)) except: attrs_select['value'] = "" if not self.attrs.has_key('id'): attrs_hidden['id'] = 'id_%s' % name attrs_select['id'] = 'id_select_%s' % name if 'class' not in attrs_select: attrs_select['class'] = 'autocomplete' new = '' if self.new: model_name = self.associated_model._meta.object_name.lower() url_new = reverse('new-' + model_name, args=[attrs_select['id']]) new = u' +' % url_new html = u'''%(new)s\ \ ''' % { 'attrs_select' : flatatt(attrs_select), 'attrs_hidden' : flatatt(attrs_hidden), 'js' : self.render_js(name), 'new':new } return html class JQueryJqGrid(forms.RadioSelect): COL_TPL = "{name:'%(idx)s', index:'%(idx)s', sortable:true}" class Media: js = ['%s/js/i18n/grid.locale-%s.js' % (settings.STATIC_URL, settings.COUNTRY), '%s/js/jquery.jqGrid.min.js' % settings.STATIC_URL, ] css = {'all':['%s/media/ui.jqgrid.css' % settings.STATIC_URL, ]} def __init__(self, source, form, associated_model, attrs={}, table_cols='TABLE_COLS', multiple=False, multiple_cols=[2], new=False, new_message="", source_full=None): self.source = source self.form = form self.attrs = attrs self.associated_model = associated_model self.table_cols = table_cols self.multiple = multiple self.multiple_cols = multiple_cols self.new, self.new_message = new, new_message self.source_full = source_full def render(self, name, value=None, attrs=None): t = loader.get_template('blocks/form_snippet.html') form = self.form() rendered = t.render(Context({'form':form})) dct = {} if self.new: model_name = self.associated_model._meta.object_name.lower() dct['url_new'] = reverse('new-' + model_name, args=['0']) dct['new_message'] = self.new_message extra_cols = [] col_names, col_idx = [], [] for k in form.get_input_ids(): #field = form.fields[k] col_idx.append(u'"%s"' % k) for field_name in getattr(self.associated_model, self.table_cols): field = self.associated_model keys = field_name.split('.') field_verbose_name = "" for key in keys: if hasattr(field, 'rel'): field = field.rel.to try: field = field._meta.get_field(key) field_verbose_name = field.verbose_name field_name = field.name except fields.FieldDoesNotExist: if hasattr(field, key + '_lbl'): field_name = key field_verbose_name = getattr(field, key + '_lbl') else: continue col_names.append(u'"%s"' % field_verbose_name) extra_cols.append(self.COL_TPL % {'idx':field_name}) col_names = col_names and ", ".join(col_names) or "" col_idx = col_idx and ", ".join(col_idx) or "" extra_cols = extra_cols and ", ".join(extra_cols) or "" dct['encoding'] = settings.ENCODING or 'utf-8' dct['source'] = unicode(self.source) if unicode(self.source_full) and unicode(self.source_full) != 'None': dct['source_full'] = unicode(self.source_full) dct.update({'name':name, 'col_names':col_names, 'extra_cols':extra_cols, 'source':unicode(self.source), 'col_idx':col_idx, 'no_result':unicode(_("No results")), 'loading':unicode(_("Loading...")), 'remove':unicode(_(u"Remove")), 'sname':name.replace('-', ''), 'multiple':self.multiple, 'multi_cols': ",".join((u'"%d"' % col \ for col in self.multiple_cols)) }) t = loader.get_template('blocks/JQueryJqGrid.html') rendered += t.render(Context(dct)) return mark_safe(rendered)