Opened 2 months ago

Closed 2 months ago

#29488 closed Bug (wontfix)

FilteredSelectMultiple Controls Don't Work if The Name of the Widget Has a Space

Reported by: Mark Phillips Owned by: nobody
Component: contrib.admin Version: 2.0
Severity: Normal Keywords: FilteredSelectMultiple widget
Cc: Carlton Gibson Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mark Phillips)

If the label for the FilteredSelectMultiple has a space in it, the controls for moving data between the boxes are not activated. The widget still works if one double clicks on the elements in the left box, they move to the right box. But the arrows don't work. Tested on Chrome 67.0.3396.62 (Official Build) (64-bit) and Firefox 60.0.1 (64-bit) using runserver to run my django code.

Take a look at the attached image first.png. There are two FilteredSelectMultiple widgets, one called Pets and one called Pet Names. Note that in the widget Pet Names, the controls are not highlighted, but the controls in the Pets widget are highlighted.

Take a look at the attached image second.png. The only change to the code was to change the Pet Names label to Pet_Names (ie replaced the space between Pet and Names with an underscore Pet Names -> Pet_Names). Now the controls are working.

Mark

Attachments (6)

first.png (36.2 KB) - added by Mark Phillips 2 months ago.
Screen shot showing a FilteredSelectMultiple widget with a space in the label and the controls not working.
second.png (36.9 KB) - added by Mark Phillips 2 months ago.
Screen shot showing a FilteredSelectMultiple widget without a space in the label and the controls are working.
Javascrpt debugging A.png (132.8 KB) - added by Mark Phillips 2 months ago.
Javascript debugging A
Javascript debugging B.png (200.0 KB) - added by Mark Phillips 2 months ago.
Javascript debugging B
Javascript debugging C.png (166.5 KB) - added by Mark Phillips 2 months ago.
Javascript debugging C
testFSM.zip (24.5 KB) - added by Mark Phillips 2 months ago.
Django project that illustrates the bug in a FilteredSelectMultiple widget with a space in the field name

Download all attachments as: .zip

Change History (20)

Changed 2 months ago by Mark Phillips

Attachment: first.png added

Screen shot showing a FilteredSelectMultiple widget with a space in the label and the controls not working.

Changed 2 months ago by Mark Phillips

Attachment: second.png added

Screen shot showing a FilteredSelectMultiple widget without a space in the label and the controls are working.

comment:1 Changed 2 months ago by Mark Phillips

Description: modified (diff)

comment:2 Changed 2 months ago by Tim Graham

Component: Uncategorizedcontrib.admin

I'm not sure that a space in the label is the issue. For example, I couldn't reproduce the problem with "Available user permissions" on the change user page. Could you debug a bit further and confirm the source of the problem?

comment:3 in reply to:  2 Changed 2 months ago by Mark Phillips

I am happy to help debug this issue. I am not sure where to start or how to proceed. Any suggestions as to a plan of attack would be very helpful!

Replying to Tim Graham:

I'm not sure that a space in the label is the issue. For example, I couldn't reproduce the problem with "Available user permissions" on the change user page. Could you debug a bit further and confirm the source of the problem?

comment:4 Changed 2 months ago by Tim Graham

I would try some JavaScript debugging in django/contrib/admin/static/admin/js/SelectFilter2.js.

comment:5 Changed 2 months ago by Carlton Gibson

Cc: Carlton Gibson added

comment:6 Changed 2 months ago by Mark Phillips

Tim,

I am not a Javascript guy, but I did manage to get this far - perhaps it will help.

In SelectFilter2.js, I tracked what was going on to the line where it is going to toggle the add link on (see picture A). When I step through the code using the widget named Pets and selecting an element, I get to picture B in the bowels of the jQuery code. You will note that "match = 3" for this control. When I step through the same code, but select an element in Pet Names, I get to the same place, but now match = null (picture C). From here, the program goes in different directions, and not being a js guy, I am a little lost.

I hope this helps!

Mark

comment:7 Changed 2 months ago by Mark Phillips

Tim,

I can't upload the three images because the tracker thinks they are spam.

Mark

Changed 2 months ago by Mark Phillips

Attachment: Javascrpt debugging A.png added

Javascript debugging A

Changed 2 months ago by Mark Phillips

Attachment: Javascript debugging B.png added

Javascript debugging B

Changed 2 months ago by Mark Phillips

Attachment: Javascript debugging C.png added

Javascript debugging C

comment:8 Changed 2 months ago by Mark Phillips

Finally found a file name that was not considered spam.....

Mark

comment:9 Changed 2 months ago by Tim Graham

Can you provide a sample project with the minimal code needed to reproduce the issue?

comment:10 Changed 2 months ago by Mark Phillips

Tim,

The project is rather large. I can try to trim it down, but I am in the middle of fixing other bugs right now. In what form and how should I send you the trimmed down project?

Mark

PS Sorry for my newbieness...;)

comment:11 Changed 2 months ago by Tim Graham

Resolution: worksforme
Status: newclosed

You can attach a file on the ticket or put the minimal project on GitHub. I tried this but could not reproduce the problem:

from django.db import models


class Pet(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class PetName(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class Whatever(models.Model):
    pets = models.ManyToManyField(Pet)
    pet_names = models.ManyToManyField(PetName)
from django.contrib import admin

from .models import Pet, PetName, Whatever

admin.site.register((Pet, PetName))
admin.site.register(Whatever, filter_horizontal=['pets', 'pet_names'])

The widget says, "Available pet names".

comment:12 Changed 2 months ago by Mark Phillips

Tim,

After looking at your example, I see I did a bad job of explaining the bug. In my program, I create the fields for the adminForm on the fly because the fields are not defined until run time. I have these lines of code:

class MetaDataNames(models.Model): 
    meta_name_id = models.AutoField(primary_key = True)
    name = models.CharField(max_length=200, unique=True)

class MetaDataValues(models.Model): 
    meta_value_id = models.AutoField(primary_key = True)
    meta_name_id = models.ForeignKey(MetaDataNames, on_delete=models.CASCADE,)
    value = models.CharField(max_length=200, unique=True)
    
class Document(models.Model):
    test_id = models.AutoField(primary_key = True)
    doc_name = models.CharField(max_length=200, unique=True)
    metadata = jsonfield.JSONField(blank=True)

This lines of code in the DocumentAdminForm(forms.ModelForm) contains :

        def __init__(self, *args, **kwargs):
            metadata_names = MetaDataNames.objects.all() 
            # create the fields
            for metadata in metadata_names:
                self.fields[metadata.name] = forms.ModelMultipleChoiceField(widget=FilteredSelectMultiple(metadata.name, is_stacked=False), required=False, queryset=MetaDataValues.objects.filter(meta_name_id=metadata.meta_name_id).order_by('value'),)
         .....

The issue with the FilteredSelectMultiple widget is that when the field name has a space, the controls don't work. In the code above, where it says self.fields[metadata.name], the metadata.name part is the string 'Pet Names', with a space. If I use 'Pet_Names', then the controls in the widget work.

I may be offending the Django Gods by having a field name with a space in it. One cannot do that in a model, as far as I can figure out. However, it is an interesting edge case for the widget, since it is perfectly reasonable for one to create fields as I am doing.

I can continue to create the test case based on the above code if you want. However, if the answer is that I cannot have a field name with a space, then I won't bother.

Please let me know if I should continue with a full test case, or that nothing will be done because I have a field name with a space in it.

Thanks,

Mark

comment:13 Changed 2 months ago by Mark Phillips

Resolution: worksforme
Status: closednew

I have attached a test django application (testFSM) that shows the behavior I am seeing. It was tested using Django 2.0.5 and Python 3.4.3 in a virtualenv on Ubuntu 14.04.

To recap:

If a field has a space in the field name for a ModelMultipleChoiceField (ie fields are generated in the init function of a ModelForm), then the controls for the associated FilteredSelectMultiple widget are not enabled. One can still double click on an element in the widget, but the controls don't work. Also, one cannot clear the selected items or deselect the items in the list.

Please see the README in the attached django project.

Mark

Changed 2 months ago by Mark Phillips

Attachment: testFSM.zip added

Django project that illustrates the bug in a FilteredSelectMultiple widget with a space in the field name

comment:14 Changed 2 months ago by Tim Graham

Resolution: wontfix
Status: newclosed

Thanks for the clarification. #29011 also raised an issue with spaces in field names. I'll reiterate my position there and say that I don't see much value in trying to fix issues such as spaces in field names that can't occur with normal declarative forms.

Note: See TracTickets for help on using tickets.
Back to Top