Permalink
Browse files

working filter

  • Loading branch information...
1 parent 27c0afc commit 027d2c89625c4613bfd0c3863a6d9d0778965d14 mattg committed Aug 8, 2012
View
@@ -0,0 +1 @@
+_site
View
@@ -0,0 +1,6 @@
+auto: true
+server: true
+baseurl: /bb-site
+exclude: [bin, tilemill, data/original-data]
+prose:
+ rooturl: "_posts"
@@ -0,0 +1,8 @@
+// Global extensions to Backbone.Model
+//
+Backbone.Model.prototype.render = function(key, def) {
@lxbarth
lxbarth Aug 14, 2012

@MateoV - if you're not using the functionality in render() I would kill it. I'd keep using render() even if you pass through as it's useful to distinguish between accessing attributes of a model and accessing them for display on the screen. Programming like this makes it very easy to filter out potentially malicious strings later.

+ def = def || '-';
+ var val = this.get(key);
+ if (val === null || val === undefined) return def;
+ return _.isArray(val) ? val.join(', ') : this.get(key);
+};
@@ -0,0 +1,35 @@
+(function(models, views, routers) {
+
+ // Site model
+ models.Site = Backbone.Model.extend();
+
+ var groupCount = function(items) {
@lxbarth
lxbarth Aug 14, 2012

@MateoV - groupCount() could move into countries() as it's only used once.

+ return _.chain(items)
+ .reduce(function(memo, v) {
+ memo[v] = memo[v] ? ++memo[v] : 1;
+ return memo;
+ }, {})
+ .map(function(v, k) {
+ return { name: k, count: v};
+ })
+ .sortBy(function(v) {
+ return v.name;
+ })
+ .value();
+ };
+
+ // Collection for site models
+ models.Sites = Backbone.Collection.extend({
+ model: models.Site,
+ url: 'data/sites.json',
+ // Returns available countries with counts.
+ countries: function() {
+ var countries = [];
+ this.each(function(sites) {
+ countries.push(sites.get('country'));
+ });
+ return groupCount(countries);
+ }
+ });
+
+}).apply(this, window.args);
@@ -0,0 +1,54 @@
+(function(models, views, routers) {
+
+routers.App = Backbone.Router.extend({
+ initialize: function() {
+ this.app = new views.App({el: '#app'});
@lxbarth
lxbarth Aug 14, 2012

@MateoV - tracking the main view is not actually necessary. You don't wind up using this.app at all. I would keep the App view object anonymous and actually create it in boot.js. Having the router create the main view was a move of convenience in the wb-knowledge project that actually wasn't that clean...

+ },
+ routes: {
+ '': 'home',
+ 'filter': 'filter'
+ },
+ home: function() {
+ },
+ filter: function() {
+ var sites = new models.Sites();
+ sites.fetch({
+ success: function() {
+ //console.log(filter.models);
+
+ var view = new views.Filter({
+ collection: sites
+ });
+ console.log(view.el);
+ //$('#main').append(view.el);
+ }
+ });
+ }/*,
+ project: function(id, country) {
+ var project = new models.Project({id: id});
+ project.fetch({
+ success: function() {
+ country && project.set({country: country});
+ var view = new views.Project({model: project});
+ $('#app').append(view.el);
+ }
+ });
+ },
+ country: function(id, projectId) {
+ var router = this;
+ var country = new models.Country({id: id});
+ country.fetch({
+ success: function() {
+ if (projectId) {
+ return router.project(projectId, country);
+ }
+ var view = new views.Country({
+ model: country
+ });
+ $('#app').append(view.el);
+ }
+ });
+ }*/
+});
+
+}).apply(this, window.args);
@@ -0,0 +1,4 @@
+<script name='app' type='text/html'>{% include templates/app._ %}</script>
+<script name='filter' type='text/html'>{% include templates/filter._ %}</script>
+<script name='sites' type='text/html'>{% include templates/sites._ %}</script>
+<script name='siteitem' type='text/html'>{% include templates/siteitem._ %}</script>
@@ -0,0 +1,6 @@
+---
+---
+<div id='header' class='dark-gradient'></div>
+<div id='main'>
+ <a href='{{site.baseurl}}/#filter' class='filter'>Filter</a>
+</div>
@@ -0,0 +1,3 @@
+<div class='content-heading clearfix'>
+<h1 class='title'>Holocaust Memorial Sites</h1>
+</div>
@@ -0,0 +1,9 @@
+<li>
+ <a href="#" class='clearfix'>
+ <div class='project-intro'>
+ <p class="topic"><%= render('country') %> - <%= render('site') %></p>
+ </div>
+ <div class='project-details'>
+ </div>
+ </a>
+</li>
@@ -0,0 +1,11 @@
+<span id='by'>All</span>
+<div class='filters clearfix'>
+ <ul class='dropdown clearfix'>
+ <li>
+ <a href='#' data-toggle='dropdown' class='dropdown-toggle'>Country</a>
+ <ul id='country-items' data-attribute='country' class='dropdown-menu'>
+ </ul>
+ </li>
+ </ul>
+</div>
+<ul id='projects-list' class='listing'></ul>
@@ -0,0 +1,18 @@
+(function(models, views, routers, templates) {
+
+ views.App = Backbone.View.extend({
+ defaults: {
+ map: null,
+ interaction: null,
+ legend: null
+ },
+ initialize: function(options) {
+ this.render();
+ },
+ render: function() {
+ $(this.el).empty().append(templates.app(this));
+ return this;
+ }
+ });
+
+}).apply(this, window.args);
@@ -0,0 +1,17 @@
+(function(models, views, routers, templates) {
+
+ views.Filter = Backbone.View.extend({
+ initialize: function(options) {
+ this.render();
+ },
+ render: function() {
+ $('#main').append(templates.filter());
+
+ $('#main').append((new views.Sites({
+ collection: this.collection
@lxbarth
lxbarth Aug 14, 2012

@MateoV - It's awkward to pass on the view's collection like this. This line makes me think that we should invert the relationship between Filter and Sites view or possibly better, eliminate the Filter view. Happy to discuss this more.

+ })).render().el);
+
+ return this;
+ }
+ });
+}).apply(this, window.args);
@@ -0,0 +1,81 @@
+(function(models, views, routers, templates) {
+
+ views.Sites = Backbone.View.extend({
+ events: {
+ 'click .dropdown-menu a': 'selectFilter'
+ },
+ initialize: function(options) {
+ this.initialCollection = this.collection;
+ },
+ render: function() {
+ $(this.el).empty().append(templates.sites());
+ this.renderList();
+ return this;
+ },
+ renderList: function() {
+ var view = this;
+
+ var updateFacets = function(selector, facets, reject) {
+ reject = reject || function() { return false; };
+ $(selector, view.el).empty();
+ _.chain(facets)
+ .reject(reject)
+ .each(function(f) {
+ if (!f.count) return;
+ $(selector, view.el).append(
+ "<li><a data-value='" + f.name + "' href='#'>" + f.name +
+ "<span class='count'>" + f.count + "</span></a></li>"
+ );
+ });
+ $(selector, view.el).prepend(
+ "<li><a data-value='All' href='#'>All" +
+ "<span class='count'>" + view.initialCollection.size() + "</span></a></li>"
+ );
+ };
+ updateFacets('#country-items', this.initialCollection.countries(), function(c) {
+ return view.model && c.name == view.model.get('name');
+ });
+
+ $('#projects-list', this.el).empty();
+ this.collection.each(function(site) {
+ $('#projects-list', view.el).append(
+ templates.siteitem(site)
+ );
+ /*
+ $('#projects-list li:last .project-details', view.el)
+ .append(view.model ?
+ templates.projectstats(project.stats(view.model.get('name'))) :
+ "<div class='country-count'>" + project.totalCountries()+ "</div>"
+ );
+ */
+
+ });
+
+ },
+ filterProjects: function(value, attribute) {
+ $('li.open', this.el).removeClass('open');
+ if (value === 'All') {
+ this.collection = this.initialCollection;
+ } else {
+ var collection = this.initialCollection.filter(function(model) {
+ return model.get(attribute) === value;
+ });
+ this.collection = new models.Sites(collection);
+ }
+ $('#by', this.el).text(value);
+ this.trigger('filterProjects', this.collection);
+ console.log(this.collection);
+ return false;
+ },
+ selectFilter: function(e) {
+ console.log($(e.currentTarget).attr('data-value'));
+ this.filterProjects(
+ $(e.currentTarget).attr('data-value'),
+ $(e.currentTarget).parent().parent().attr('data-attribute')
+ );
+ this.renderList();
+ return false;
+ }
+ });
+
+}).apply(this, window.args);
View
@@ -0,0 +1,89 @@
+[
+{"id": 1, "uid": "1", "site": "Gusen", "country": "Austria", "lat": "", "lon": "", "co_lat": "47.58", "co_lon": "14.2", "co_zoom": "7", "desc": "" }
+,
+{"id": 2, "uid": "2", "site": "Mauthausen", "country": "Austria", "lat": "", "lon": "", "co_lat": "47.58", "co_lon": "14.2", "co_zoom": "7", "desc": "" }
+,
+{"id": 3, "uid": "3", "site": "Schloss Hartheim", "country": "Austria", "lat": "", "lon": "", "co_lat": "47.58", "co_lon": "14.2", "co_zoom": "7", "desc": "" }
+,
+{"id": 4, "uid": "4", "site": "Vienna", "country": "Austria", "lat": "", "lon": "", "co_lat": "47.58", "co_lon": "14.2", "co_zoom": "7", "desc": "" }
+,
+{"id": 5, "uid": "5", "site": "Belarus", "country": "Belarus", "lat": "", "lon": "", "co_lat": "53.7", "co_lon": "27.9", "co_zoom": "6", "desc": "" }
+,
+{"id": 6, "uid": "6", "site": "Lidice", "country": "Czech Republic", "lat": "", "lon": "", "co_lat": "49.8", "co_lon": "15.5", "co_zoom": "7", "desc": "" }
+,
+{"id": 7, "uid": "7", "site": "Terezin (Theresianstadt)", "country": "Czech Republic", "lat": "", "lon": "", "co_lat": "49.8", "co_lon": "15.5", "co_zoom": "7", "desc": "" }
+,
+{"id": 8, "uid": "8", "site": "Natzweiler-Strutthof", "country": "France", "lat": "", "lon": "", "co_lat": "46.6", "co_lon": "2.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 9, "uid": "9", "site": "Paris", "country": "France", "lat": "", "lon": "", "co_lat": "46.6", "co_lon": "2.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 10, "uid": "10", "site": "Bergen-Belsen", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 11, "uid": "11", "site": "Berlin", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 12, "uid": "12", "site": "Buchenwald", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 13, "uid": "13", "site": "Dachau", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 14, "uid": "14", "site": "Documentation and Cultural Centre of German Sinti and Roma, Heidelberg", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 15, "uid": "15", "site": "Flossenbürg", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 16, "uid": "16", "site": "Munich", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 17, "uid": "17", "site": "Ravensbrück", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 18, "uid": "18", "site": "Sachsenhausen", "country": "Germany", "lat": "", "lon": "", "co_lat": "51.1", "co_lon": "10.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 19, "uid": "19", "site": "Biķernieki", "country": "Latvia", "lat": "", "lon": "", "co_lat": "57", "co_lon": "24.6", "co_zoom": "7", "desc": "" }
+,
+{"id": 20, "uid": "20", "site": "Riga", "country": "Latvia", "lat": "", "lon": "", "co_lat": "57", "co_lon": "24.6", "co_zoom": "7", "desc": "" }
+,
+{"id": 21, "uid": "21", "site": "Rumbula", "country": "Latvia", "lat": "", "lon": "", "co_lat": "57", "co_lon": "24.6", "co_zoom": "7", "desc": "" }
+,
+{"id": 22, "uid": "22", "site": "Salaspils", "country": "Latvia", "lat": "", "lon": "", "co_lat": "57", "co_lon": "24.6", "co_zoom": "7", "desc": "" }
+,
+{"id": 23, "uid": "23", "site": "Ninth Fort", "country": "Lithuania", "lat": "", "lon": "", "co_lat": "55.4", "co_lon": "24", "co_zoom": "7", "desc": "" }
+,
+{"id": 24, "uid": "24", "site": "Ponary (Paneriai)", "country": "Lithuania", "lat": "", "lon": "", "co_lat": "55.4", "co_lon": "24", "co_zoom": "7", "desc": "" }
+,
+{"id": 25, "uid": "25", "site": "Vilnius (Vilna)", "country": "Lithuania", "lat": "", "lon": "", "co_lat": "55.4", "co_lon": "24", "co_zoom": "7", "desc": "" }
+,
+{"id": 26, "uid": "26", "site": "Amsterdam", "country": "The Netherlands", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "5.5", "co_zoom": "7", "desc": "" }
+,
+{"id": 27, "uid": "27", "site": "Westerbork", "country": "The Netherlands", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "5.5", "co_zoom": "7", "desc": "" }
+,
+{"id": 28, "uid": "28", "site": "Auschwitz-Birkenau", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 29, "uid": "29", "site": "Bełżec", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 30, "uid": "30", "site": "Chełmno (Kulmhof)", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 31, "uid": "31", "site": "Izbica", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 32, "uid": "32", "site": "Józefów", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 33, "uid": "33", "site": "Kazimierz Dolny", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 34, "uid": "34", "site": "Łódź", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 35, "uid": "35", "site": "Lublin", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 36, "uid": "36", "site": "Majdanek", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 37, "uid": "37", "site": "Płaszów", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 38, "uid": "38", "site": "Sobibor", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 39, "uid": "39", "site": "Tarnów", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 40, "uid": "40", "site": "Treblinka", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 41, "uid": "41", "site": "Warsaw", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 42, "uid": "42", "site": "Zamość", "country": "Poland", "lat": "", "lon": "", "co_lat": "52.3", "co_lon": "19.6", "co_zoom": "6", "desc": "" }
+,
+{"id": 43, "uid": "43", "site": "Babi Yar", "country": "Ukraine", "lat": "", "lon": "", "co_lat": "49.2", "co_lon": "31.5", "co_zoom": "6", "desc": "" }
+,
+{"id": 44, "uid": "44", "site": "London", "country": "United Kingdom", "lat": "", "lon": "", "co_lat": "51.5", "co_lon": "0", "co_zoom": "7", "desc": "" }
+]
View
@@ -0,0 +1,27 @@
+---
+---
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset='utf-8' />
+ <title>Backbone Filter</title>
+ <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
+ <meta name='apple-mobile-web-app-status-bar-style' content='black' />
+ <meta name='apple-mobile-web-app-capable' content='yes' />
+ <link rel='stylesheet' href='site2.css' type='text/css' />
+ <link href='http://api.tiles.mapbox.com/mapbox.js/v0.6.2/mapbox.css' rel='stylesheet' type='text/css' />
+</head>
+<body>
+
+ <div id='app'></div>
+ {% include templates.html %}
+
+ <script src='scripts/vendor/jquery.min.js'></script>
+ <script src='scripts/vendor/underscore.min.js'></script>
+ <script src='scripts/vendor/backbone.min.js'></script>
+ <script src='scripts/vendor/bootstrap-dropdown.js'></script>
+ <script src='http://api.tiles.mapbox.com/mapbox.js/v0.6.2/mapbox.js' type='text/javascript'></script>
+ <script src='scripts/boot.js'></script>
+
+</body>
+</html>
Oops, something went wrong.

0 comments on commit 027d2c8

Please sign in to comment.