def render(self, name, value=None, attrs=None): """ The widget consists of two text fields: 1. Field with id = "id_<field_name>_text", which holds the text values 2. Field with id = "id_<field_name>", which is hidden and holds the pk of a selected item. """ text_field_attrs = self.build_attrs(attrs, name=name + "_text") # if there is any initial value available, fill the text field from the queryset text_field_value = "" if value: func = get_installed("%(app)s.ajax.%(func)s" % { 'app': self.app, 'func': self.qs_function, }) queryset = func("all") try: obj = queryset.get(pk=value) text_field_value = getattr(obj, self.display_attr) if callable(text_field_value) and not getattr(text_field_value, "alters_data", False): text_field_value = text_field_value() except: pass text_field_attrs['value'] = text_field_value text_field_attrs['class'] = "autocomplete textinput textInput form-control" if not self.attrs.has_key('id'): text_field_attrs['id'] = 'id_%s_text' % name # hidden field for key value hidden_field_attrs = { 'id' : 'id_%s' % name, 'name' : '%s' % name, 'value' : value or "", 'class' : "form_hidden", } return mark_safe( u""" <input type="text" %(text_field_attrs)s/> <input type="hidden" %(hidden_field_attrs)s /> <script type="text/javascript"> /* <![CDATA[ */ %(js)s /* ]]> */ </script>""" % { 'text_field_attrs' : flatatt(text_field_attrs), 'js' : self.render_js( hidden_field_attrs['id'], text_field_attrs['id'], text_field_value, ), 'hidden_field_attrs' : flatatt(hidden_field_attrs), } )
def to_python(self, value): func = get_installed("%(app)s.ajax.%(func)s" % { 'app': self.app, 'func': self.qs_function, }) if value: try: value = func("all").filter(pk__in=value.split(",")) except: raise forms.ValidationError(self.error_messages['invalid']) else: value = func("all").none() return value
def __init__(self, app, qs_function, display_attr, add_display_attr=None, options=None, attrs=None, *args, **kwargs): if not attrs: attrs = {} if not options: options = {} self.app = app self.qs_function = qs_function self.func = get_installed("%(app)s.ajax.%(func)s" % { 'app': self.app, 'func': self.qs_function, }) self.queryset = self.func("all") self.widget = SelectToAutocompleteWidget( app, qs_function, display_attr, add_display_attr, options, attrs) forms.CharField.__init__(self, *args, **kwargs)
def ajax_autocomplete(request, app, qs_function, display_attr, add_display_attr=None, limit=1000): """ Method to lookup a model field and return an array. Intended for use in AJAX widgets. """ obj_list = [] t = Template("") if "q" in request.GET: search = request.GET["q"] func = get_installed("%(app)s.ajax.%(func)s" % {"app": app, "func": qs_function}) queryset = func(search) if add_display_attr == u"None": add_display_attr = None for obj in queryset[:limit]: display = getattr(obj, display_attr) if callable(display) and not getattr(display, "alters_data", False): display = display() if add_display_attr: add_display = getattr(obj, add_display_attr) if callable(add_display) and not getattr(add_display, "alters_data", False): add_display = add_display() obj_list.append([display, obj.pk, add_display]) else: obj_list.append([display, obj.pk]) if add_display_attr: t = Template( "{% autoescape off %}{% for el in obj_list %}{{ el.0 }}|{{ el.1 }}|{{ el.2 }}\n{% endfor %}{% endautoescape %}" ) else: t = Template( "{% autoescape off %}{% for el in obj_list %}{{ el.0 }}|{{ el.1 }}\n{% endfor %}{% endautoescape %}" ) c = Context({"obj_list": obj_list}) r = HttpResponse(t.render(c)) r["Content-Type"] = "text/plain; charset=UTF-8" return r
def __init__(self, app, qs_function, display_attr, add_display_attr=None, options=None, attrs=None): super(SelectToAutocompleteWidget, self).__init__(app, qs_function, display_attr) if not attrs: attrs = {} if not options: options = {} self.app = app self.qs_function = qs_function self.display_attr = display_attr self.add_display_attr = add_display_attr self.options = options self.attrs = attrs self.func = get_installed("%(app)s.ajax.%(func)s" % { 'app': self.app, 'func': self.qs_function, }) self.queryset = self.func("all") #self.choices = list(XChoiceList(self.queryset)) self.choices = XChoiceList(self.queryset)
def render(self, name, value=None, attrs=None): """ The widget consists of two text fields: 1. Field with id = "id_<field_name>_text", which is used for entering text values 2. Field with id = "id_<field_name>", which is hidden and holds comma-separated pks of selected items 3. List of selected text values with id = "id_<field_name>_value_pk-<pk>" """ text_field_attrs = self.build_attrs(attrs, name=name + "_text") value = value or [] # if there is any initial value available, fill the text field from the queryset value_list = [] if value: func = get_installed("%(app)s.ajax.%(func)s" % { 'app': self.app, 'func': self.qs_function, }) queryset = func("all") for obj in queryset.filter(pk__in=value): text_value = getattr(obj, self.display_attr) if callable(text_value) and not getattr(text_value, "alters_data", False): text_value = text_value() value_list.append( """<li id="id_%(name)s_value_pk-%(pk)s"> <span>%(text_value)s</span> </li>""" % { 'name': name, 'pk': obj.pk, 'text_value': force_unicode(text_value), }) html_value_list = "" if value_list: html_value_list = """<ul id="id_%(name)s_value_list" class="ac_value_list"> %(value_list)s </ul>""" % { 'name': name, 'value_list': "".join(value_list), } text_field_attrs['value'] = "" text_field_attrs['class'] = "autocomplete textinput textInput" if not self.attrs.has_key('id'): text_field_attrs['id'] = 'id_%s_text' % name # hidden field for key value hidden_field_attrs = { 'id' : 'id_%s' % name, 'name' : '%s' % name, 'value' : ",".join([force_unicode(pk) for pk in value]), 'class' : "form_hidden", } return mark_safe( u""" <input type="hidden" %(hidden_field_attrs)s /> %(html_value_list)s <input type="text" %(text_field_attrs)s/> <script type="text/javascript"> /* <![CDATA[ */ %(js)s /* ]]> */ </script>""" % { 'text_field_attrs' : flatatt(text_field_attrs), 'js' : self.render_js( hidden_field_attrs['id'], text_field_attrs['id'], "", ), 'hidden_field_attrs': flatatt(hidden_field_attrs), 'html_value_list': html_value_list } )