I've written a short piece of code to get myself familiar with backbone.js. I'm filtering 100 results from the Twitter API. Once those are in, I use a time picker and a hash tag selector to filter my results.
I want the filter to work in the following manner:
Pick a time range, get a filtered collection and a filtered set of hash tags in the selector tag. Pick a hash tag, filter the SAME RESULTS within that time range.
Pick a hashtag, get a filtered collection. Select a date and filter the same results gotten with the originally chosen hashtag.
Don't lose the original collection:
"use strict";
Define the model:
var Tweet = Backbone.Model.extend({});
Define the collection:
var Tweets = Backbone.Collection.extend({
initialize : function(options) {
if (options !== undefined) {
if (options.location !== undefined) {
this.location = options.location;
// console.log(location);
}
}
},
model : Tweet,
parse : function(response) {
var data = response.results;
$(data).each(
function() {
var timezoneOffset = new Date().getTimezoneOffset() / -60;
// var offset = Date.getTimezoneOffset(today.getTimezone(),
// today.hasDaylightSavingTime());
// console.log(timezoneOffset);
var dateTime = Date.parse(this.created_at).addHours(
timezoneOffset).toString(
"dddd, MMMM dd, yyyy, h:mm:ss tt");
this.created_at = dateTime;
this.text = twttr.txt.autoLink(this.text);
this.from_user = twttr.txt.autoLink("@" + this.from_user);
// console.log("user: ", this.from_user);
});
// console.log('\nformatted data: ', data);
return data;
},
Overwrite the sync method to pass over the Same Origin Policy:
sync : function(method, model, options) {
// console.log(options);
var self = this;
var params = {
url : 'http://search.twitter.com/search.json?q=' + self.location
+ '&rpp=100&lang=all&include_entities=true',
type : 'GET',
dataType : 'jsonp',
processData : false
};
options = _.extend(options, params);
return $.ajax(options);
},
showhide : function(toDate, fromDate) {
// console.log(toDate,"\n", fromDate,"\n", this.models);
var results;
//if(toDate !== undefined && fromDate !== undefined){
results = this.filter(function(tweet) {
var tweetDate = Date.parse(tweet.attributes.created_at);
if (tweetDate.between(fromDate, toDate)) {
//console.log("valid ", tweet);
return true;
}
});
//}
return results;
console.log("Date Filtered Results: ", results);
},
selectShowHide : function(selectedHashTag){
var results;
if(selectedHashTag !== 'all'){
results = this.filter(function(tweet){
var hashtag = tweet.attributes.entities.hashtags;
//console.log("hashtag array: ", hashtag);
var matchingHashTag = "";
$(hashtag).each(function(){
if(this.text == selectedHashTag){
return matchingHashTag = true;
}
});
return matchingHashTag;
});
}
else{
results = this.filter(function(tweet){
return true;
});
}
return results;
console.log("Date Filtered Results: ", results);
}
});
Define the Master View:
var MasterView = Backbone.View.extend({
initialize : function() {
// console.log("Master View Initialized");
},
events : {
"click #buttonSubmit" : "doSearch",
},
doSearch : function() {
// console.log(this);
var $self = this.$el;
// THIS IS VERY IMPORTANT!!! DEFINE A TOP VIEW LEVEL COLLECTION FOR YOUR
// VIEWS TO WORK ON
// IF YOU WISH TO DO FRONT END FILTERING ON YOUR RESULTS!!!
var TweetResults = new Tweets({
location : $self.find('#textLocation').val()
});
TweetResults.fetch({
success : function(collection, resp) {
var dateView = new DateView({
el : $('#date'),
collection : collection
});
var selectView = new SelectView({
el: $('#hashTag'),
collection: collection
});
var resultsView = new ResultsView({
el : $('#display'),
collection : collection
});
var resetView = new ResetView({
el: $("#reset"),
collection : collection
});
}
});
}
});
Define the reset View
var ResetView = Backbone.View.extend({
initialize: function(options){
this.collection = options.collection;
this.render();
},
render: function(){
this.$el.html("");
var self = this;
$.ajax({
url : '../templates/ResetTemplate.html',
cache : false,
success : function(data) {
templateLoader(data, self);
}
});
},
events:{
"click #buttonReset": "collectionReset"
},
collectionReset: function(){
var dateView = new DateView({
el : $('#date'),
collection : this.collection
});
var resultsView = new ResultsView({
el : $('#display'),
collection : this.collection
});
var selectView = new SelectView({
el: $('#hashTag'),
collection: this.collection
});
}
});
Define the date View
var DateView = Backbone.View
.extend({
initialize : function(options) {
// console.log('Date View Initialized');
this.collection = options.collection;
this.render();
},
render : function() {
this.$el.html("");
var self = this;
$.ajax({
url : '../templates/DateTemplate.html',
cache : false,
success : function(data) {
templateLoader(data, self);
datePicker(self, "#textFrom");
datePicker(self, "#textTo");
}
});
},
events : {
"click #buttonFilter" : "showHide"
},
// filter the results
showHide : function() {
var fromDate = "";
var toDate = "";
if ($('#textFrom').val() === "") {
alert("Please Enter a 'From' Date");
} else {
fromDate = Date.parse($('#textFrom').val());
}
if ($('#textTo').val() === "") {
alert("Please Enter a 'To' Date");
} else {
toDate = Date.parse($('#textTo').val());
}
if (toDate && fromDate && fromDate.isBefore(toDate)) {
var filteredCollection = new Tweets(this.collection
.showhide(toDate, fromDate));
//console.log("filtered results: ", filteredCollection);
var filteredResultsView = new ResultsView({
el : $('#display'),
collection : filteredCollection
});
/*var filteredSelectView = new SelectView({
el : $('#hashTag'),
collection : filteredCollection
});*/
} else {
alert("Please check if your 'From' date comes before your 'To' date!");
}
}
});
Define the select View:
var SelectView = Backbone.View.extend({
initialize : function(options) {
// create a collection
this.collection = options.collection;
//console.log('select collection: ', this.collection);
this.render();
},
render : function() {
this.$el.html("");
var self = this;
$.ajax({
url : '../templates/HashTagSelectionTemplate.html',
cache : true,
success : function(data) {
templateLoader(data, self);
}
});
},
events:{
"change #selectHashTag" : "selectShowHide"
},
selectShowHide: function()
{
var selected = $("#selectHashTag").find("option:selected").val();
console.log("selected option: ", selected);
var filteredCollection = new Tweets(this.collection
.selectShowHide(selected));
var filteredResultsView = new ResultsView({
el : $('#display'),
collection : filteredCollection
});
/*var filteredDateView = new DateView({
el : $('#date'),
collection : filteredCollection
});*/
}
});
Define the results View:
var ResultsView = Backbone.View.extend({
initialize : function(options) {
// console.log(options);
// create a collection
this.collection = options.collection;
this.render();
},
render : function() {
this.$el.html("");
var self = this;
$.ajax({
url : '../templates/TweetsTemplate.html',
cache : false,
success : function(data) {
templateLoader(data, self);
}
});
}
});
Function to handle template loading:
function templateLoader(data, self) {
var source = data;
var template = Handlebars.compile(source);
var html = template(self.collection);
self.$el.html(html);
}
Function to attach the datepicker to the supplied element:
function datePicker(self, elementId) {
self.$el.find(elementId).datetimepicker({
dateFormat : "DD, dd MM yy",
ampm : true
});
}
Initialize the master view:
var app = new MasterView({
el : $('#fieldsetForm')
});
Am I on the right track? Should I be using another way? Am I in danger of memory leaks?