e81bff20d8a59a45daa1248a5abfeededcecdebb
[oweals/finalsclub.git] / public / javascripts / main.js
1 /*
2 This is the core logic for the main page.
3 It implements most page transitions by showing and hiding DIV elements
4 in the page with javascript+jquery
5 */
6
7 /* Convert a JSON string to an object, or null if unparseable */
8 function j2o(json) { try { return JSON.parse(json); } catch(e) { return null; } }
9
10 /* Convert an object to a JSON string (just easier to type than "JSON.stringify" */
11 function o2j(obj) { return JSON.stringify(obj); }
12
13 function showHome(matches, cb) {
14         cb("home");
15 }
16
17 // go to the page that lists the schools
18 function showSchools(matches, cb) {
19         ProtoDiv.reset("PROTO_school");
20         $.get("/schools", { cache: false }, function(response) {
21                 var schools = [];
22                 if(typeof response == 'object') {
23                         schools = response.schools;
24                 }
25                 ProtoDiv.replicate("PROTO_school", schools);
26                 cb("schools");
27         });
28 }
29
30 // go to the page that lists the courses for a specific school
31 function showCourses(matches, cb) {
32         var schoolId = matches[1];
33         ProtoDiv.reset("PROTO_course");
34         $.get("/school/"+schoolId, { cache: false }, function(response) {
35                 var courses = [];
36                 if(typeof response == 'object') {
37                         var school = response.school;
38                         $("#school_name").html(school.name);
39                         courses = school.courses;
40                 }
41                 ProtoDiv.replicate("PROTO_course", courses);
42                 cb("courses");
43         });
44 }
45
46 // go to the page that lists the lectures for a specific course
47 function showLectures(matches, cb) {
48         var courseId = matches[1];
49         ProtoDiv.reset("PROTO_lecture");
50         $.get("/course/"+courseId, { cache: false }, function(response) {
51                 ProtoDiv.reset("PROTO_lectures_head");
52                 ProtoDiv.reset("PROTO_lectures_instructor");
53                 ProtoDiv.reset("PROTO_lecture");
54                 if(typeof response == 'object') {
55                         var course = response.course;
56                         if(course)
57                                 ProtoDiv.replicate("PROTO_lectures_head", [course]);
58                         var instructor = response.instructor;
59                         if(instructor)
60                                 ProtoDiv.replicate("PROTO_lectures_instructor", [instructor]);
61                         var lectures = response.lectures;
62                         if(lectures)
63                                 ProtoDiv.replicate("PROTO_lecture", lectures);
64                 }
65                 cb("lectures");
66         });
67 }
68
69 // go to the page that lists the note taking sessions for a specific lecture
70 function showNotes(matches, cb) {
71         var lectureId = matches[1];
72         ProtoDiv.reset("PROTO_note");
73         $.get("/lecture/"+lectureId, { cache: false }, function(response) {
74                 if(typeof response == 'object') {
75                         var course = response.course;
76                         //if(course)
77                         //      ProtoDiv.replicate("PROTO_lectures_head", [course])
78                         var instructor = response.instructor;
79                         //if(instructor)
80                         //      ProtoDiv.replicate("PROTO_lectures_instructor", [instructor])
81                         var lecture = response.lecture;
82                         //if(lecture)
83                         //      ProtoDiv.replicate("PROTO_lecture", lectures);
84                         var notes = response.notes;
85                         if(notes)
86                                 ProtoDiv.replicate("PROTO_note", notes);
87                 }
88                 cb("notes");
89         });
90 }
91
92 // go to the page that lists the archived subject names
93 function showArchiveSubjects(matches, cb) {
94         ProtoDiv.reset("PROTO_archive_subject");
95         $.get("/archive", { cache: false }, function(response) {
96                 var subjects = response.subjects;
97                 ProtoDiv.replicate("PROTO_archive_subject", subjects);
98         })
99         cb("archive_subjects");
100 }
101
102 function showArchiveCourses(matches, cb) {
103         var subjectId = parseInt(matches[1]);
104         ProtoDiv.reset("PROTO_archive_course");
105         $.get("/archive/subject/"+subjectId, { cache: false }, function(response) {
106                 var courses = response.courses;
107                 ProtoDiv.replicate("PROTO_archive_course", courses);
108         })
109         cb("archive_courses");
110 }
111
112 function showArchiveNotes(matches, cb) {
113         var courseId = parseInt(matches[1]);
114         ProtoDiv.reset("PROTO_archive_note");
115         $.get("/archive/course/"+courseId, { cache: false }, function(response) {
116                 var notes = response.notes;
117                 $.each(notes, function(i, note) {
118                         if(!note.topic)
119                                 note.topic = note.text.substr(0, 15)+" ...";
120                 })
121                 ProtoDiv.replicate("PROTO_archive_note", notes);
122         })
123         cb("archive_notes");
124 }
125
126
127
128 function showArchiveNote(matches, cb) {
129         var noteId = matches[1];
130         ProtoDiv.reset("PROTO_archive_note_display");
131         $.get("/archive/note/"+noteId, { cache: false }, function(response) {
132                 var note = response.note;
133 //note = { text: "Hi <i>Mom!</i>", topic: "21st Century Greetings" }
134 //              note.text = note.text || ""
135                 if(!note.topic)
136                         note.topic = note.text.substr(0, 15)+" ...";
137 //              if(note.err) {
138 //                      note.topic = note.message
139 //                      note.err = note.err.stack
140 //              }
141 //
142                 ProtoDiv.replicate("PROTO_archive_note_display", note);
143         })
144         cb("archive_note_display");
145 }
146
147 // go to the account registration page
148 function showRegister(matches, cb) {
149         // xxx clear fields?
150         // xxx change FORM to use AJAX
151         cb("register");
152 }
153
154 function showLogin(matches, cb) {
155         cb("login");
156 }
157
158 // go to the press articles page
159 function showPress(matches, cb) {
160         cb("press");
161 }
162
163 // go to the "code of conduct" page
164 function showConduct(matches, cb) {
165         cb("conduct");
166 }
167
168 var pageVectors = [
169         { regex: /^\/(index.html)?$/, func: showHome },
170         { regex: /^\/schools/, func: showSchools },
171         { regex: /^\/school\/([a-f0-9]{24})/, func: showCourses },
172         { regex: /^\/course\/([a-f0-9]{24})/, func: showLectures },
173         { regex: /^\/lecture\/([a-f0-9]{24})/, func: showNotes },
174         { regex: /^\/archive\/?$/, func: showArchiveSubjects },
175         { regex: /^\/archive\/subject\/([0-9]+)/, func: showArchiveCourses },
176         { regex: /^\/archive\/course\/([0-9]+)/, func: showArchiveNotes },
177         { regex: /^\/archive\/note\/([a-f0-9]{24})/, func: showArchiveNote },
178         { regex: /^\/login/, func: showLogin },
179         { regex: /^\/register/, func: showRegister },
180         { regex: /^\/press/, func: showPress },
181         { regex: /^\/conduct/, func: showConduct }
182 ];
183
184 /* Do and show the appropriate thing, based on the pages current URL */
185 function showPage(y) {
186         var path = document.location.pathname;
187         $(".page").hide(); //(100);             // hide all pseudo pages
188         for(var i = 0; i < pageVectors.length; i++) {
189                 var vector = pageVectors[i];
190                 var matches = path.match(vector.regex);
191                 if(matches) {
192                         vector.func(matches, function(pageId) {
193                                 $("#pg_"+pageId).fadeIn(100);
194                                 window.scroll(0, y);
195                         })
196                         break;
197                 }
198         }
199         if(i == pageVectors.length) {
200                 $("#pg_notfound").fadeIn(100);
201                 window.scroll(0, 0);
202         }
203         // scroll to top of page (as if we'd done a real page fetch)
204         /*$('html, body').animate({
205                 scrollTop: $("#topofcontent").offset().top
206         }, 100);*/
207 }
208
209 /* Simulates a page load.
210         'path' is something like "/schools", etc.
211         A page fetch doesn't really happen.
212         Based on what path looks like, an appropriate DIV is shown, and action taken
213 */
214 var topQueue = [0];
215 function goPage(path) {
216         if(history.pushState !== undefined) {
217                 topQueue.push(window.pageYOffset);
218                 history.pushState({}, path, path);
219                 showPage(0);
220         }
221         else {
222                 document.location = path;
223         }
224 }
225
226 /* Simulates a "back" browser navigation.  */
227 var popped = false;
228 function goBack(event) {
229         popped = true;
230         showPage( topQueue.pop() );
231 }
232
233 $(document).ready(function() {
234         // This code executes after the page has been fully loaded
235         $(".proto").css("display", "none");             // make all the prototypes invisible
236         //$("body").get(0).onunload = function() { }    // fires when leaving the page proper
237         ProtoDiv.each = function(e) { $(e).show() };
238         window.onpopstate = goBack;
239         /*setTimeout(function() {
240                 if(!popped)
241                         showPage(0)
242         }, 2000);*/
243         // xxx older FF browsers don't fire a page load/reload - deal with it somehow.
244         // showPage( 0 );               // needed for some older browsers, redundant for chrome
245 })
246