matata
matata

Reputation: 15

Django templates using buttons for Boolean fields

I have a preferences page that has many Boolean fields. I created an UpdateView and when I use {{ form.as_p }} in my template it works, but I am trying to create individual buttons for each option instead of checkboxes. I couldn't find a way to make it work in my template.

models.py:

class Preference(models.Model):
    user = models.OneToOneField("User", on_delete=models.SET_NULL, null=True)
    option1= models.BooleanField(default=False)
    option2= models.BooleanField(default=False)
    option3= models.BooleanField(default=False)
    option4= models.BooleanField(default=False)

views.py:

class preferencesview(UpdateView):
    model = Preference
    form_class = PreferenceForm
    success_url = reverse_lazy("profiles:preferences")

forms.py:

class PreferenceForm (forms.ModelForm):
    class Meta:
        model = Preference
        exclude = ['user']

I want to have individual buttons for each option and a submit button to save the changes. Please let me know if you have any documentation or tutorials.

Upvotes: 0

Views: 247

Answers (1)

Waldemar Podsiadło
Waldemar Podsiadło

Reputation: 1412

There is so many ways you can do it. But there is no out of the box solution. My example is with bootstrap css and a little bit of jquery/js:

In form class definition change fields widgets to HiddenInput like:

class PreferenceForm (forms.ModelForm):
class Meta:
    model = Preference
    exclude = ['user']
    widgets = {'option1': forms.HiddenInput,
               'option2': forms.HiddenInput,
               }

end so on

then in your template loop over fields of form and based on value render the class of button (btn-success/btn-danger):

 <form id="myform">
            {% for field in form %}
                <button type="button" class="btn {% if field.value %} btn-success{% else %}btn-danger{% endif %}"
                name="{{ field.name }}">
                    {{ field.name }}</button>
                {{ field }}
            {% endfor %}
        </form>

don't forget to add {{ field }} itself,

And now with js watch for click on buttons inside #myform and based on hasClass change class of button and value of input:

<script>
        $('#myform button').on('click', function () {
            let nameof = $(this).attr('name');
            
           if ($(this).hasClass('btn-success')){
               $(this).removeClass('btn-success');
               $(this).addClass('btn-danger');
               $('#myform input[name='+nameof+']').val('False');
           } else {
               $(this).removeClass('btn-danger');
               $(this).addClass('btn-success');
               $('#myform input[name='+nameof+']').val('True');
           }
        });
    </script>

That's all. Don't forget to add save button to form. Its just one of many examples how can you do it.

Upvotes: 1

Related Questions