André
André

Reputation: 25554

Django - How to customize a checkbox in a form?

I'm out of clues on how to customize a form with checkboxes. Basically I need to choose in the queryset only two choices of a list, I've tried to use "filter(pk=2, pk=3)" but it is not working. I've also to make the "pk=2" choice checked and not editable and the "pk=3" editable and not checked by default.

My form(does not work, filter(pk=2, pk=3) is not valid):

class PrimaryCategoryForm(forms.ModelForm):
    primarycategorytype = forms.ModelMultipleChoiceField(queryset=PrimaryAdCategoryType.objects.filter(pk=2, pk=3), required=True, widget=forms.CheckboxSelectMultiple)

Any clues on how to achieve this?

Best Regards,

Upvotes: 2

Views: 1911

Answers (2)

Aidan Ewen
Aidan Ewen

Reputation: 13308

Trying building your queryset using the pythons union operator -

class PrimaryCategoryForm(forms.ModelForm):
    set_1 = PrimaryAdCategoryType.objects.filter(pk=2)
    set_2 = PrimaryAdCategoryType.objects.filter(pk=3)
    qs = set_1 | set_2
    primarycategorytype = forms.ModelMultipleChoiceField(queryset=qs, 
                                                        required=True,
                                                        widget=forms.CheckboxSelectMultiple)

The | operator is creating a new set with all items from set_1 and all items from set_2.

UPDATE

Whilst the method above will support creating complicated sets. Martin's suggestion in the comments is probably sufficient if you simply want to pick a few pk's -

class PrimaryCategoryForm(forms.ModelForm):
    qs=PrimaryAdCategoryType.objects.filter(pk__in=[2,3])
    primarycategorytype = forms.ModelMultipleChoiceField(queryset=qs, 
                                                        required=True,
                                                        widget=forms.CheckboxSelectMultiple)

EDITABLE CHECKBOXES

I think when it comes to making the checkboxes editable and preselected you may need to resort to javascript. Perhaps add data-attributes to the widget, then create a jquery function that manipulates the checkboxes on the basis of the data-attributes. Something like -

attrs = {'data-selected-value': 2, 'data-readonly-value': 2}
primarycateogrytype = forms.ModelMultipleChoiceField(attrs=attrs)

Then in the javascript -

var readonlyCheckboxValue = $('#your_mulliplecheckboxselect).data('selected-value');
var $readonlyCheckbox = $('#your_multiplecheckboxselect .input[value=readonlyCheckboxValue]');
$readonlyCheckbox.attr('readonly', true);

I haven't tested this code, but it should give you an idea of what I'm suggesting. Do check out the data-attribute if you haven't come across it already - it's pretty awesome.

Upvotes: 2

redDragonzz
redDragonzz

Reputation: 1571

Its possible that you would need the form to be dynamic in nature. You would need to override the __init__ method for the class.

Something like this here: How to Modify Choices of ModelMultipleChoiceField

An example:

class ServiceStartForm(forms.Form):
    serviceList = service.models.Service.objects.all()
    print serviceList.count()
    b = {}
    for aService in serviceList:
        b[aService.id] = aService.name
    c = b.items()
    print "Within the form, ", serviceList.count()
    serviceChoice = forms.ChoiceField(choices=c, widget=forms.Select())
    input_directory = forms.CharField(max_length=200)
    output_directory = forms.CharField(max_length=200)

    def __init__(self, *args, **kwargs):
        super(ServiceStartForm, self).__init__(*args, **kwargs)
        serviceList = service.models.Service.objects.all()
        b = {}
        for aService in serviceList:
            b[aService.id] = aService.name
        c = b.items()
        self.fields["serviceChoice"].choices = c

Upvotes: 1

Related Questions