Repository: py-pdf/pypdf
Pull request: BUG: Make reader.get_fields also return dropdowns with options
Adding `/Opt` to the attributes list get_fields() will now add /Opt if it has it. For Combo Box /Ch it will list all of the available options in the drop down menu.  

Closes #391

Problem statement:
PdfReader.get_form_text_fields() not returning dropdown fields
I have a pdf form with multiple Form-Fields in it. The function "getFormTextFields()" is only returning a dictionary without the dropdown-fields. The dictionary contains the information of all other fields, but the dropdown-fields are simply missing.

## Minimal Example

```python
from PyPDF2 import PdfReader

reader = PdfReader("sample-files/012-libreoffice-form/libreoffice-form.pdf")
reader.get_form_text_fields()
```

gives

```json
{"First Name": "Alice", "Last Name": "", "Birthday": "", "First Name_2": "Bob"}
```

The "Nationality" part is missing.

On the other hand:

```pycon
>>> reader.get_fields()
{'First Name': {'/FT': '/Tx', '/T': 'First Name', '/V': 'Alice', '/DV': 'Alice'},
 'Last Name': {'/FT': '/Tx', '/T': 'Last Name', '/V': '', '/DV': ''}, 
'female': {'/FT': '/Btn', '/Kids': [IndirectObject(7, 0), IndirectObject(9, 0)], '/T': 'female', '/Ff': 49152, '/V': '/Off', '/DV': '/Off'},
 'Birthday': {'/FT': '/Tx', '/T': 'Birthday', '/V': '', '/DV': ''}, 
'gdpr': {'/FT': '/Btn', '/T': 'gdpr', '/V': '/Off', '/DV': '/Off'}, 
'other': {'/FT': '/Btn', '/T': 'other', '/V': '/Off', '/DV': '/Off'}, 
'First Name_2': {'/FT': '/Tx', '/T': 'First Name_2', '/Ff': 4096, '/V': 'Bob', '/DV': 'Bob'}, 
'Nationality': {'/FT': '/Ch', '/T': 'Nationality', '/Ff': 131072, '/V': '', '/DV': ''}}
```

Hints from issue discussion:
if you want to get all the values, instead of _.getFormTextFields()_ you can use the following method after opening the pdf file with _PyPDF2.PdfFileReader()_ :

**.getFields()** 

- getFormTextFields() works as pdf form reader but doesn't read the drop down menus or tick boxes    
- whereas getFields() gets all the data but needs cleaning up
According to the official documentation, `getFormTextFields()` can indeed be used to extract the contents of a drop down.

![github_issue_pypdf2](https://user-images.githubusercontent.com/69465171/124714541-2e9e7f80-df02-11eb-9a4d-52f1c447a8fb.png)

So I guess the documentation is just wrong on this.


_Sorry for being the issue-necromancer here._
I've just added https://github.com/py-pdf/sample-files/tree/main/012-libreoffice-form to confirm the issue
@akallai I've added a minimal example to your question. Thank you for raising the issue!

Commit message: removed garbage

Patch to review:
diff --git a/PyPDF2/constants.py b/PyPDF2/constants.py
index a195c22fe..0e0eddf1c 100644
--- a/PyPDF2/constants.py
+++ b/PyPDF2/constants.py
@@ -302,6 +302,7 @@ class FieldDictionaryAttributes:
     V = "/V"  # text string, optional
     DV = "/DV"  # text string, optional
     AA = "/AA"  # dictionary, optional
+    Opt = "/Opt" # Options, Optional
 
     @classmethod
     def attributes(cls) -> Tuple[str, ...]:
@@ -316,6 +317,7 @@ def attributes(cls) -> Tuple[str, ...]:
             cls.DV,
             cls.Kids,
             cls.AA,
+            cls.Opt,
         )
 
     @classmethod
@@ -329,6 +331,7 @@ def attributes_dict(cls) -> Dict[str, str]:
             cls.Ff: "Field Flags",
             cls.V: "Value",
             cls.DV: "Default Value",
+            cls.Opt: "Options"
         }
 
 
diff --git a/resources/libreoffice-form.pdf b/resources/libreoffice-form.pdf
new file mode 100644
index 000000000..7641b4d54
Binary files /dev/null and b/resources/libreoffice-form.pdf differ
diff --git a/tests/test_workflows.py b/tests/test_workflows.py
index aaf99ac65..4f6e60aa3 100644
--- a/tests/test_workflows.py
+++ b/tests/test_workflows.py
@@ -22,6 +22,14 @@
 sys.path.append(PROJECT_ROOT)
 
 
+def test_dropdown_items():
+    with open(os.path.join(RESOURCE_ROOT, "libreoffice-form.pdf"), "rb") as inputfile:
+    # Load PDF file from file
+        reader = PdfReader(inputfile)
+        fields = reader.get_fields()
+        assert "/Opt" in fields['Nationality'].keys() 
+
+
 def test_PdfReaderFileLoad():
     """
     Test loading and parsing of a file. Extract text of the file and compare to expected


Code review comments:
diff_hunk: @@ -302,6 +302,7 @@ class FieldDictionaryAttributes:
     V = "/V"  # text string, optional
     DV = "/DV"  # text string, optional
     AA = "/AA"  # dictionary, optional
+    Opt = "/Opt" # Options, Optional
path: PyPDF2/constants.py
text: @user1:
Very nice that you've added the constant!

This attribute is not defined in Table 8.69 but in Table 8.76. Please use

```suggestion
class CheckboxRadioButtonAttributes:
    """TABLE 8.76 Additional entry specific to check box and radio button fields."""
    Opt = "/Opt" # Options, Optional
```

The main reason for using those constants is to point to the right part of the documentation / adding additional information.

@author:
where is the table/documentation stored at?