/FarmasWebSite/Content/features/weather/weather.js
https://bitbucket.org/pragmaticlogic/farmas-sandbox · JavaScript · 256 lines · 229 code · 24 blank · 3 comment · 9 complexity · a0ab913b86af3cfe4e15edfee98100d2 MD5 · raw file
- (function () {
- var STORAGE_KEY = 'weather.cities';
- var server = {
- getWeather: function (zip) {
- return $.getJSON('/Weather/GetWeather?zip=' + zip);
- }
- };
- var WeatherApp = Backbone.Model.extend({
- defaults: {
- 'unit': 'F'
- },
- initialize: function () {
- this.cities = new CityCollection();
- if(Modernizr.localstorage && localStorage[STORAGE_KEY]) {
- _.each(localStorage[STORAGE_KEY].split(','), function(z) {
- this.addCity(z);
- }, this);
- }
- else {
- this.addCity(98052);
- this.addCity(10001);
- this.addCity(75201);
- this.addCity(94121);
- }
-
- // bind to collection changes after adding the starting cities
- this.cities.bind('add remove', this.saveCities, this);
- },
- saveCities: function () {
- var data = this.cities.map(function(c) {
- return c.get('zip')
- }).join();
- localStorage[STORAGE_KEY] = data;
- },
- addCity: function (zip) {
- var city = new City({ 'app': this, 'zip': zip });
- this.cities.add(city);
- city.refresh();
- },
- getCities: function () {
- return this.cities;
- },
- refresh: function () {
- this.cities.each(function (c) {
- c.refresh();
- });
- },
- changeUnit: function () {
- var u = this.get('unit');
- if (u === 'F')
- u = 'C';
- else
- u = 'F';
- this.set({ 'unit': u });
- },
- getUnit: function () {
- return this.get('unit');
- }
- });
- var WeatherView = Backbone.View.extend({
- events: {
- 'click #unitCheckbox': 'changeUnit',
- 'click #refreshLink': 'refreshAll',
- 'submit form': 'addCity'
- },
- initialize: function () {
- this.template = _.template($('#weatherTemplate').html());
- this.model.bind('change', this.render, this);
- this.model.getCities().bind('all', this.focus, this);
- },
- focus: function () {
- $(this.el).find('#zipTextbox').focus();
- },
- changeUnit: function () {
- this.model.changeUnit();
- },
- refreshAll: function (evt) {
- evt.preventDefault();
- this.model.refresh();
- },
- addCity: function (evt) {
- evt.preventDefault();
- var $text = $('#zipTextbox');
- var zip = $text.val();
- if (zip) {
- this.model.addCity($text.val());
- $text.val('');
- }
- $text.focus();
- },
- render: function () {
- var self = this;
- //load the main UI
- $(this.el).html(this.template(this.model.toJSON()));
- $('#unitCheckbox').lightSwitch({
- switchImg: '/Content/lib/lightswitch/switch-unit.png',
- switchImgCover: '/Content/lib/lightswitch/switchplate.png',
- });
- // load the cities list
- var citiesView = new CityCollectionView({ collection: this.model.getCities() });
- $('#citiesDiv').html(citiesView.render().el);
- this.focus();
- return this;
- }
- });
- var City = Backbone.Model.extend({
- defaults: {
- 'name': '???',
- 'temperature': '???',
- 'state': '???',
- 'url': '???'
- },
- initialize: function () {
- this.app = this.get('app');
- this.state = 'init';
- this.farenheit = '???';
- this.celsius = '???';
- },
- invoke: function (event) {
- this.state = event;
- this.trigger(event);
- },
- getState: function () {
- return this.state;
- },
- getViewData: function () {
- var json = this.toJSON();
- json.unit = this.app.getUnit();
- json.temperature = this.app.getUnit() === 'F' ? this.farenheit : this.celsius;
- return json;
- },
- refresh: function () {
- this.invoke('loading');
- var self = this;
- var promise = server.getWeather(this.get('zip'));
- promise.done(function (data) {
- if (data.success) {
- self.farenheit = data.temperature;
- self.celsius = Math.round((data.temperature - 32) / 1.8);
- self.set({
- 'name': data.city,
- 'state': data.state,
- 'url': data.url
- });
- self.invoke('update');
- }
- else {
- self.invoke('error');
- }
- });
- promise.fail(function (data) {
- self.invoke('error');
- });
- }
- });
- var CityView = Backbone.View.extend({
- className: 'city',
- events: {
- 'click .city-refresh': 'refresh',
- 'click .city-remove': 'remove'
- },
- initialize: function () {
- this.template = _.template($('#cityTemplate').html());
- this.loadingTemplate = _.template($('#cityLoadingTemplate').html());
- this.errorTemplate = _.template($('#cityErrorTemplate').html());
- this.model.bind('update loading error', this.render, this);
- },
- render: function () {
- var viewData = this.model.getViewData();
- switch (this.model.getState()) {
- case 'loading':
- this.$el.removeClass('city-error');
- this.$el.html(this.loadingTemplate(viewData));
- break;
- case 'error':
- this.$el.html(this.errorTemplate(viewData));
- this.$el.addClass('city-error');
- break;
- default:
- this.$el.removeClass('city-error');
- this.$el.html(this.template(viewData));
- break;
- }
- this.$el.data('zip', viewData.zip);
-
- return this;
- },
- remove: function () {
- this.model.destroy();
- },
- refresh: function () {
- this.model.refresh();
- }
- });
- var CityCollection = Backbone.Collection.extend({
- model: City
- });
- var CityCollectionView = Backbone.View.extend({
- tagName: 'ul',
- events: {
- 'sortupdate': 'updateOrder'
- },
- initialize: function () {
- this.collection.bind('add destroy', this.render, this);
- },
- updateOrder: function () {
- var self = this;
- var sortedModels = [];
- this.$el.find('.city').each(function(index, city) {
- var cityModel = self.collection.where({ 'zip': $(city).data('zip') })[0];
- sortedModels.push(cityModel);
- });
- self.collection.reset(sortedModels);
- },
- render: function () {
- var self = this;
- self.$el.empty();
- this.collection.forEach(function (c) {
- var cityView = new CityView({ model: c });
- var $li = $('<li>').html(cityView.render().el);
- self.$el.append($li);
- });
- if(this.collection.length > 0) {
- self.$el.sortable();
- }
-
- return this;
- }
- });
- $(function () {
- var appView = new WeatherView({ model: new WeatherApp() });
- appView.setElement($('#appDiv'));
- appView.render();
- });
- })();