0

I have that HTML:

<span class="label-text"></span><ul id="id_stars">
<li><label for="id_stars_0"><input class="star-field" id="id_stars_0" name="stars" type="radio" value="1" /> 1</label></li>
<li><label for="id_stars_1"><input class="star-field" id="id_stars_1" name="stars" type="radio" value="2" /> 2</label></li>
<li><label for="id_stars_2"><input class="star-field" id="id_stars_2" name="stars" type="radio" value="3" /> 3</label></li>
<li><label for="id_stars_3"><input class="star-field" id="id_stars_3" name="stars" type="radio" value="4" /> 4</label></li>
<li><label for="id_stars_4"><input class="star-field" id="id_stars_4" name="stars" type="radio" value="5" /> 5</label></li>
</ul>

And I have that CSS:

#id_stars{
  list-style: none;
}

#id_stars label{
  font-weight: normal;
}

#id_stars input[type=radio]{
  display: none;
}

#id_stars label{
  width: 15px;
  height: 15px;
  margin: 0 0 0 5px;
  cursor: pointer;
  border: 0px;
  border-radius: 2px;
  background-color: #C1C1C1;
}

input[type=radio]:checked + label{
  background: #F79414;
}

When the radio field is cheked, the color of the label is not changing.

Any idea?

Bonus question: How could I do custom a custom radio button near the label without touching the HTML code (generated by Django forms), instead of modifying the label like now?

4
  • It's not changing the label color because the radio buttons are inside the labels. The css you are targeting is for a sibling. It will work well if you can change the HTML. I'm not sure how to help you without doing that. Commented Oct 1, 2015 at 21:07
  • Thnaks for your answer cocoa. Not even changing taking the radio buttons out of the label is working. Commented Oct 1, 2015 at 23:41
  • you also need to target #id_stars input[type=radio]:checked + label Commented Oct 2, 2015 at 15:15
  • Solved! Thanks cocoa =) Commented Oct 3, 2015 at 12:39

2 Answers 2

2

As cocoa told, the main problem was that the radio buttons are inside the labels. That is because Django is rendering the default RadioSelect widget in that way.

The solution I found that works is to create a custom render for the radio select in orther to take out the radio input from the label.

That's the way:

class CustomRadioInputStar(RadioInput):
    def __unicode__(self):
        if 'id' in self.attrs:          
            label_for = ' for="%s"' % (self.attrs['id'])
        return mark_safe(u'%s<label%s class="rating-star"></label>' % (self.tag(), label_for))

class RadioStarCustomRenderer(forms.RadioSelect.renderer):
    def __iter__(self):
        for i, choice in enumerate(self.choices):
            yield CustomRadioInputStar(self.name, self.value, self.attrs.copy(), choice, i)

    def __getitem__(self, idx):
        choice = self.choices[idx]
        return CustomRadioInputStar(self.name, self.value, self.attrs.copy(), choice, idx)

    def render(self):
        return mark_safe(u'%s' % u'\n'.join([u'%s' % force_unicode(w) for w in self]))

Then, you just need to add the custom render to the RadioSelect widget:

stars = forms.ChoiceField(choices=CHOICES_STARS, widget=forms.RadioSelect(renderer=RadioStarCustomRenderer))

Of course, dont forget to import the respective libraries:

from django.utils.safestring import mark_safe
from django.forms.widgets import RadioInput
from django.utils.encoding import force_unicode
from django.utils.html import conditional_escape
Sign up to request clarification or add additional context in comments.

Comments

1

It's not changing the label color because the radio buttons are inside the labels. The css you are targeting is for a sibling. So change your html like this:

<li>
  <input class="star-field" id="id_stars_0" name="stars" type="radio" value="1" />
  <label for="id_stars_0">1</label>
</li> 

also add #id_stars to

input[type=radio]:checked + label{
  background: #F79414;
}

#id_stars {
  list-style: none;
}
#id_stars label {
  font-weight: normal;
}
#id_stars input[type=radio] {
  display: none;
}
#id_stars label {
  width: 15px;
  height: 15px;
  margin: 0 0 0 5px;
  cursor: pointer;
  border: 0px;
  border-radius: 2px;
  background-color: #C1C1C1;
}
#id_stars input[type=radio]:checked + label {
  background: #F79414;
}
<span class="label-text"></span>

<ul id="id_stars">
  <li>
    <input class="star-field" id="id_stars_0" name="stars" type="radio" value="1" />
    <label for="id_stars_0">1</label>
  </li>
  <li>
    <input class="star-field" id="id_stars_1" name="stars" type="radio" value="2" />
    <label for="id_stars_1">2</label>
  </li>
  <li>
    <input class="star-field" id="id_stars_2" name="stars" type="radio" value="3" />
    <label for="id_stars_2">3</label>
  </li>
  <li>
    <input class="star-field" id="id_stars_3" name="stars" type="radio" value="4" />
    <label for="id_stars_3">4</label>
  </li>
  <li>
    <input class="star-field" id="id_stars_4" name="stars" type="radio" value="5" />
    <label for="id_stars_4">5</label>
  </li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.