views:

365

answers:

1

Hi,

In my model I have a manytomany field

mentors = models.ManyToManyField(MentorArea, verbose_name='Areas', blank=True)

In my form I want to render this as:

  1. drop down box with list of all MentorArea objects which has not been associated with the object.

  2. Next to that an add button which will call a javascript function which will add it to the object.

  3. Then under that a ul list which has each selected MentorArea object with a x next to it which again calls a javascript function which will remove the MentorArea from the object.

I know that to change how an field element is rendered you create a custom widget and override the render function and I have done that to create the add button.

class AreaWidget(widgets.Select):

    def render(self, name, value, attrs=None, choices=()):
        jquery = u'''
        <input class="button def" type="button" value="Add" id="Add Area" />'''

        output = super(AreaWidget, self).render(name, value, attrs, choices)

        return output + mark_safe(jquery) 

However I don't know how to list the currently selected ones underneath as a list. Can anyone help me? Also what is the best way to filter down the list so that it only shows MentorArea objects which have not been added? I currently have the field as

mentors = forms.ModelMultipleChoiceField(queryset=MentorArea.objects.all(), widget = AreaWidget, required=False)

but this shows all mentors no matter if they have been added or not.

Thanks

A: 

For me the functionality you described sounds a lot like what you can achieve with using the ModelAdmin' filter_horizontal and filter_vertical settings. The widget they render lives in django.contrib.admin.widgets.FilteredSelectMultiple. You should have a look at its code!

lazerscience