-
Notifications
You must be signed in to change notification settings - Fork 6
/
catalog.js
191 lines (162 loc) · 7.1 KB
/
catalog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
define([
"namespace",
// Libs
"jquery",
"jquerym",
"use!backbone",
// Modules
// Plugins
// Templates
"text!templates/catalog.html",
"text!templates/items.html",
"text!templates/item.html",
"text!templates/message.html"
],
function( namespace, $, $m, Backbone, catalogTemplate, itemsTemplate, itemTemplate, messageTemplate ) {
// Create a new catalog module
var Catalog = namespace.module();
// Catalog model
Catalog.FullCatalog = Backbone.Model.extend({});
var localCatalog = localStorage.getItem( "catalog" );
// Category view
Catalog.Views.Categories = Backbone.View.extend({
render: function( done ) {
var timestamp = new Date().getTime(),
catalogTimestamp = localStorage.getItem( "catalogTimestamp" ),
view = this;
//If there is no catalog in localstorage or the cached catalog is older than 1 hour, refresh
if ( localCatalog && timestamp - catalogTimestamp <= 3600000 ) {
Catalog.renderList( catalogTemplate, $.parseJSON( localCatalog ), view, done );
} else {
// Build the cache and then once complete, render the appropriate view
Catalog.buildCache().done( function() {
Catalog.renderList( catalogTemplate, $.parseJSON( localCatalog ), view, done );
});
}
}
});
// Item list view
Catalog.Views.ItemList = Backbone.View.extend({
events: {
"click a.add-button": "addItem"
},
initialize: function( catID ) {
// Store the current category ID on the view instance
this.catID = catID;
},
render: function( done ) {
var timestamp = new Date().getTime(),
catalogTimestamp = localStorage.getItem( "catalogTimestamp" ),
view = this;
if ( localCatalog && timestamp - catalogTimestamp <= 3600000 ) {
Catalog.renderList( itemsTemplate, $.parseJSON( localCatalog )[ view.catID ].items, view, done );
} else {
// Handle direct links to category before catalog is cached
// Build the cache and then once complete, render the appropriate view
Catalog.buildCache().done( function() {
Catalog.renderList( itemsTemplate, $.parseJSON( localCatalog )[ view.catID ].items, view, done );
});
}
},
addItem: function( event ) {
Catalog.addItem( event );
}
});
// Individual item view
Catalog.Views.ItemPage = Backbone.View.extend({
events: {
"click a.add-button": "addItem"
},
initialize: function( catID, itemID ) {
// Store the current category and item ID's on the view instance
this.catID = catID;
this.itemID = itemID;
},
render: function( done ) {
var timestamp = new Date().getTime(),
catalogTimestamp = localStorage.getItem( "catalogTimestamp" ),
view = this;
if ( localCatalog && timestamp - catalogTimestamp <= 3600000 ) {
Catalog.renderList( itemTemplate, $.parseJSON( localCatalog )[ view.catID ].items[ view.itemID ], view, done );
} else {
// Handle direct links to item before catalog is cached
// Build the cache and then once complete, render the appropriate view
Catalog.buildCache().done( function() {
Catalog.renderList( itemTemplate, $.parseJSON( localCatalog )[ view.catID ].items[ view.itemID ], view, done );
});
}
},
addItem: function( event ) {
Catalog.addItem( event );
}
});
Catalog.addItem = function( event ) {
// Don't add to browser history
event.preventDefault();
var user = $.parseJSON( localStorage.getItem( "user" ) ).id,
cart = $.parseJSON( localStorage.getItem( "cart" ) ),
itemID = $( event.target ).closest( ".add-button" ).data( "item-id" );
$m.showPageLoadingMsg();
$.ajax({
url: namespace.serviceURL + "/cart/" + user + "/additem",
type: "POST",
data: '{"id":' + itemID + '}',
success: function() {
cart.cartCount++;
localStorage.setItem( "cart", JSON.stringify( cart ) );
namespace.app.router.navigate( "#buyer/cart", { trigger: true } );
},
error: function( jqXHR, textStatus, errorThrown ) {
var response = $.parseJSON( jqXHR.responseText );
switch ( response.type ) {
case "INVALID_ITEM":
case "STORE_CLOSED":
namespace.showMessageDialog( "#main", "#buyer/catalog", messageTemplate, response.message, 2000, namespace.app.router );
break;
case "INVALID_USER":
default:
namespace.showMessageDialog( "#main", "#logout", messageTemplate, response.message, 2000, namespace.app.router );
break;
}
},
done: function() {
$m.hidePageLoadingMsg();
}
});
}
// Shared view renderer for all catalog views
Catalog.renderList = function( template, items, view, done ) {
view.el.innerHTML = _.template( template, { "items": items } );
// If a done function is passed, pass it the updated element for processing, display, etc.
if ( _.isFunction( done ) ) {
done( view.el );
}
}
// Cache the catalog to prevent unnecessary REST calls and reload if it's more than one hour old
Catalog.buildCache = function() {
// Return the jqXHR which implements the Promise interface. We can use that interface to act
// on the returned data in our render functions using jQuery's deferred.done()
return $.ajax({
url: namespace.serviceURL + "/category",
// Our services expect a different Accept header in order to return the full catalog
headers: {
"Accept": "application/vnd.categorymap+json"
},
dataType: "json",
success: function( data, response ) {
var timestamp = new Date().getTime();
localStorage.setItem( "catalogTimestamp", timestamp );
localCatalog = JSON.stringify( data );
localStorage.setItem( "catalog", localCatalog );
},
error: function( jqXHR, textStatus, errorThrown ) {
// TODO: Add better offline handling in the future
if ( !localCatalog ) {
namespace.showMessageDialog( "#main", "#buyer/role", messageTemplate, $.parseJSON( jqXHR.responseText ).message, 2000, namespace.app.router );
}
}
});
}
// Required, return the module for AMD compliance
return Catalog;
});