Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- from django import forms
- from django.utils.safestring import mark_safe
- from django.utils.encoding import force_unicode
- from django.core.urlresolvers import reverse
- from django.forms.util import ErrorList, ValidationError
- from django.utils.translation import ugettext as _
- CLIENT_CODE = u"""
- <input type="text" class="ac_input" name="%(name)s_text" id="%(html_id)s_text" value="%(text)s"/>
- <input type="hidden" name="%(name)s" id="%(html_id)s" value="%(value)s" />
- <script type="text/javascript">
- $(function(){
- $("#%(html_id)s_text").autocomplete({
- 'source': '%(url)s',
- 'minLength': 2,
- 'select': function(event, ui) {
- $("#%(html_id)s")
- .val(ui.item.id)
- .data('prev', ui.item.label)
- .trigger('change');
- %(callback)s
- },
- 'close': function(event, ui) {
- // dont restore the old value here. It should be better to restore it in the blur-function */
- /*setTimeout(function() {
- var prev = $('#%(html_id)s').data('prev');
- $("#%(html_id)s_text").val(prev);
- }, 100);*/
- }
- })
- .blur(function() {
- var prev = $('#%(html_id)s').data('prev');
- $("#%(html_id)s_text").val(prev);
- })
- .data("autocomplete")._renderItem = function( ul, item ) {
- return $( "<li></li>" )
- .data( "item.autocomplete", item )
- .append( "<a>" + item.label + "</a>" )
- .appendTo( ul );
- };
- // Speichern des initialien Werts
- $("#%(html_id)s").data('prev', '%(value)s');
- });
- </script>
- """
- class ModelAutoCompleteWidget(forms.widgets.TextInput):
- """
- Autocomplete-Widget. Rendert die Inputs und das JAvascript um das AutoComplete-Field
- einzubinden. Kann nur in Verbindung mit dem ModelAutoCompleteField benutzt werden.
- (Fuer den Text-wert wird das Model benoetigt, es wird also vom Field an dieses Widget
- weitergegeben)
- """
- def __init__(self, url, model, callback=None, *args, **kw):
- super(forms.widgets.TextInput, self).__init__(*args, **kw)
- self.url = url
- self.model = model
- self.callback = callback
- def render(self, name, value, attrs=None):
- """
- Rendert das Widget
- `name`
- Der Name des Widgets
- `value`
- Der Wert den der Hauptinput (In diesem Fall ID) haben soll
- """
- # Defaults falls was nicht Ok ist:
- text = ''
- val = ''
- # Wenn Wert gegeben wurde versuchen die Daten zu holen
- if value != None:
- try:
- text = self.model.objects.get(pk=value)
- val = value
- except Exception:
- pass
- html_id = attrs.get('id', name)
- url = self.url() if callable(self.url) else self.url
- callback = u"%s(ui.item.id);" % self.callback if self.callback else ""
- return mark_safe(CLIENT_CODE % dict(name=name, html_id=html_id, url=url, value=val, text=text, callback=callback))
- def value_from_datadict(self, data, files, name):
- """
- Given a dictionary of data and this widget's name, returns the value
- of this widget. Returns None if it's not provided.
- """
- return data.get(name, None)
- class ModelAutoCompleteField(forms.fields.CharField):
- """
- Autocomplete-Feld das die gelesenen Werte direkt zurueck in Django-Model-Objekte
- konvertiert. Als Widget wird das AutoCOmpleteWidget von oben benutzt, was die
- JavaScript-Logik und Felder korrekt fuellt.
- Momentan muss ein gueltiger WErt selektiert werden.
- """
- default_error_messages = {
- 'invalid_choice': mark_safe(u'Keine gültige Auswahl. Bitte eine gültige Option wählen.'),
- 'no_choice' : mark_safe(u'Kein Eintrag ausgewählt. Bitte wählen sie einen Eintrag.'),
- }
- def __init__(self, model, url, callback=None,size=None, *args, **kwargs):
- """
- Neues AutoCOmpleteField anlegen
- `model`
- Das Model auf dem die Vervollstaendigung beruht.
- `url`
- Die URL aus der die Callbackdatan angefragt werden
- """
- self.model = model
- # build attrs for widget
- attrs = {'size': size} if size else {}
- super(ModelAutoCompleteField, self).__init__(
- widget = ModelAutoCompleteWidget(url=url, model=model, callback=callback, attrs=attrs),
- *args,
- **kwargs)
- def update_url(self, url):
- self.widget.url = url
- def clean(self, value):
- """
- Die Methode konvertiert die ID des HiddenFields zurueck in ein Django-MOdel
- """
- # Kein WErt gegeben, es wird aber auch keiner gebraucht
- if value=='' and not self.required:
- return None
- # Wenn kein Wert gegeben ist kann auch kein Model gelesen werden
- if value=='':
- raise ValidationError(self.error_messages['no_choice'])
- # Versuchen das Objekt zu lesen
- try:
- obj = self.model.objects.get(pk=value)
- except self.model.DoesNotExist:
- raise ValidationError(self.error_messages['invalid_choice'])
- return obj
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement