0) {
this.addTagItem($tagCategory, tag, opts);
} else {
- this.$list.append(
- '
' +
- tag +
- ''
- );
+ this.$list.append(`
${tag}`);
}
if (this.$list.find('.tag__item').length > 0) {
- this.$resultType.html('filtered ' + this.opts.resultType + ' for:');
+ this.$resultType.html(`filtered ${this.opts.resultType} for:`);
this.$list.attr('aria-hidden', false);
}
@@ -119,14 +131,15 @@ TagList.prototype.addTag = function(e, opts) {
/**
* Called from within @see TagList.prototype.addTag
- * @param {} $tagCategory
- * @param {} tag
- * @param {} opts
- * @param {} opts.range
+ * @param {jQuery} $tagCategory - element inside this.$list with a matching value for data-tag-category
+ * @param {(boolean|string)} tag - boolean from TagList.addTag(opts.nonremoveable),
+ * or string of HTML element defined by template_nonremoveableTag or template_tag
+ * @param {object} opts
+ * @param {('min' | 'max' | 'false')} opts.range
+ * @param {string} opts.rangeName - appended to a class named of 'tag__category__range--'
*/
TagList.prototype.addTagItem = function($tagCategory, tag, opts) {
var rangeClass = 'tag__category__range--' + opts.rangeName;
-
if (opts.range == 'min') {
$tagCategory.addClass(rangeClass).prepend(tag);
} else if (opts.range == 'max') {
@@ -138,13 +151,16 @@ TagList.prototype.addTagItem = function($tagCategory, tag, opts) {
/**
* Called from @see TagList.prototype.removeTag
- * @param {} $tag
- * @param {} emit
+ * @param {jQuery} $tag
+ * @param {boolean} [emit] - Whether to broadcast tag:removed
+ *
+ * @emits tag:removed from $tag if emit is true
*/
TagList.prototype.removeTagElement = function($tag, emit) {
// This handles the actual removal of the DOM elementrs
var $tagCategory = $tag.parent();
var key = $tag.data('id');
+
if (emit) {
$tag.trigger('tag:removed', [{ key: key }]);
}
@@ -152,21 +168,25 @@ TagList.prototype.removeTagElement = function($tag, emit) {
$tagCategory.removeClass(
'tag__category__range--amount tag__category__range--date'
);
+
if ($tagCategory.is(':empty')) {
$tagCategory.remove();
}
};
/**
- * Called from @see TagList.prototype.removeAllTags
- * Called from @see TagList.prototype.removeTagEvt
- * Called from @see TagList.prototype.addTag
- * @param {} key
- * @param {} emit
- * @param {} forceRemove
+ * Called from TagList.prototype.removeAllTags
+ * Called from TagList.prototype.removeTagEvt
+ * Called from TagList.prototype.addTag
+ * @param {string} key - Used to find [data-id="{key}"] in this.$list
+ * @param {boolean} emit=false - Whether to broadcast that this tag was removed. Comes in as true from removeTagDom(), false from addTag(). Passed to removeTagElement.
+ * @param {boolean} [forceRemove] - Whether to force the removal, like on table switch
+ *
+ * @property {jQuery} $tag - The item in the list with data-id matching the passed key
*/
TagList.prototype.removeTag = function(key, emit, forceRemove) {
var $tag = this.$list.find('[data-id="' + key + '"]');
+
if ($tag.length > 0) {
// If the tag exists, remove the element if it's removable
if ($tag.attr('data-removable') !== 'false') {
@@ -198,8 +218,18 @@ TagList.prototype.removeTag = function(key, emit, forceRemove) {
* @param {} opts
* @param {} opts.forceRemove
* @param {} emit
+ *
+ * @emits tag:removeAll from document.body if emit && if (the clear button has the js-filter-reset class AND
+ * (!opts || !opts.fromFilterSet))
*/
TagList.prototype.removeAllTags = function(e, opts, emit) {
+ console.log('TagList.removeAllTags()');
+ console.log(' typeof e: ', typeof e);
+ console.log(' typeof opts: ', typeof opts);
+ console.log(' typeof emit: ', typeof emit);
+ console.log(' e: ', e);
+ console.log(' opts: ', opts);
+ console.log(' emit: ', emit);
// If the element has the reset class, we revert to the original page state by re-navigating.
// Do not trigger tag removal for filter reset on load
if (
@@ -239,43 +269,31 @@ TagList.prototype.removeAllTags = function(e, opts, emit) {
};
/**
- * The handler when document.body hears filter:removed
- * @param {} e
- * @param {} opts
- * @param {} opts.key
- * @param {} opts.name
+ * The handler when document.body hears filter:removed,
+ * which come from the filter's checkbox items being clicked, or when the chiclets above the table are clicked
+ * @param {jQuery.Event} e - The filter:removed event
+ * @param {object} passedOpts - Object of options
+ * @param {jQuery} passedOpts.filterLabel -
+ * @param {string} passedOpts.name - Is the name of the variable from the API
+ * @param {string} passedOpts.key - Follows the format of {opts.name}-checkbox-{value}
+ * @param {string} passedOpts.value - Used as the visible label for the filter tag
+ * @param {boolean} passedOpts.loadedOnce
+ *
+ * @calls {this.removeTag}
*/
-TagList.prototype.removeTagEvt = function(e, opts) {
+TagList.prototype.removeTagEvt = function(e, passedOpts) {
+ const opts = passedOpts || e.originalEvent.detail;
+
this.removeTag(opts.key, false);
- // logic to handle adding an all years tag if
- // no two year transaction period filter is provided
- // we evaluate on every tag removal=
- //
- /* Hiding this for now since we're removing the Clear all filters option for Indiv Contribs & Receipts
- if (opts.name === 'two_year_transaction_period') {
- var tytp = $('li[data-tag-category="two_year_transaction_period"]');
- var ary = $('li[data-tag-category="all-report-years"]');
- if (tytp.length == 0 && ary.length == 0) {
- // if we didn't already add the all years tag and there are no two year transiaction period filters,
- // add the all year tag
- this.$body.trigger('filter:added', [
- {
- key: 'two_year_transaction_period-all',
- value: 'All report years',
- loadedOnce: true,
- filterLabel: 'All report years',
- name: 'all-report-years',
- nonremovable: true,
- removeOnSwitch: true
- }
- ]);
- }
- }*/
};
/**
- * Click handler for this.$list .js-close
- * @param {} e
+ * Click handler for this.$list .js-close. (looks like an X on the right side of the chiclet)
+ * Looks at the event's target's closest .tag__item and sends its id to removeTag()
+ * @param {jQuery.Event} e - The 'click' event from this.$list .js-close
+ *
+ * @calls @see removeTag > @see removeTagElement > @see removeTagEvt > @see removeTag > @see removeTagElement
+ * TODO: SHOULD THIS ^^ LOOP LIKE IT DOES? (The order of functions above is 1, 2, 3, 1, 2)
*/
TagList.prototype.removeTagDom = function(e) {
var key = $(e.target)
@@ -286,12 +304,15 @@ TagList.prototype.removeTagDom = function(e) {
/**
* Handles document.body filter:renamed
- * @param {} e
- * @param {} opts
- * @param {} opts.key
- * @param {} opts.nonremovable
+ * @param {jQuery.Event} e
+ * @param {CustomEvent} e.originalEvent -
+ * @param {object} passedOpts - Data for the tag. Can also come in a e.originalEvent.detail
+ * @param {string} passedOpts.key - The tag identifier, e.g. committee_id-C00123456-checkbox
+ * @param {string} passedOpts.value - The visible text from the tag
+ * @param {boolean} passedOpts.nonremovable -
*/
-TagList.prototype.renameTag = function(e, opts) {
+TagList.prototype.renameTag = function(e, passedOpts) {
+ const opts = passedOpts || e.originalEvent.detail;
var tag = opts.nonremovable
? template_nonremoveableTag(opts)
: template_tag(opts);
@@ -308,6 +329,9 @@ TagList.prototype.renameTag = function(e, opts) {
* @param {} opts.key
*/
TagList.prototype.disableTag = function(e, opts) {
+ console.log('TagList.disableTag(e, opts): ', e, opts);
+ console.log(' typeof e: ', typeof e);
+ console.log(' typeof opts: ', typeof opts);
var $tag = this.$list.find('[data-id="' + opts.key + '"]');
$tag.closest('.tag__category').hide();
};
@@ -319,6 +343,10 @@ TagList.prototype.disableTag = function(e, opts) {
* @param {} opts.key
*/
TagList.prototype.enableTag = function(e, opts) {
+ console.log('TagList.enableTag(e, opts): ', e, opts);
+ console.log(' typeof e: ', e);
+ console.log(' typeof opts: ', opts);
+
var $tag = this.$list.find('[data-id="' + opts.key + '"]');
$tag.closest('.tag__category').show();
};
diff --git a/fec/fec/static/js/modules/filters/typeahead-filter.js b/fec/fec/static/js/modules/filters/typeahead-filter.js
index 5fd216105a..a9c9c36e44 100644
--- a/fec/fec/static/js/modules/filters/typeahead-filter.js
+++ b/fec/fec/static/js/modules/filters/typeahead-filter.js
@@ -31,8 +31,9 @@ TypeaheadFilter.prototype.fromQuery = function(query) {
return this;
};
-// Ignore changes on typeahead input
-TypeaheadFilter.prototype.handleChange = function() {};
+TypeaheadFilter.prototype.handleChange = function() {
+ // Ignore changes on typeahead input
+};
TypeaheadFilter.prototype.handleNestedChange = function(e) {
var $input = $(e.target);
diff --git a/fec/fec/static/js/modules/form-nav.js b/fec/fec/static/js/modules/form-nav.js
index 9983f2e6fd..9bf11cf5a0 100644
--- a/fec/fec/static/js/modules/form-nav.js
+++ b/fec/fec/static/js/modules/form-nav.js
@@ -13,7 +13,7 @@ function FormNav(form) {
/**
* We don't want empty elements to send empty vars into the form submit.
* So, if it has no value, remove its name, too.
- * @param {Event} e MouseEvent, TouchEvent
+ * @param {Event} e - MouseEvent, TouchEvent
*/
FormNav.prototype.clearNamesIfNull = function(e) {
var allSelects = this.form.querySelectorAll('select,input');
diff --git a/fec/fec/static/js/modules/helpers.js b/fec/fec/static/js/modules/helpers.js
index a3c15de380..9d54ec4a40 100644
--- a/fec/fec/static/js/modules/helpers.js
+++ b/fec/fec/static/js/modules/helpers.js
@@ -498,7 +498,7 @@ function missingDataReason(dataType) {
/**
* Takes a jQuery element and returns whether or not it's in the viewport
* @param {jQuery} $elm - the element to check
- * @return {bool} - If the element is in the viewport
+ * @return {boolean} - If the element is in the viewport
*/
function isInViewport($elm) {
var top = $elm.offset().top;
diff --git a/fec/fec/static/js/modules/keyword-modal.js b/fec/fec/static/js/modules/keyword-modal.js
index 9047a43fb8..9dc70617d4 100644
--- a/fec/fec/static/js/modules/keyword-modal.js
+++ b/fec/fec/static/js/modules/keyword-modal.js
@@ -110,7 +110,7 @@ KeywordModal.prototype.parseValue = function($input) {
/**
* Fire an event to GTM
- * @param {String} actionLabel - Name of the action to register with GA
+ * @param {string} actionLabel - Name of the action to register with GA
*/
KeywordModal.prototype.fireEvent = function(actionLabel) {
// Updating this to use DataLayer for GTM
diff --git a/fec/fec/static/js/modules/line-chart-committees.js b/fec/fec/static/js/modules/line-chart-committees.js
index 2c45c4cac2..5f1336bfc4 100644
--- a/fec/fec/static/js/modules/line-chart-committees.js
+++ b/fec/fec/static/js/modules/line-chart-committees.js
@@ -27,10 +27,10 @@ var MAX_RANGE = 4000000000; // Set the max y-axis to 4 billion
*
* Creates an SVG line chart for total raising and spending
*
- * @param {String} selector - Selector of the parent element
- * @param {String} snapshot - Selector to use for the snapshot,
+ * @param {string} selector - Selector of the parent element
+ * @param {string} snapshot - Selector to use for the snapshot,
* which is the set of numbers that is updated when moving the cursor
- * @param {String} dataType - The type of data the chart is showing ('raised' or 'spent')
+ * @param {string} dataType - The type of data the chart is showing ('raised' or 'spent')
*
*/
diff --git a/fec/fec/static/js/modules/line-chart.js b/fec/fec/static/js/modules/line-chart.js
index c9ee991a33..c54ac6aacd 100644
--- a/fec/fec/static/js/modules/line-chart.js
+++ b/fec/fec/static/js/modules/line-chart.js
@@ -27,10 +27,10 @@ var MAX_RANGE = 4000000000; // Set the max y-axis to 4 billion
*
* Creates an SVG line chart for total raising and spending
*
- * @param {String} selector - Selector of the parent element
- * @param {String} snapshot - Selector to use for the snapshot,
+ * @param {string} selector - Selector of the parent element
+ * @param {string} snapshot - Selector to use for the snapshot,
* which is the set of numbers that is updated when moving the cursor
- * @param {String} dataType - The type of data the chart is showing ('raised' or 'spent')
+ * @param {string} dataType - The type of data the chart is showing ('raised' or 'spent')
*
*/
diff --git a/fec/fec/static/js/modules/site-nav.js b/fec/fec/static/js/modules/site-nav.js
index cb11c38c7c..1a9023ed29 100644
--- a/fec/fec/static/js/modules/site-nav.js
+++ b/fec/fec/static/js/modules/site-nav.js
@@ -84,8 +84,8 @@ SiteNav.prototype.assignAria = function() {
/**
* Append searchbox to correct location upon user screen resize
- * @param {Object} mql
- * @param {Boolean} mql.matches - true if large; false if less than large
+ * @param {object} mql
+ * @param {boolean} mql.matches - true if large; false if less than large
*/
SiteNav.prototype.mediaQueryResponse = function(mql) {
//If large
diff --git a/fec/fec/static/js/modules/tables.js b/fec/fec/static/js/modules/tables.js
index cfb56fb51f..5c286a8e77 100644
--- a/fec/fec/static/js/modules/tables.js
+++ b/fec/fec/static/js/modules/tables.js
@@ -260,7 +260,17 @@ function barsAfterRender(template, api) {
});
}
+/**
+ * Adds a 'change' listener to `$form[0] input` and `$form[0] select`
+ * @param {jQuery} $form - jQuery object of the selector for the div#[type]-filters.filters__content
+ * @param {_Api} api - Object in the form of {context: Array(1), selector: {…}, tables: ƒ, table: ƒ, draw: ƒ,…}
+ */
function updateOnChange($form, api) {
+ /**
+ * @param {jQuery.Event} e
+ * @param {CustomEvent} e.originalEvent
+ * @param {object} e.originalEvent.detail
+ */
function onChange(e) {
e.preventDefault();
hidePanel(api, $('#datatable-modal'));
@@ -271,6 +281,10 @@ function updateOnChange($form, api) {
$form.on('change', 'input,select', _.debounce(onChange, 250));
}
+/**
+ * Called by @fetchSuccess
+ * @param {*} changeCount -
+ */
function filterSuccessUpdates(changeCount) {
// on filter change update:
// - loading/success status
@@ -295,7 +309,7 @@ function filterSuccessUpdates(changeCount) {
.removeClass('is-disabled-filter')
.addClass('is-active-filter');
- // Reenable committee ID typeahead input
+ // Reenable committee ID autosuggest input
$('#committee_id').removeClass('is-disabled-filter');
if (type === 'checkbox') {
@@ -318,10 +332,10 @@ function filterSuccessUpdates(changeCount) {
filterAction = 'Filter removed.';
}
} else if (type === 'text') {
- // typeahead
- if ($elm.hasClass('tt-input')) {
+ // autosuggest
+ if ($elm.hasClass('as-input')) {
// show message after generated checkbox (last item in list)
- $label = $('[data-filter="typeahead"] li').last();
+ $label = $('[data-filter="autosuggest"] li').last();
filterAction = 'Filter added';
} else if ($elm.closest('.range').hasClass('range--currency')) {
$label = $elm.closest('.range');
@@ -704,6 +718,11 @@ DataTable.prototype.enableExport = function() {
}
};
+/**
+ * @param {object} data - Object in the form of {draw: 1, columns: Array(7), order: Array(1), start: 0, length: 30,…}
+ * @param {function} callback
+ * @returns null if we hit the filter limit or !self.filterSet.isValid
+ */
DataTable.prototype.fetch = function(data, callback) {
var self = this;
self.ensureWidgets();
@@ -887,6 +906,10 @@ DataTable.prototype.buildUrl = function(data, paginate, download) {
);
};
+/**
+ *
+ * @param {object} resp - Object in the form of {api_version: '1.0', pagination: {…}, results: Array(30)}
+ */
DataTable.prototype.fetchSuccess = function(resp) {
this.paginator.handleResponse(this.fetchContext.data, resp);
this.fetchContext.callback(mapResponse(resp));
@@ -922,6 +945,11 @@ DataTable.prototype.fetchSuccess = function(resp) {
}
};
+/**
+ *
+ * @param {jQuery.jqXHR} jqXHR -
+ * @param {*} textStatus -
+ */
DataTable.prototype.fetchError = function(jqXHR, textStatus) {
var self = this;
// Default error message that occurs most likely due to timeout
@@ -960,7 +988,7 @@ DataTable.prototype.fetchError = function(jqXHR, textStatus) {
.after($(errorMessage));
} else if (
$(updateChangedEl).attr('type') === 'text' &&
- $(updateChangedEl).hasClass('tt-input') === false
+ $(updateChangedEl).hasClass('as-input') === false
) {
$(updateChangedEl)
.parent()
@@ -1048,6 +1076,10 @@ function initSpendingTables(className, context, options) {
});
}
+/**
+ * @param {*} e -
+ * @param {*} context -
+ */
function refreshTables(e, context) {
var $comparison = $('#comparison');
var selected = $comparison
@@ -1083,6 +1115,13 @@ function refreshTables(e, context) {
}
}
+/**
+ * Called from @see /fec/fec/static/js/pages/elections.js `$(document).ready() $.getJSON(url).done()`
+ * Adds 'change' listener to input[type="checkbox"]
+ * Calls refreshTables()
+ * @param {*} results -
+ * @param {*} pageContext -
+ */
function drawComparison(results, pageContext) {
var $comparison = $('#comparison');
var context = { selected: results.slice(0, 10), options: results.slice(10) };
diff --git a/fec/fec/static/js/modules/typeahead.js b/fec/fec/static/js/modules/typeahead.js
index 22151fce8c..2c2224b994 100644
--- a/fec/fec/static/js/modules/typeahead.js
+++ b/fec/fec/static/js/modules/typeahead.js
@@ -251,17 +251,19 @@ var typeaheadOpts = {
/**
* @class
- * @param {String} selector - A string to be used to find the element in the page.
- * @param {String} type - The kinda of data we'll be showing. e.g., 'candidates'.
- * @param {URL} url - Optional. Where we should find the data if not the default.
+ * @param {string} selector - A string to be used to find the element in the page.
+ * @param {string} type - The kinda of data we'll be showing. e.g., 'candidates'.
+ * @param {URL} [url] - Where we should find the data if not the default.
*
- * @event typeahead:select Triggered when a user clicks an autocomplete search result
+ * @event typeahead:select - Triggered when a user clicks an autocomplete search result
* @property {jQuery.Event}
- * @property {Object} - The data from the selected item
+ * @property {object} - The data from the selected item
*
- * @event typeahead:render Inherited from typeahead.jquery.js, called any time the pulldown menu changes. Typing a character calls the event when the menu is reset _and_ when it's drawn again
+ * @event typeahead:render - Inherited from typeahead.jquery.js, called any time the pulldown menu changes. Typing a character calls the event when the menu is reset _and_ when it's drawn again
* @property {jQuery.Event}
- * @property {Object} - null if no results. Otherwise we get back an {Object} for each item in the menu
+ * @property {object} - null if no results. Otherwise we get back an {Object} for each item in the menu
+ *
+ * @listens window.events.searchTypeChanged
*/
function Typeahead(selector, type, url) {
this.$input = $(selector);
@@ -290,6 +292,11 @@ Typeahead.prototype.init = function() {
this.$input.on('typeahead:select', this.select.bind(this));
};
+/**
+ * Re-inits element on searchTypeChanged event
+ * @param {JQuery.Event} data - From window.events
+ * @listens window.events.searchTypeChanged
+ */
Typeahead.prototype.handleChangeEvent = function(data) {
this.init(data.type);
};
diff --git a/fec/fec/static/js/modules/utils.js b/fec/fec/static/js/modules/utils.js
new file mode 100644
index 0000000000..cccf980772
--- /dev/null
+++ b/fec/fec/static/js/modules/utils.js
@@ -0,0 +1,48 @@
+/**
+ * Multiple small functions meant to be used in various places
+ */
+
+/**
+ * Used to translate 'H', 'S', and 'P' into their full office names
+ */
+const officeNames = {
+ H: 'House',
+ S: 'Senate',
+ P: 'President'
+};
+
+/**
+ * Converts input to a string, changes non-word characters to dashes and trims leading, double, and trailing dashes
+ * @param {*} val - Typically a string that should be translated to slug format
+ * @param {boolean} retainCase - Whether to force to lowercase
+ * @returns {string} lowercase, separated by dashes
+ */
+function slugify(val, retainCase = false) {
+ let toReturn = val.toString();
+
+ if (retainCase === false) toReturn = toReturn.toLowerCase();
+
+ toReturn = toReturn
+ .replace(/\s+/g, '-') // change spaces to dashes
+ .replace(/[^\w\-]+/g, '') // drop any non-word characters (except _ and -)
+ .replace(/\-\-+/g, '-') // change -- to -
+ .replace(/^-+/, '') // remove dashes from the beginning
+ .replace(/-+$/, ''); // remove dashes from the end
+
+ return toReturn;
+}
+
+/**
+ * Removes double quotes from a given value
+ * @param {string} value - A string whose doublequote characters should be removed
+ * @returns {string} A string with any " characters removed
+ */
+ function stripDoubleQuotes(value) {
+ return value.replace(/["]+/g, '');
+}
+
+module.exports = {
+ officeNames,
+ slugify,
+ stripDoubleQuotes
+};
diff --git a/fec/fec/static/js/pages/contact-form.js b/fec/fec/static/js/pages/contact-form.js
index 177b26c81d..c5caad07ea 100644
--- a/fec/fec/static/js/pages/contact-form.js
+++ b/fec/fec/static/js/pages/contact-form.js
@@ -2,6 +2,8 @@
var $ = require('jquery');
var Typeahead = require('../modules/typeahead').Typeahead;
+import { Autosuggest } from '../modules/autosuggest';
+
var URI = require('urijs');
const loadRecaptcha = require('../modules/load-recaptcha').loadRecaptcha;
@@ -19,13 +21,24 @@ function ContactForm($elm) {
this.committeeNameError = $elm.find('.id_committee_name');
this.category = $elm.find('#id_u_category');
this.otherReason = $elm.find('#id_u_other_reason').closest('div');
- this.typeahead = new Typeahead(
- $elm.find('.js-contact-typeahead'),
- 'committees',
- ''
- );
+
+ // TODO: remove the useTt conditional when FEATURES.use_tt goes away
+ if (window.useTt === false) {
+ const elm = $elm.get()[0]; // Converting from jQuery to HTMLElement
+ this.autosuggest = new Autosuggest(elm.querySelector('.js-contact-committee'));
+ this.autosuggest.input.addEventListener('autosuggest:select', this.handleAutosuggestSelection.bind(this));
+
+ } else {
+ this.typeahead = new Typeahead(
+ $elm.find('.js-contact-committee'),
+ 'committees',
+ ''
+ );
+ this.initTypeahead();
+ }
+ // TODO: remove the useTt conditional when FEATURES.use_tt goes away
+
this.$cancel = $elm.find('.js-cancel');
- this.initTypeahead();
this.initOtherReason();
this.category.on('change', this.toggleOtherReason.bind(this));
this.$cancel.on('click', this.clearForm.bind(this));
@@ -53,7 +66,19 @@ ContactForm.prototype.initTypeahead = function() {
};
/**
- * Clear comm_id field when keyup is registered on comm name field.
+ * Handles when an autosuggest selection is made.
+ * Assigns the selection value (id) to this.committeeId,
+ * and sets the name of the selection into the field.
+ * @param {CustomEvent} e - From inside autosuggest
+ * @listens this.autosuggest.input#autosuggest:select
+ */
+ContactForm.prototype.handleAutosuggestSelection = function(e) {
+ this.committeeId.val(e.detail.selection.value.id);
+ this.autosuggest.input.value = e.detail.selection.value.name;
+};
+
+ /**
+ * Clear comm_id field when keyup is registered on comm name field.
*/
ContactForm.prototype.clearHidden = function() {
this.committeeId.val('');
@@ -104,14 +129,34 @@ function AnalystLookup($elm) {
this.$analystDetails = this.$elm.find('.js-yes-analyst');
this.$analystNoResults = this.$elm.find('.js-no-analyst');
- this.typeahead = new Typeahead(this.$input, 'committees', '');
- this.initTypeahead();
+ // TODO: remove the useTt conditional when FEATURES.use_tt goes away
+ if (window.useTt === false) {
+ this.autosuggest = new Autosuggest(this.$input.get()[0]); // Converting from jQuery $input to HTMLElement
+ this.autosuggest.input.addEventListener('autosuggest:select', this.handleAutosuggestSelection.bind(this));
+ this.autosuggest.input.addEventListener('change', this.handleChange.bind(this));
+ this.autosuggest.input.addEventListener('blur', this.handleChange.bind(this));
- this.$input.on('change, blur', this.handleChange.bind(this));
+ } else {
+ this.typeahead = new Typeahead(this.$input, 'committees', '');
+ this.initTypeahead();
+ this.$input.on('change, blur', this.handleChange.bind(this));
+ }
loadRecaptcha();
}
+/**
+ * Handles when an autosuggest selection is made.
+ * Sets the name of the selection into the field,
+ * and calls fetchAnalyst.
+ * @param {CustomEvent} e - From inside autosuggest
+ * @listens this.autosuggest.input#autosuggest:select
+ */
+AnalystLookup.prototype.handleAutosuggestSelection = function(e) {
+ this.autosuggest.input.value = e.detail.selection.value.name;
+ this.fetchAnalyst(e, e.detail.selection.value);
+};
+
/**
*
*/
diff --git a/fec/fec/static/js/vendor/tablist.js b/fec/fec/static/js/vendor/tablist.js
index f8b425581a..047e71f84c 100644
--- a/fec/fec/static/js/vendor/tablist.js
+++ b/fec/fec/static/js/vendor/tablist.js
@@ -15,6 +15,11 @@ var analytics = require('../modules/analytics');
var $container = '.tab-interface';
+/**
+ * called from @init and @refreshTabs
+ * @param {*} $target
+ * @param {*} push
+ */
function show($target, push) {
// Toggle tabs
$('[role="tab"]').attr({
diff --git a/fec/fec/static/js/widgets/aggregate-totals-box.js b/fec/fec/static/js/widgets/aggregate-totals-box.js
index a70dbe84da..c974023c92 100644
--- a/fec/fec/static/js/widgets/aggregate-totals-box.js
+++ b/fec/fec/static/js/widgets/aggregate-totals-box.js
@@ -16,17 +16,18 @@ const isModernBrowser = 'fetch' in window && 'assign' in Object;
// Includes
import analytics from '../modules/analytics';
import { buildUrl } from '../modules/helpers';
-import { electionYearsOptions, officeDefs } from './widget-vars';
+import { electionYearsOptions } from './widget-vars';
+import { officeNames } from '../modules/utils';
/**
* Handles the functionality for the aggregate totals box(es).
* Loads, creates an