#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2010-2011 É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.template import Context, loader from django.utils.safestring import mark_safe from django.forms.widgets import flatatt from django.utils.encoding import smart_unicode from django.utils.html import escape from django.utils.simplejson import JSONEncoder from django.core.urlresolvers import resolve, reverse from django.utils.translation import ugettext_lazy as _ from django.db.models import fields from ishtar import settings 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)) output = u' %s '\ u'(0 ha)' % (final_attrs, settings.SURFACE_UNIT_LABEL, attrs['id']) output += """ """ % {"id":attrs['id'], "safe_id":attrs['id'].replace('-', '_')} return mark_safe(output) 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.MEDIA_URL, settings.COUNTRY), '%s/js/jquery.jqGrid.min.js' % settings.MEDIA_URL, ] css = {'all':['%s/media/ui.jqgrid.css' % settings.MEDIA_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('form_snippet.html') rendered = t.render(Context({'form':self.form})) rendered += u"\n\n"\ u"" % ( name, unicode(_("Search"))) if self.new: model_name = self.associated_model._meta.object_name.lower() url_new = reverse('new-' + model_name) rendered += u'

'\ u'%s

' % (url_new, unicode(self.new_message)) rendered += "\n

%s

\n" % unicode(_("Search and select an item")) extra_cols = [] col_names, col_idx = [], [] for k in self.form.fields: field = self.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 ",\n".join(col_names) or "" col_idx = col_idx and ",\n".join(col_idx) or "" extra_cols = extra_cols and ",\n".join(extra_cols) or "" rendered += u"
\n"\ u"
\n"% (name, name) encoding = settings.ENCODING or 'utf-8' rendered += u"
\n" % name if unicode(self.source_full): rendered += u"%s (%s) %s - "\ u"%s\n" % ( unicode(_("Export as CSV")), encoding, unicode(self.source), unicode(_(u"simple")), unicode(self.source_full), unicode(_(u"full")),) else: rendered += u'%s (%s)\n' % ( unicode(self.source), unicode(_("Export as CSV")), encoding) rendered += "
\n" if self.multiple: rendered += u''\ u'
    \n
\n' % ( name, unicode(_("Add")), name) rendered += '\n' % (name, name) dct = {'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('-', ''), 'multi_cols': ",".join((u'"%d"' % col \ for col in self.multiple_cols)) } rendered += """\n" return mark_safe(rendered)