1<!DOCTYPE html>
2<html>
3 <head>
4 <title>Users</title>
5 <meta
6 name="viewport"
7 content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;"
8 />
9 <link rel="stylesheet" href="css/styles.css" />
10 <link rel="stylesheet" href="css/ratchet.css" />
11 </head>
12
13 <body>
14 <div id="content"></div>
15 <script src="js/jquery.min.js"></script>
16 <script src="js/underscore-min.js"></script>
17 <script src="js/backbone-min.js"></script>
18
19
20 <script src="js/MockCordova.js"></script>
21 <script src="js/cordova.force.js"></script>
22 <script src="js/Mock.js"></script>
23
24
25
26 <script src="cordova.js"></script>
27
28
29 <script src="js/"></script>
30 <script src="js/force+promise.js"></script>
31 <script src="js/"></script>
32 <script src="js/fastclick.js"></script>
33 <script src="js/stackrouter.js"></script>
34 <script src="js/auth.js"></script>
35
36
37 <script id="search-page" type="text/template">
38 <header class="bar-title">
39 <h1 class="title">Users</h1>
40 </header>
41
42 <div class="bar-standard bar-header-secondary">
43 <input type="search"
44 class="search-key"
45 placeholder="Search"/>
46 </div>
47
48 <div class="content">
49 <ul class="list"></ul>
50 </div>
51 </script>
52
53
54 <script id="user-list-item" type="text/template">
55
56 <a href="#users/<%= Id %>" class="pad-right">
57 <img src="<%= SmallPhotoUrl %>" class="small-img" />
58 <div class="details-short">
59 <b><%= FirstName %> <%= LastName %></b><br/>
60 Title<%= Title %>
61 </div>
62 </a>
63 </script>
64
65
66 <script id="user-page" type="text/template">
67 <header class="bar-title">
68 <a href="#" class="button-prev">Back</a>
69 <h1 class="title">User</h1>
70 </header>
71
72 <footer class="bar-footer">
73 <span id="offlineStatus"></span>
74 </footer>
75
76 <div class="content">
77 <div class="content-padded">
78 <img id="employeePic"
79 src="<%= SmallPhotoUrl %>" class="large-img" />
80 <div class="details">
81 <b><%= FirstName %> <%= LastName %></b><br/>
82 <%= Id %><br/>
83 <% if (Title) { %><%= Title %><br/><% } %>
84 <% if (City) { %><%= City %><br/><% } %>
85 <% if (MobilePhone) { %>
86 <a href="tel:<%= MobilePhone %>">
87 <%= MobilePhone %></a><br/><% } %>
88 <% if (Email) { %>
89 <a href="mailto:<%= Email %>">
90 <%= Email %></a><% } %>
91 </div>
92 </div>
93 </div>
94 </script>
95
96 <script>
97 // ---- The Models ---- //
98 // The User Model
99 app.models.User = Force.SObject.extend({
100 sobjectType: "User",
101 fieldlist: [
102 "Id",
103 "FirstName",
104 "LastName",
105 "SmallPhotoUrl",
106 "Title",
107 "Email",
108 "MobilePhone",
109 "City",
110 ],
111 });
112
113 // The UserCollection Model
114 app.models.UserCollection = Force.SObjectCollection.extend({
115 model: app.models.User,
116 fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl", "Title"],
117
118 getCriteria: function () {
119 return this.key;
120 },
121
122 setCriteria: function (key) {
123 this.key = key;
124 this.config = {
125 type: "soql",
126 query:
127 "SELECT " +
128 this.fieldlist.join(",") +
129 " FROM User" +
130 " WHERE Name like '" +
131 key +
132 "%'" +
133 " ORDER BY Name " +
134 " LIMIT 25 ",
135 };
136 },
137 });
138
139 // -------------------------------------------------- The Views ---------------------------------------------------- //
140
141 app.views.SearchPage = Backbone.View.extend({
142 template: _.template($("#search-page").html()),
143
144 events: {
145 "keyup .search-key": "search",
146 },
147
148 initialize: function () {
149 this.listView = new app.views.UserListView({ model: this.model });
150 },
151
152 render: function (eventName) {
153 $(this.el).html(this.template());
154 $(".search-key", this.el).val(this.model.getCriteria());
155 this.listView.setElement($("ul", this.el)).render();
156 return this;
157 },
158
159 search: function (event) {
160 this.model.setCriteria($(".search-key", this.el).val());
161 this.model.fetch();
162 },
163 });
164
165 app.views.UserListView = Backbone.View.extend({
166 listItemViews: [],
167
168 initialize: function () {
169 this.model.bind("reset", this.render, this);
170 },
171
172 render: function (eventName) {
173 _.each(this.listItemViews, function (itemView) {
174 itemView.close();
175 });
176 this.listItemViews = _.map(this.model.models, function (model) {
177 return new app.views.UserListItemView({ model: model });
178 });
179 $(this.el).append(
180 _.map(this.listItemViews, function (itemView) {
181 return itemView.render().el;
182 }),
183 );
184 return this;
185 },
186 });
187
188 app.views.UserListItemView = Backbone.View.extend({
189 tagName: "li",
190 template: _.template($("#user-list-item").html()),
191
192 render: function (eventName) {
193 $(this.el).html(this.template(this.model.toJSON()));
194 return this;
195 },
196
197 close: function () {
198 this.remove();
199 this.off();
200 },
201 });
202
203 app.views.UserPage = Backbone.View.extend({
204 template: _.template($("#user-page").html()),
205
206 render: function (eventName) {
207 $(this.el).html(this.template(this.model.toJSON()));
208 return this;
209 },
210 });
211
212 // ----------------------------------------------- The Application Router ------------------------------------------ //
213
214 app.Router = Backbone.StackRouter.extend({
215 routes: {
216 "": "list",
217 list: "list",
218 "users/:id": "viewUser",
219 },
220
221 initialize: function () {
222 Backbone.Router.prototype.initialize.call(this);
223
224 // Collection behind search screen
225 app.searchResults = new app.models.UserCollection();
226
227 // We keep a single instance of SearchPage and UserPage
228 app.searchPage = new app.views.SearchPage({ model: app.searchResults });
229 app.userPage = new app.views.UserPage();
230 },
231
232 list: function () {
233 app.searchResults.fetch();
234 // Show page right away
235 // List will redraw when data comes in
236 this.slidePage(app.searchPage);
237 },
238
239 viewUser: function (id) {
240 var that = this;
241 var user = new app.models.User({ Id: id });
242 user.fetch({
243 success: function () {
244 app.userPage.model = user;
245 that.slidePage(app.userPage);
246 },
247 });
248 },
249 });
250 </script>
251 </body>
252</html>