Having an issue while styling django-selectable.

46 views
Skip to first unread message

Guanting Liu

unread,
Jul 4, 2015, 1:41:02 AM7/4/15
to django-s...@googlegroups.com
Hi all,

I have troubles styling django-selectable.

Currently, without any styling work, the search result dropdown list would appear on a transparent background. And I noticed that I when specifying the get_item_label method, I can include HTML there. So I have been experimenting adding HTML tags to style the dropdown list. And here is my main part of code.

# models.py

from django.db import models


class Topic(models.Model):

    name
= models.CharField(max_length=20)

   
def __str__(self):
       
return self.name


class LessonsLearned(models.Model):
    topic
= models.ForeignKey(Topic)
    text
= models.TextField(max_length=3000)


# lookups.py


from selectable.base import ModelLookup
from selectable.registry import registry
from .models import Topic




class TopicLookup(ModelLookup):
    model
= Topic
    search_fields
= ('name__icontains', )


   
def get_item_label(self, item):
       
"""The label is shown in the drop down menu of search results."""
       
return '<strong>%s</strong>' % item.name


   
def get_item_value(self, item):
       
"""The id is the value that will eventually be returned by the field/widget."""
       
return item.name


   
def get_item_value(self, item):
       
"""The value is shown in the input once the item has been selected."""
       
return item.name


registry
.register(TopicLookup)

# forms.py

from django.forms import ModelForm
from charsleft_widget.widgets import CharsLeftArea
from .models import Topic, LessonsLearned
from .lookups import TopicLookup


class LessonsLearnedForm(ModelForm):
    topic
= AutoCompleteSelectField(lookup_class=TopicLookup, allow_new=True)

   
class Meta:
        model
= LessonsLearned
        exclude
= ['creator', 'topic']
        labels
= {
           
'text': "Lessons learned",
       
}
        widgets
= {
           
'text': CharsLeftArea(
                attrs
={'placeholder': '%d characters max...' % model._meta.get_field('text').max_length}
           
),
       
}

   
def __init__(self, *args, **kwargs):
       
super(LessonsLearnedForm, self).__init__(*args, **kwargs)
       
if self.instance and self.instance.pk and self.instance.topic:
           
self.initial['topic'] = self.instance.topic

   
def save(self, *args, **kwargs):
        topic
= self.cleaned_data['topic']
       
if topic and not topic.pk:
            topic
= Topic.objects.create(name=topic.name)
       
self.instance.topic = topic
       
return super(LessonsLearnedForm, self).save(*args, **kwargs)

But the result is not as expected, the <strong>...</strong> tags were not parsed as HTML tags, as shown in the following screenshot.


My questions are:
Am I doing something wrong?
Is the get_item_label method designed to be a handy way to style the item labels in the dropdown list without touching any Javascript?
And is it possible to style them without touching any Javascript?

Hopefully I am describing my issue in enough detail. Please help me.

Mark Lavin

unread,
Jul 4, 2015, 6:22:41 AM7/4/15
to django-s...@googlegroups.com
If there is no style applied to the list items then you are most likely missing the jQuery UI CSS http://django-selectable.readthedocs.org/en/v0.9.X/quick-start.html#including-jquery-jquery-ui

get_item_label can be used to add additional HTML to the label; however, it needs to be marked as safe for it to not end up escaped as it is in your example. If the content of the label contains any user input (not created by a trusted site admin) I would not recommend doing that since it can open your site up to an XSS attack.

You do not need JS to style HTML. That is the role of CSS.

--
You received this message because you are subscribed to the Google Groups "django-selectable" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-selecta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Guanting Liu

unread,
Jul 4, 2015, 6:28:02 AM7/4/15
to django-s...@googlegroups.com
@Mark Lavin

Thanks Mark, I will try it out. Another question I want to ask is that while using AutoCompleteSelectField/AutoCompleteSelectWidget, it seems that the max_length=20 validation check is lost. How should I make it work again?

Mark Lavin

unread,
Jul 4, 2015, 10:35:35 AM7/4/15
to django-s...@googlegroups.com
Not sure what you mean by that. If you are only changing the widget does it not change the field level validation. The AutoCompleteSelectField is meant mostly as a replacement for selecting another related object like a FK. In which case I'm not sure how the max_length makes sense.

In either case, you can always add more form validation using the field or form level clean methods described here https://docs.djangoproject.com/en/1.8/ref/forms/validation/#cleaning-a-specific-field-attribute

On Sat, Jul 4, 2015 at 6:28 AM, Guanting Liu <guanti...@west.cmu.edu> wrote:
@Mark Lavin

Thanks Mark, I will try it out. Another question I want to ask is that while using AutoCompleteSelectField/AutoCompleteSelectWidget, it seems that the max_length=20 validation check is lost. How should I make it work again?

--

Guanting Liu

unread,
Jul 4, 2015, 7:31:14 PM7/4/15
to django-s...@googlegroups.com
Nevermind, it is my own conceptial error. Thanks Mark!
Reply all
Reply to author
Forward
0 new messages