Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Political Memory
memopol
Commits
0a22f9a0
Commit
0a22f9a0
authored
Oct 14, 2016
by
njoyard
Browse files
Merge branch 'autocomplete-all-the-things' into 'master'
Autocomplete all the things See merge request
!175
parents
2a3afb72
ec5ff1db
Pipeline
#220
passed with stages
in 9 minutes and 23 seconds
Changes
24
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
setup.py
View file @
0a22f9a0
...
...
@@ -11,7 +11,7 @@ setup(name='political-memory',
author_email
=
'cortex@worlddomination.be'
,
url
=
'http://github.com/political-memory/political_memory/'
,
install_requires
=
[
'django-autocomplete-light==3.
1.6
'
,
'django-autocomplete-light==3.
2.0
'
,
'django-autoslug>=1.9,<1.10'
,
'django-bootstrap3>=6,<7'
,
'django-coffeescript>=0.7,<0.8'
,
...
...
src/memopol/context_processors.py
View file @
0a22f9a0
from
memopol_settings.models
import
Setting
from
representatives.models
import
Chamber
,
Group
from
.forms
import
DossierSearchForm
,
RepresentativeSearchForm
def
search_form_options
(
request
):
d
=
{}
# Note: Those queries needs to be eval in the template so that we can cache
# it efficiently
from
memopol_settings.models
import
Setting
d
[
'chambers'
]
=
Chamber
.
objects
.
all
()
d
[
'countries'
]
=
Group
.
objects
.
filter
(
kind
=
'country'
)
d
[
'parties'
]
=
Group
.
objects
.
filter
(
kind
=
'group'
)
d
[
'delegations'
]
=
Group
.
objects
.
filter
(
kind
=
'delegation'
)
d
[
'committees'
]
=
Group
.
objects
.
filter
(
kind
=
'committee'
)
return
d
def
search_forms
(
request
):
return
{
'representative_search_form'
:
RepresentativeSearchForm
(
request
.
GET
),
'dossier_search_form'
:
DossierSearchForm
(
request
.
GET
)
}
def
intro_text
(
request
):
...
...
src/memopol/forms.py
0 → 100644
View file @
0a22f9a0
from
django
import
forms
from
dal
import
autocomplete
,
forward
from
representatives.models
import
Chamber
,
Group
class
RepresentativeSearchForm
(
forms
.
Form
):
search
=
forms
.
CharField
(
required
=
False
,
label
=
'Name'
,
widget
=
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
''
})
)
scoremin
=
forms
.
FloatField
(
required
=
False
,
label
=
'Between'
,
widget
=
forms
.
NumberInput
(
attrs
=
{
'placeholder'
:
'Min. score'
})
)
scoremax
=
forms
.
FloatField
(
required
=
False
,
label
=
'and'
,
widget
=
forms
.
NumberInput
(
attrs
=
{
'placeholder'
:
'Max. score'
})
)
chamber
=
forms
.
ModelChoiceField
(
queryset
=
Chamber
.
objects
.
all
(),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'chamber-autocomplete'
,
attrs
=
{
'data-html'
:
'true'
}
)
)
country
=
forms
.
ModelChoiceField
(
queryset
=
Group
.
objects
.
filter
(
kind
=
'country'
),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'group-autocomplete'
,
forward
=
(
forward
.
Const
(
'country'
,
'kind'
),),
attrs
=
{
'data-html'
:
'true'
}
)
)
party
=
forms
.
ModelChoiceField
(
queryset
=
Group
.
objects
.
filter
(
kind
=
'group'
),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'group-autocomplete'
,
forward
=
(
forward
.
Const
(
'group'
,
'kind'
),),
attrs
=
{
'data-html'
:
'true'
}
)
)
committee
=
forms
.
ModelChoiceField
(
queryset
=
Group
.
objects
.
filter
(
kind
=
'committee'
),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'group-autocomplete'
,
forward
=
(
forward
.
Const
(
'committee'
,
'kind'
),),
attrs
=
{
'data-html'
:
'true'
}
)
)
delegation
=
forms
.
ModelChoiceField
(
queryset
=
Group
.
objects
.
filter
(
kind
=
'delegation'
),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'group-autocomplete'
,
forward
=
(
forward
.
Const
(
'delegation'
,
'kind'
),),
attrs
=
{
'data-html'
:
'true'
}
)
)
class
DossierSearchForm
(
forms
.
Form
):
search
=
forms
.
CharField
(
required
=
False
,
label
=
'Name'
,
widget
=
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
''
})
)
chamber
=
forms
.
ModelChoiceField
(
queryset
=
Chamber
.
objects
.
all
(),
required
=
False
,
widget
=
autocomplete
.
ModelSelect2
(
url
=
'chamber-autocomplete'
,
attrs
=
{
'data-html'
:
'true'
}
)
)
src/memopol/settings.py
View file @
0a22f9a0
...
...
@@ -133,7 +133,7 @@ TEMPLATE_LOADERS = (
TEMPLATE_CONTEXT_PROCESSORS
=
global_settings
.
TEMPLATE_CONTEXT_PROCESSORS
+
(
'django.template.context_processors.request'
,
'memopol.context_processors.search_form
_option
s'
,
'memopol.context_processors.search_forms'
,
'memopol.context_processors.intro_text'
)
...
...
src/memopol/static/css/custom.css
View file @
0a22f9a0
...
...
@@ -59,7 +59,7 @@ a.tag:hover {
}
body
,
.panel-title
{
font-family
:
FiraSansRegula
t
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-family
:
FiraSansRegula
r
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
}
h2
,
h3
,
h4
,
h5
,
h6
{
...
...
@@ -99,7 +99,7 @@ label {
font-weight
:
400
;
}
.form-control
,
input
,
textarea
{
.form-control
,
.control-label
,
input
,
textarea
{
color
:
#212121
!important
;
}
...
...
@@ -129,7 +129,7 @@ label {
box-shadow
:
inset
0
1px
1px
rgba
(
0
,
0
,
0
,
0.075
),
0
0
8px
rgba
(
102
,
175
,
233
,
0.6
);
}
textarea
,
textarea
.form-control
,
input
.form-control
,
input
[
type
=
text
],
input
[
type
=
password
],
input
[
type
=
email
],
input
[
type
=
number
],
[
type
=
text
]
.form-control
,
[
type
=
password
]
.form-control
,
[
type
=
email
]
.form-control
,
[
type
=
tel
]
.form-control
,
[
contenteditable
]
.form-control
{
textarea
,
textarea
.form-control
,
input
.form-control
,
input
[
type
=
text
],
input
[
type
=
number
],
input
[
type
=
password
],
input
[
type
=
email
],
input
[
type
=
number
],
[
type
=
text
]
.form-control
,
[
type
=
number
]
.form-control
,
[
type
=
password
]
.form-control
,
[
type
=
email
]
.form-control
,
[
type
=
tel
]
.form-control
,
[
contenteditable
]
.form-control
{
padding
:
0
;
border
:
none
;
border-radius
:
0
;
...
...
@@ -138,7 +138,7 @@ textarea, textarea.form-control, input.form-control, input[type=text], input[typ
box-shadow
:
inset
0
-1px
0
#ddd
;
}
textarea
:focus
,
textarea
.form-control
:focus
,
input
.form-control
:focus
,
input
[
type
=
text
]
:focus
,
input
[
type
=
password
]
:focus
,
input
[
type
=
email
]
:focus
,
input
[
type
=
number
]
:focus
,
[
type
=
text
]
.form-control
:focus
,
[
type
=
password
]
.form-control
:focus
,
[
type
=
email
]
.form-control
:focus
,
[
type
=
tel
]
.form-control
:focus
,
[
contenteditable
]
.form-control
:focus
{
textarea
:focus
,
textarea
.form-control
:focus
,
input
.form-control
:focus
,
input
[
type
=
text
]
:focus
,
input
[
type
=
number
]
:focus
,
input
[
type
=
password
]
:focus
,
input
[
type
=
email
]
:focus
,
input
[
type
=
number
]
:focus
,
[
type
=
text
]
.form-control
:focus
,
[
type
=
number
]
.form-control
:focus
,
[
type
=
password
]
.form-control
:focus
,
[
type
=
email
]
.form-control
:focus
,
[
type
=
tel
]
.form-control
:focus
,
[
contenteditable
]
.form-control
:focus
{
-webkit-box-shadow
:
inset
0
-2px
0
#487ED6
;
box-shadow
:
inset
0
-2px
0
#487ED6
;
}
...
...
@@ -167,6 +167,49 @@ select:focus, select.form-control:focus {
background-image
:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=)
;
}
/***************************************************************
Select2
***************************************************************/
.select2-selection
{
border
:
none
!important
;
border-radius
:
0
!important
;
box-shadow
:
rgb
(
221
,
221
,
221
)
0px
-1px
0px
0px
inset
!important
;
}
.select2-container--focus
.select2-selection
{
box-shadow
:
rgb
(
72
,
126
,
214
)
0px
-2px
0px
0px
inset
!important
;
}
.select2-selection__choice
{
background-color
:
#487ED6
!important
;
padding
:
.2em
.6em
.3em
!important
;
color
:
#fff
!important
;
vertical-align
:
baseline
!important
;
border-radius
:
.25em
!important
;
border-color
:
#487ED6
!important
;
font-size
:
80%
!important
;
font-weight
:
bold
!important
;
}
.select2-selection__choice__remove
{
color
:
#fff
!important
;
}
.select2-icon-result
{
display
:
flex
;
flex-flow
:
row
nowrap
;
}
.select2-icon-result
.group-icon
{
flex-shrink
:
0
;
}
.select2-icon-result
.select2-label
{
flex-grow
:
1
;
}
/***************************************************************
Buttons
***************************************************************/
...
...
@@ -485,6 +528,14 @@ iframe {
height
:
1.75em
;
}
.select2-icon-result
.chamber-icon
,
.select2-icon-result
.group-icon
,
.select2-icon-result
.flag-icon
{
width
:
1.75em
;
height
:
1.75em
;
margin-right
:
0.5em
;
}
.flag-icon
:before
{
content
:
initial
;
}
...
...
src/memopol/templates/_base_search.html
View file @
0a22f9a0
{% load i18n memopol_tags %}
{% load fontawesome %}
{% load bootstrap3 %}
<form
class=
"form-horizontal hidden-print"
method=
"GET"
action=
"{% url "
representative-list
"
%}"
>
<div
class=
"input-group"
>
...
...
@@ -30,97 +31,20 @@
aria-expanded=
"{% if view == 'representative_list' and filter.data %}true{% else %}false{% endif %}"
id=
"form-rep"
>
<form
id=
"rep-search-form"
class=
"form-horizontal"
method=
"GET"
action=
"{% url "
representative-list
"
%}"
>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"search-rep"
>
{% trans "Name" %}
</label
>
<div
class=
"col-
sm-9
"
>
<input
type=
"text"
class=
"form-control"
name=
"search"
id=
"search-rep"
value=
"{{ filter.data.search }}"
>
{% bootstrap_field representative_search_form.search layout='horizontal' %}
<div
class=
"row"
>
<div
class=
"col-
md-7
"
>
{% bootstrap_field representative_search_form.scoremin layout='horizontal' horizontal_label_class='col-md-5' horizontal_field_class='col-md-7' placeholder='prout' %}
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"score-min"
>
{% trans "Score between" %}
</label>
<div
class=
"col-sm-4"
>
<input
type=
"number"
class=
"form-control"
name=
"scoremin"
id=
"score-min"
value=
"{{ filter.data.scoremin }}"
>
</div>
<label
class=
"col-sm-1"
for=
"score-max"
>
{% trans "and" %}
</label>
<div
class=
"col-sm-4"
>
<input
type=
"number"
class=
"form-control"
name=
"scoremax"
id=
"score-max"
value=
"{{ filter.data.scoremax }}"
>
<div
class=
"col-md-5"
>
{% bootstrap_field representative_search_form.scoremax layout='horizontal' horizontal_label_class='col-md-2' horizontal_field_class='col-md-10' %}
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"chamber-rep"
>
{% trans "Chamber" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
id=
"chamber-rep"
name=
"chamber"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for chamber in chambers %}
<option
{%
if
filter.data.chamber =
chamber.id|cast_str
%}
selected
{%
endif
%}
value=
"{{ chamber.id }}"
>
{{ chamber.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"country"
>
{% trans "Country" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
id=
"country"
name=
"country"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for country in countries %}
<option
{%
if
filter.data.country =
country.id|cast_str
%}
selected
{%
endif
%}
value=
"{{ country.id }}"
>
{% if country.abbreviation %}{{ country.abbreviation }}
–
{% endif %}
{{ country.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"party"
>
{% trans "Party" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
id=
"party"
name=
"party"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for party in parties %}
<option
{%
if
filter.data.party =
party.pk|cast_str
%}
selected
{%
endif
%}
value=
"{{ party.pk }}"
>
{% if party.abbreviation %}{{ party.abbreviation }}
–
{% endif %}
{{ party.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"committee"
>
{% trans "Committee" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
id=
"committee"
name=
"committee"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for committee in committees %}
<option
{%
if
filter.data.committee =
committee.pk|cast_str
%}
selected
{%
endif
%}
value=
"{{ committee.pk }}"
data-url=
"{% url "
representative-list
"
%}?
committee=
{{
committee.pk
}}"
>
{% if committee.abbreviation %}{{ committee.abbreviation }}
–
{% endif %}
{{ committee.name }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"delegation"
>
{% trans "Delegation" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
id=
"delegation"
name=
"delegation"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for delegation in delegations %}
<option
{%
if
filter.data.delegation =
delegation.pk|cast_str
%}
selected
{%
endif
%}
value=
"{{ delegation.pk }}"
data-url=
"{% url "
representative-list
"
%}?
delegation=
{{
delegation.pk
}}"
>
{{ delegation.name }}
</option>
{% endfor %}
</select>
</div>
</div>
{% bootstrap_field representative_search_form.chamber layout='horizontal' %}
{% bootstrap_field representative_search_form.country layout='horizontal' %}
{% bootstrap_field representative_search_form.party layout='horizontal' %}
{% bootstrap_field representative_search_form.committee layout='horizontal' %}
{% bootstrap_field representative_search_form.delegation layout='horizontal' %}
<button
type=
"submit"
class=
"btn btn-default"
>
{% trans "Search" %}
</button>
</form>
</div>
...
...
@@ -133,29 +57,10 @@
<div
class=
"collapse{% if view == 'dossier_list' and filter.data %} in{% endif %}"
aria-expanded=
"{% if view == 'dossier_list' and filter.data %}true{% else %}false{% endif %}"
id=
"form-dossier"
>
<form
id=
"dossier-search-form"
class=
"form-horizontal"
method=
"GET"
action=
"{% url "
dossier-list
"
%}"
>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"search-dossier"
>
{% trans "Name" %}
</label>
<div
class=
"col-sm-9"
>
<input
type=
"text"
class=
"form-control"
name=
"search"
id=
"search-dossier"
value=
"{{ filter.data.search }}"
>
</div>
</div>
<div
class=
"form-group"
>
<label
class=
"col-sm-3"
for=
"chamber-dossier"
>
{% trans "Chamber" %}
</label>
<div
class=
"col-sm-9"
>
<select
class=
"form-control"
name=
"chamber"
id=
"chamber-dossier"
>
<option
value=
""
>
{% trans "All" %}
</option>
{% for chamber in chambers %}
<option
{%
if
filter.data.chamber =
chamber.id|cast_str
%}
selected
{%
endif
%}
value=
"{{ chamber.id }}"
>
{{ chamber.name }}
</option>
{% endfor %}
</select>
</div>
</div>
{% bootstrap_field dossier_search_form.search layout='horizontal' %}
{% bootstrap_field dossier_search_form.chamber layout='horizontal' %}
<button
type=
"submit"
class=
"btn btn-default"
>
{% trans "Search" %}
</button>
</form>
</div>
</div>
\ No newline at end of file
</div>
src/memopol/tests/base.py
View file @
0a22f9a0
...
...
@@ -9,16 +9,8 @@ class BaseTest(ResponseDiffTestMixin, test.TestCase):
"""
Common queries
- 1 for settings
- 5 for search forms
- 1 for chambers
- 1 for countries
- 1 for parties
- 1 for committees
- 1 for delegations
- 1 for the position form
- 1 for themes
"""
left_pane_queries
=
7
left_pane_queries
=
1
def
setUp
(
self
):
RepresentativeScore
.
refresh
()
...
...
@@ -72,8 +64,9 @@ class ThemeBaseTest(BaseTest):
"""
Common queries plus:
- 1 for the theme
- 1 for DAL to fetch its initial value in the position form
"""
queries
=
BaseTest
.
left_pane_queries
+
1
queries
=
BaseTest
.
left_pane_queries
+
2
@
property
def
url
(
self
):
...
...
src/memopol/tests/response_fixtures/NavigationPaneTest.test_dossier_search_chambers.content
deleted
100644 → 0
View file @
2a3afb72
<option value="">All</option>
---
<option value="1">
European Parliament
</option>
---
<option value="2">
Assemblée nationale
</option>
---
<option value="3">
Sénat
</option>
\ No newline at end of file
src/memopol/tests/response_fixtures/NavigationPaneTest.test_dossier_search_chambers.metadata
deleted
100644 → 0
View file @
2a3afb72
{
"status_code": 200
}
\ No newline at end of file
src/memopol/tests/response_fixtures/NavigationPaneTest.test_rep_search_chambers.content
deleted
100644 → 0
View file @
2a3afb72
<option value="">All</option>
---
<option value="1">
European Parliament
</option>
---
<option value="2">
Assemblée nationale
</option>
---
<option value="3">
Sénat
</option>
\ No newline at end of file
src/memopol/tests/response_fixtures/NavigationPaneTest.test_rep_search_chambers.metadata
deleted
100644 → 0
View file @
2a3afb72
{
"status_code": 200
}
\ No newline at end of file
src/memopol/tests/response_fixtures/NavigationPaneTest.test_rep_search_committee.content
deleted
100644 → 0
View file @
2a3afb72
<option value="">All</option>
---
<option data-url="/representatives/?committee=345" value="345">
AnComImmu –
Commission chargée de l'application de l'article 26 de la constitution
</option>
---
<option data-url="/representatives/?committee=274" value="274">
AnComDef –
Commission de la défense nationale et des forces armées
</option>
---
<option data-url="/representatives/?committee=387" value="387">
Commission d'enquête relative aux moyens mis en œuvre par l'État pour lutter contre le terrorisme depuis le 7 janvier
</option>
---
<option data-url="/representatives/?committee=876" value="876">
Commission d'enquête sur les conditions d'abattage des animaux de boucherie dans les abattoirs français
</option>
---
<option data-url="/representatives/?committee=484" value="484">
Commission d'enquête sur les conditions d'octroi d'une autorisation d'émettre à la chaîne numéro 23 et de sa vente
</option>
---
<option data-url="/representatives/?committee=1297" value="1297">
Commission d'enquête visant à évaluer les conséquences sur l'investissement public et les services publics de proximité de la baisse des dotations de l'État aux communes et aux epci
</option>
---
<option data-url="/representatives/?committee=335" value="335">
AnComCult –
Commission des affaires culturelles et de l'éducation
</option>
---
<option data-url="/representatives/?committee=427" value="427">
AnComEco –
Commission des affaires économiques
</option>
---
<option data-url="/representatives/?committee=285" value="285">
AnComEtrg –
Commission des affaires étrangères
</option>
---
<option data-url="/representatives/?committee=364" value="364">
AnComEU –
Commission des affaires européennes
</option>
---
<option data-url="/representatives/?committee=365" value="365">
AnComSoc –
Commission des affaires sociales
</option>
---
<option data-url="/representatives/?committee=401" value="401">
AnComFin –
Commission des finances, de l'économie générale et du contrôle budgétaire
</option>
---
<option data-url="/representatives/?committee=530" value="530">
AnComLois –
Commission des lois constitutionnelles, de la législation et de l'administration générale de la république
</option>
---
<option data-url="/representatives/?committee=423" value="423">
AnComDevD –
Commission du développement durable et de l'aménagement du territoire
</option>
---
<option data-url="/representatives/?committee=346" value="346">
Commission spéciale chargée d'examiner le projet de loi Égalité et citoyenneté
</option>
---
<option data-url="/representatives/?committee=1622" value="1622">
Commission spéciale chargée d'examiner le projet de loi pour la croissance et l'activité
</option>
---
<option data-url="/representatives/?committee=286" value="286">
Commission spéciale pour l'examen de la proposition de loi renforçant la lutte contre le système prostitutionnel
</option>
---
<option data-url="/representatives/?committee=47" value="47">
AGRI –
Committee on Agriculture and Rural Development
</option>
---
<option data-url="/representatives/?committee=89" value="89">
CONT –
Committee on Budgetary Control
</option>
---
<option data-url="/representatives/?committee=34" value="34">
BUDG –
Committee on Budgets
</option>
---
<option data-url="/representatives/?committee=7" value="7">
LIBE –
Committee on Civil Liberties, Justice and Home Affairs
</option>
---
<option data-url="/representatives/?committee=37" value="37">
AFCO –
Committee on Constitutional Affairs
</option>
---
<option data-url="/representatives/?committee=20" value="20">
CULT –
Committee on Culture and Education
</option>
---
<option data-url="/representatives/?committee=8" value="8">
DEVE –
Committee on Development
</option>
---
<option data-url="/representatives/?committee=30" value="30">
ECON –
Committee on Economic and Monetary Affairs
</option>
---
<option data-url="/representatives/?committee=3" value="3">
EMPL –
Committee on Employment and Social Affairs
</option>
---
<option data-url="/representatives/?committee=55" value="55">
PECH –
Committee on Fisheries
</option>
---
<option data-url="/representatives/?committee=5" value="5">
AFET –
Committee on Foreign Affairs
</option>
---
<option data-url="/representatives/?committee=23" value="23">
ITRE –
Committee on Industry, Research and Energy
</option>
---
<option data-url="/representatives/?committee=49" value="49">
INTA –
Committee on International Trade