From 7b4f887466303a06bce060cce1c9f65e4eed0f60 Mon Sep 17 00:00:00 2001 From: Theresa Summa Date: Fri, 19 Dec 2014 00:42:09 +0000 Subject: [PATCH 1/3] single page urls --- static/js/modules/api.js | 12 +++--------- static/js/modules/single-links.js | 20 ++++---------------- static/js/modules/tmpls.js | 16 ++++++++-------- static/js/modules/urls.js | 16 +++++++++++++--- tests/unit/api.js | 2 +- views/candidates-single.handlebars | 20 ++++++++++---------- views/committees-single.handlebars | 10 +++++----- 7 files changed, 44 insertions(+), 52 deletions(-) diff --git a/static/js/modules/api.js b/static/js/modules/api.js index 5c0b7758d..ff5910a12 100644 --- a/static/js/modules/api.js +++ b/static/js/modules/api.js @@ -16,17 +16,11 @@ var callAPI = function(url) { }; var buildURL = function(e) { - var URL = 'rest/' + entityMap[e.category], + var URL = '/rest/' + entityMap[e.category], field; - if (typeof e.filters.cmte_id !== 'undefined') { - URL += '/' + e.filters.cmte_id; - - // if we're requesting a single committee, filters - // aren't applicable, though they still get passed - // in if there were filters chosen leading up to - // finding this committee - delete e.filters; + if (typeof e.id !== 'undefined') { + URL += '/' + e.id; } URL += '?'; diff --git a/static/js/modules/single-links.js b/static/js/modules/single-links.js index 70af8551c..3be7e435c 100644 --- a/static/js/modules/single-links.js +++ b/static/js/modules/single-links.js @@ -7,22 +7,10 @@ var singleClickHandler = function(e) { var id = $(this).data('id'); var category = $(this).data('category'); - if ( category === 'candidate' ) { - events.emit('load:singleEntity', { - category: 'candidates', - filters: { - 'candidate_id': id - } - }); - } - else if ( category === 'committee' ) { - events.emit('load:singleEntity', { - category: 'committees', - filters: { - 'cmte_id': id - } - }); - } + events.emit('load:singleEntity', { + category: category + 's', + id: id + }); } module.exports = { diff --git a/static/js/modules/tmpls.js b/static/js/modules/tmpls.js index 66a274ff6..832f92ae9 100644 --- a/static/js/modules/tmpls.js +++ b/static/js/modules/tmpls.js @@ -14,7 +14,7 @@ var renderBrowse = function(e) { } else { var tmplName = e.category + '-table', - promise = loadTemplate('views/partials/' + tmplName + '.handlebars'); + promise = loadTemplate('/views/partials/' + tmplName + '.handlebars'); promise.done(function(data) { var context = {}; @@ -85,8 +85,8 @@ var renderFilters = function(e) { // pre-load table partial so the template can be shared on client + server $.when( - loadTemplate('views/' + tmplName + '.handlebars'), - loadTemplate('views/partials/' + tmplName + '-table.handlebars') + loadTemplate('/views/' + tmplName + '.handlebars'), + loadTemplate('/views/partials/' + tmplName + '-table.handlebars') ).done(function(tmpl1, tmpl2) { templates[tmplName] = Handlebars.compile(tmpl1[0]); templates[partialName] = Handlebars.registerPartial(partialName, tmpl2[0]); @@ -100,10 +100,10 @@ var renderSearchResultsList = function(e) { i, len = categories.length; - promises.push(loadTemplate('views/search-results.handlebars')); + promises.push(loadTemplate('/views/search-results.handlebars')); for (i = 0; i < len; i++) { - promises.push(loadTemplate('views/partials/' + categories[i] + 's-table.handlebars')); + promises.push(loadTemplate('/views/partials/' + categories[i] + 's-table.handlebars')); } $.when.apply($, promises).done(function() { @@ -133,8 +133,8 @@ var renderSearchResultsList = function(e) { var renderLandingView = function() { $.when( - loadTemplate('views/search.handlebars'), - loadTemplate('views/partials/search-bar.handlebars') + loadTemplate('/views/search.handlebars'), + loadTemplate('/views/partials/search-bar.handlebars') ).done(function(tmpl1, tmpl2) { templates['landing'] = Handlebars.compile(tmpl1[0]); templates['search-bar'] = Handlebars.registerPartial('search-bar', tmpl2[0]); @@ -144,7 +144,7 @@ var renderLandingView = function() { var renderSingleEntity = function(e) { $.when( - loadTemplate('views/' + e.category + '-single.handlebars') + loadTemplate('/views/' + e.category + '-single.handlebars') ).done(function(tmpl1) { var context = {}; context = mapFields(e.category, e.data.results); diff --git a/static/js/modules/urls.js b/static/js/modules/urls.js index b94da96c9..bf50b36df 100644 --- a/static/js/modules/urls.js +++ b/static/js/modules/urls.js @@ -7,7 +7,17 @@ var buildURL = function(context) { field; if (typeof context.category !== 'undefined') { - URL += context.category + '?'; + URL += context.category; + + if (typeof context.id !== 'undefined') { + URL += '/' + context.id; + + return URL; + } + + if (typeof context.query !== 'undefined' || typeof context.filters !== 'undefined') { + URL += '?'; + } if (typeof context.query !== 'undefined') { URL += 'q=' + encodeURIComponent(context.query) + '&'; @@ -22,7 +32,7 @@ var buildURL = function(context) { } } - return URL + 'fields=*'; + return URL; }; var changeURL = function(context) { @@ -37,7 +47,7 @@ module.exports = { init: function() { events.on('load:browse', changeURL); events.on('render:browse', changeURL); - events.on('load:singleEntity', changeURL); + events.on('render:singleEntity', changeURL); events.on('selected:filter', changeURL); events.on('removed:filter', changeURL); events.on('render:searchResultsList', changeURL); diff --git a/tests/unit/api.js b/tests/unit/api.js index 94517a6ab..bc20d3221 100644 --- a/tests/unit/api.js +++ b/tests/unit/api.js @@ -19,7 +19,7 @@ describe('API Module', function() { var context = { category: 'committees', filters: { - cmte_id: '12345' + id: '12345' } }; diff --git a/views/candidates-single.handlebars b/views/candidates-single.handlebars index 83b6f965e..2851df6ce 100644 --- a/views/candidates-single.handlebars +++ b/views/candidates-single.handlebars @@ -74,7 +74,7 @@
JANET FOR DELAWARE

Principal Candidate Campaign Committee | Last updated 11/11/2014

- +
Summary
@@ -103,7 +103,7 @@
FRIENDS OF JANET

Principal Candidate Campaign Committee

- +
Summary
@@ -136,7 +136,7 @@
CANDIDATES XYZ

Principal Candidate Campaign Committee

- +
Summary
@@ -165,7 +165,7 @@
LEADERPAC

Principal Candidate Campaign Committee

- +
Summary
@@ -201,24 +201,24 @@

Independent Expenditures Summary

Total Outside Spending
- +
Super PACs
- +
Party Committees
- +
PACs
- +
Individuals, Corporations & Unions
- +
@@ -438,7 +438,7 @@ - + + - + diff --git a/views/committees-single.handlebars b/views/committees-single.handlebars index d50f5327c..5e910f6f3 100644 --- a/views/committees-single.handlebars +++ b/views/committees-single.handlebars @@ -365,12 +365,4 @@ - - + From 14d0daa91f877fd789f6936a0e2b1e08825ec8da Mon Sep 17 00:00:00 2001 From: Theresa Summa Date: Fri, 19 Dec 2014 01:01:32 +0000 Subject: [PATCH 3/3] some of what I said before --- static/js/modules/single-entity.js | 16 ++++++ static/js/vendor/tablist.js | 87 ++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 static/js/modules/single-entity.js create mode 100644 static/js/vendor/tablist.js diff --git a/static/js/modules/single-entity.js b/static/js/modules/single-entity.js new file mode 100644 index 000000000..06d02a712 --- /dev/null +++ b/static/js/modules/single-entity.js @@ -0,0 +1,16 @@ +'use strict'; + +var events = require('./events.js'); + +var initChosen = function() { + $('.chosen-select').chosen({ + width: "100%", + disable_search: true, + }); +} + +module.exports = { + init: function() { + events.on('bind:singleEntity', initChosen); + } +}; diff --git a/static/js/vendor/tablist.js b/static/js/vendor/tablist.js new file mode 100644 index 000000000..cd555613d --- /dev/null +++ b/static/js/vendor/tablist.js @@ -0,0 +1,87 @@ +/* Accessible tab interface +/* Courtesy of http://heydonworks.com/practical_aria_examples/ +----------------------------------------------------------------------------------------- +*/ + +// The class for the container div + +var $container = '.tab-interface'; + +// Change focus between tabs with arrow keys + +$('[role="tab"]').on('keydown', function(e) { + + // define current, previous and next (possible) tabs + + var $original = $(this); + var $prev = $(this).parents('li').prev().children('[role="tab"]'); + var $next = $(this).parents('li').next().children('[role="tab"]'); + var $target; + + // find the direction (prev or next) + + switch (e.keyCode) { + case 37: + $target = $prev; + break; + case 39: + $target = $next; + break; + default: + $target = false + break; + } + + if ($target.length) { + $original.attr({ + 'tabindex' : '-1', + 'aria-selected' : null + }); + $target.attr({ + 'tabindex' : '0', + 'aria-selected' : true + }).focus(); + } + + // Hide panels + + $($container +' [role="tabpanel"]') + .attr('aria-hidden', 'true'); + + // Show panel which corresponds to target + + $('#' + $(document.activeElement).attr('href').substring(1)) + .attr('aria-hidden', null); + +}); + +// Handle click on tab to show + focus tabpanel + +$('[role="tab"]').on('click', function(e) { + + e.preventDefault(); + + // remove focusability [sic] and aria-selected + + $('[role="tab"]').attr({ + 'tabindex': '-1', + 'aria-selected' : null + }); + + // replace above on clicked tab + + $(this).attr({ + 'aria-selected' : true, + 'tabindex' : '0' + }); + + // Hide panels + + $($container +' [role="tabpanel"]').attr('aria-hidden', 'true'); + + // show corresponding panel + + $('#' + $(this).attr('href').substring(1)) + .attr('aria-hidden', null); + +});