Advertisement
Guest User

Untitled

a guest
Apr 8th, 2013
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.63 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. from django import forms
  3. from django.utils.safestring import mark_safe
  4. from django.utils.encoding import force_unicode
  5. from django.core.urlresolvers import reverse
  6. from django.forms.util import ErrorList, ValidationError
  7. from django.utils.translation import ugettext as _
  8.  
  9.  
  10. CLIENT_CODE = u"""
  11. <input type="text" class="ac_input" name="%(name)s_text" id="%(html_id)s_text" value="%(text)s"/>
  12. <input type="hidden" name="%(name)s" id="%(html_id)s" value="%(value)s" />
  13. <script type="text/javascript">
  14.    $(function(){
  15.        $("#%(html_id)s_text").autocomplete({
  16.            'source': '%(url)s',
  17.            'minLength': 2,
  18.            'select': function(event, ui) {
  19.                 $("#%(html_id)s")
  20.                     .val(ui.item.id)
  21.                     .data('prev', ui.item.label)
  22.                     .trigger('change');
  23.                %(callback)s
  24.            },
  25.            'close': function(event, ui) {
  26.                // dont restore the old value here. It should be better to restore it in the blur-function */
  27.                /*setTimeout(function() {
  28.                    var prev = $('#%(html_id)s').data('prev');
  29.                    $("#%(html_id)s_text").val(prev);
  30.                }, 100);*/
  31.            }
  32.        })  
  33.        .blur(function() {
  34.            var prev = $('#%(html_id)s').data('prev');
  35.            $("#%(html_id)s_text").val(prev);
  36.        })    
  37.        .data("autocomplete")._renderItem = function( ul, item ) {
  38.            return $( "<li></li>" )
  39.                .data( "item.autocomplete", item )
  40.                .append( "<a>" + item.label + "</a>" )
  41.                .appendTo( ul );
  42.        };
  43.        
  44.         // Speichern des initialien Werts
  45.        $("#%(html_id)s").data('prev', '%(value)s');
  46.    });
  47. </script>
  48. """
  49.  
  50. class ModelAutoCompleteWidget(forms.widgets.TextInput):
  51.     """
  52.    Autocomplete-Widget. Rendert die Inputs und das JAvascript um das AutoComplete-Field
  53.    einzubinden. Kann nur in Verbindung mit dem ModelAutoCompleteField benutzt werden.
  54.    (Fuer den Text-wert wird das Model benoetigt, es wird also vom Field an dieses Widget
  55.    weitergegeben)
  56.    """
  57.     def __init__(self, url, model, callback=None, *args, **kw):
  58.         super(forms.widgets.TextInput, self).__init__(*args, **kw)
  59.         self.url = url
  60.         self.model = model
  61.         self.callback = callback
  62.        
  63.        
  64.  
  65.     def render(self, name, value, attrs=None):
  66.         """
  67.        Rendert das Widget
  68.        `name`
  69.            Der Name des Widgets
  70.        `value`
  71.            Der Wert den der Hauptinput (In diesem Fall ID) haben soll
  72.        """
  73.         # Defaults falls was nicht Ok ist:
  74.         text = ''
  75.         val = ''
  76.  
  77.         # Wenn Wert gegeben wurde versuchen die Daten zu holen
  78.         if value != None:
  79.             try:                
  80.                 text = self.model.objects.get(pk=value)
  81.                 val = value
  82.             except Exception:
  83.                 pass
  84.            
  85.            
  86.         html_id = attrs.get('id', name)
  87.         url = self.url() if callable(self.url) else self.url
  88.         callback = u"%s(ui.item.id);" % self.callback if self.callback else ""
  89.        
  90.         return mark_safe(CLIENT_CODE % dict(name=name, html_id=html_id, url=url, value=val, text=text, callback=callback))
  91.        
  92.  
  93.     def value_from_datadict(self, data, files, name):
  94.         """
  95.        Given a dictionary of data and this widget's name, returns the value
  96.        of this widget. Returns None if it's not provided.
  97.        """
  98.  
  99.         return data.get(name, None)
  100.  
  101.  
  102.  
  103.        
  104. class ModelAutoCompleteField(forms.fields.CharField):
  105.     """
  106.    Autocomplete-Feld das die gelesenen Werte direkt zurueck in Django-Model-Objekte
  107.    konvertiert. Als Widget wird das AutoCOmpleteWidget von oben benutzt, was die
  108.    JavaScript-Logik und Felder korrekt fuellt.
  109.    Momentan muss ein gueltiger WErt selektiert werden.
  110.    """
  111.    
  112.     default_error_messages = {
  113.         'invalid_choice': mark_safe(u'Keine g&uuml;ltige Auswahl. Bitte eine g&uuml;ltige Option w&auml;hlen.'),
  114.         'no_choice' : mark_safe(u'Kein Eintrag ausgew&auml;hlt. Bitte w&auml;hlen sie einen Eintrag.'),
  115.     }
  116.  
  117.  
  118.     def __init__(self, model, url, callback=None,size=None, *args, **kwargs):
  119.         """
  120.        Neues AutoCOmpleteField anlegen
  121.        `model`
  122.            Das Model auf dem die Vervollstaendigung beruht.
  123.        `url`
  124.            Die URL aus der die Callbackdatan angefragt werden
  125.        """
  126.         self.model = model
  127.        
  128.         # build attrs for widget
  129.        
  130.         attrs = {'size': size} if size else {}
  131.        
  132.         super(ModelAutoCompleteField, self).__init__(
  133.             widget = ModelAutoCompleteWidget(url=url, model=model, callback=callback, attrs=attrs),            
  134.             *args,
  135.             **kwargs)
  136.            
  137.     def update_url(self, url):
  138.         self.widget.url = url
  139.  
  140.     def clean(self, value):
  141.         """
  142.        Die Methode konvertiert die ID des HiddenFields zurueck in ein Django-MOdel
  143.        """
  144.        
  145.         # Kein WErt gegeben, es wird aber auch keiner gebraucht
  146.         if value=='' and not self.required:
  147.             return None
  148.        
  149.         # Wenn kein Wert gegeben ist kann auch kein Model gelesen werden
  150.         if value=='':
  151.             raise ValidationError(self.error_messages['no_choice'])
  152.  
  153.         # Versuchen das Objekt zu lesen
  154.         try:
  155.             obj = self.model.objects.get(pk=value)
  156.         except self.model.DoesNotExist:
  157.             raise ValidationError(self.error_messages['invalid_choice'])
  158.        
  159.         return obj
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement