source: main/trunk/greenstone3/web/interfaces/default/js/user_comments.js@ 31540

Last change on this file since 31540 was 31540, checked in by ak19, 7 years ago

Some commits ahead of further changes: 1. Kathy came up with better name for GS2Construct.java method (to be refactored) that's more descriptive of the multiple tasks it performs. Removed unused paramter. 2. Javascript user_comments.js displays the heading for the comments section only when appropriate, which is when there is a comment history or when the form to add a comment is shown. Otherwise only the Add Comment link will be shown. 3. Changed core.css colours of links and headings in comments section to better match GS3. 4. document.xsl needs to display usercomments section not just for simple docs but also for wrapped docs.

File size: 11.5 KB
Line 
1// http://toddmotto.com/avoiding-anonymous-javascript-functions
2// https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/
3// pass event to addEventListener onmouseover
4// http://stackoverflow.com/questions/256754/how-to-pass-arguments-to-addeventlistener-listener-function
5// http://stackoverflow.com/questions/8714472/cant-pass-event-to-addeventlistener-closure-issue
6
7
8/***************
9* USER COMMENTS
10****************/
11// http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss
12// Call as: alert(timestamp.printTime());
13function formatTime(timestamp) {
14 var int_timestamp = parseInt(timestamp, 10); // don't forget the second param
15 var date = new Date(int_timestamp);
16 return date.toLocaleDateString() + " " + date.toLocaleTimeString();
17}
18
19function loadUserComments() {
20 /*
21
22 if(gs.variables) {
23 var listing = "";
24 for (prop in gs.variables) {
25 listing = listing + prop.toString() + ": " + gs.variables[prop] + "\n";
26 }
27 alert ("gs variables:\n" + listing);
28 } else {
29 alert("LOADING USER COMMENTS - no gs.variables set");
30 }
31 */
32
33 // don't bother loading comments if we're not on a document page (in which case there's no usercommentdiv)
34 var usercommentdiv = document.getElementById("usercomments");
35 if(usercommentdiv == undefined || usercommentdiv == null) {
36 return;
37 }
38
39 // else, if we have a usercommentdiv, we would have a docid. Get toplevel section of the docid
40 var doc_id = gs.variables["d"]; ///"_cgiargdJssafe_"; //escape("cgiargd");
41 var period = doc_id.indexOf(".");
42 if(period != -1) {
43 doc_id = doc_id.substring(0, period);
44 }
45
46 var username_rec = {
47 metaname: "username",
48 metapos: "all"
49 };
50
51 var timestamp_rec = {
52 metaname: "usertimestamp",
53 metapos: "all"
54 };
55
56 var comment_rec = {
57 metaname: "usercomment",
58 metapos: "all"
59 };
60
61 var doc_rec = {
62 docid: doc_id,
63 metatable: [username_rec, timestamp_rec, comment_rec]
64 };
65
66 var docArray = [doc_rec];
67 //alert(JSON.stringify(docArray));
68
69 var json_result_str = gs.functions.getMetadataArray(gs.variables["c"], gs.variables["site"], docArray, "index");
70 // alert(json_result_str);
71 var result = JSON.parse(json_result_str);
72 // result contains only one docrec (result[0]), since we asked for the usercomments of one docid
73 var metatable = result[0].metatable;
74 // alert(JSON.stringify(metatable));
75
76 var i = 0;
77 var looping = true;
78
79
80 // if there's at least one existing comment OR if the form is currently being displayed
81 // (regardless of whether previous comments exist), display a heading for the comments section
82 if(metatable[0].metavals[0] != undefined || document.getElementById("usercommentform") != undefined) {
83 var heading=document.createElement("div");
84 var attr=document.createAttribute("class");
85 attr.nodeValue="usercommentheading";
86 heading.setAttributeNode(attr);
87 var txt=document.createTextNode(gs.variables["textusercommentssection"]); ///"_textusercommentssection_");
88 heading.appendChild(txt);
89 usercommentdiv.appendChild(heading);
90 }
91
92
93 // metatable[0] = list of usernames, metatable[1] = list of timestamps, metatable[2] = list of comments
94 // the 3 lists/arrays should be of even length. Assuming this, loop as long as there's another username
95 while(looping) {
96 var metaval_rec = metatable[0].metavals[i];
97 if(metaval_rec == undefined) {
98 looping = false;
99 }
100 else {
101
102 var username = metaval_rec.metavalue;
103 var timestamp = metatable[1].metavals[i].metavalue;
104 var comment = metatable[2].metavals[i].metavalue;
105
106 //alert("Comment: " + username + " " + timestamp + " " + comment);
107
108 // No need to sort by time, as the meta are already stored sorted
109 // and hence retrieved in the right order by using the i (metapos) counter
110 // If sorting the array of comment records, which would be by timestamp, see
111 // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort
112
113 // for each usercomment, create a child div with the username, timestamp and comment
114 displayInUserCommentList(usercommentdiv, username, timestamp, comment);
115
116 i++;
117 }
118 }
119
120}
121
122
123function displayInUserCommentList(usercommentdiv, username, timestamp, comment) {
124
125 //alert("Comment: " + username + " " + timestamp + " " + comment);
126
127 var divgroup=document.createElement("div");
128 var attr=document.createAttribute("class");
129 attr.nodeValue="usercomment";
130 divgroup.setAttributeNode(attr);
131
132 var divuser=document.createElement("div");
133 var divtime=document.createElement("div");
134 var divcomment=document.createElement("div");
135
136
137 divgroup.appendChild(divuser);
138 var txt=document.createTextNode(username);
139 divuser.appendChild(txt);
140
141 divgroup.appendChild(divtime);
142 txt=document.createTextNode(formatTime(timestamp)); // format timestamp for date/time display
143 divtime.appendChild(txt);
144
145 // any quotes and colons in the fields would have been protected for transmitting as JSON
146 // so decode their entity values
147 comment = comment.replace(/"/gmi, '"');
148 comment = comment.replace(/&58;/gmi, ':');
149
150 divgroup.appendChild(divcomment);
151 txt=document.createTextNode(comment);
152 divcomment.appendChild(txt);
153
154 usercommentdiv.appendChild(divgroup);
155
156}
157
158
159// Unused. Replaced in favour of call to escape() in setMetaArray function that calls urlPostSync
160// http://stackoverflow.com/questions/6020714/escape-html-using-jquery
161function safeHTML(str) {
162 return str.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"',"&quot;").replace("'","&#x27;").replace("/", "&#x2F;"); //"\\""
163}
164
165
166function addUserComment(_username, _comment, _docid, doc) {
167
168 // don't add empty strings for name/comment
169
170 // http://stackoverflow.com/questions/498970/how-do-i-trim-a-string-in-javascript
171 //var trimmed_username=_username.replace(/^\s+|\s+$/g, '');
172 var trimmed_comment = _comment.replace(/^\s+|\s+$/g, '');
173
174 if(!trimmed_comment) { // || !trimmed_username
175 doc.AddUserCommentForm.comment.value = "";
176 //doc.AddUserCommentForm.username.value = "";
177 doc.getElementById("usercommentfeedback").innerHTML = gs.variables["textisempty"]; ///"_textisempty_";
178 return;
179 }
180
181 // Need to the add user comment meta of username, timestamp and comment to the
182 // topmost section of the document. So only get the docId up to any period mark:
183 var period = _docid.indexOf(".");
184 if(period != -1) {
185 _docid = _docid.substring(0, period);
186 }
187
188
189 // Want to store username, timestamp and comment in import/metadata.xml, archives/doc.xml
190 // and index/col.gdb.
191
192 // For getting the current time, see
193 // http://stackoverflow.com/questions/3830244/get-current-date-time-in-seconds
194 var _timestamp = new Date().getTime(); // div by 1000 to get seconds. valueOf() may return string
195
196 //alert("username:" + _username
197 //+ "\\ncomment: " + _comment
198 //+ "\\ncollection: " + collection
199 //+ "\\ndocid: " + _docid
200 //+ "\\ntimestamp: " + _timestamp);
201
202
203 // Entity encode the values before storing (at least <, >, forward slash.
204 // And single and double quote, ampersand)
205 // http://stackoverflow.com/questions/6020714/escape-html-using-jquery
206 // setMetadataArray escapes the entire JSON, is that better than escaping individually here?
207 //_docid = escape(_docid);
208 //_timestamp = escape(_timestamp);
209 //_username = escape(_username); //safeHTML(_username);
210 //_comment = escape(_comment); //safeHTML(_comment);
211
212 // Use this if making individual api calls to set username meta, then timestamp then comment meta
213 // GSAPI already knows the collection
214 //gsapi.setMetadata(_docid, "username", null, _username, "accumulate", "import|archives|index");
215 //gsapi.setMetadata(_docid, "usertimestamp", null, _timestamp, "accumulate", "import|archives|index");
216 //gsapi.setMetadata(_docid, "usercomment", null, _comment, "accumulate", "import|archives|index");
217
218
219 // Use the new JSON metatable format to set username, timestamp and comment meta for docid in one go
220
221 // For creating the JSON object that gets turned into a string, see
222 // http://msdn.microsoft.com/en-us/library/ie/cc836459%28v=vs.94%29.aspx
223 // http://jsfiddle.net/qmacro/W54hy/
224
225 var username_rec = {
226 metaname: "username",
227 metavals: [_username]
228 };
229
230 var timestamp_rec = {
231 metaname: "usertimestamp",
232 metavals: [_timestamp]
233 };
234
235 var comment_rec = {
236 metaname: "usercomment",
237 metavals: [_comment]
238 };
239
240 var doc_rec = {
241 docid: _docid,
242 metatable: [username_rec, timestamp_rec, comment_rec],
243 metamode: "accumulate"
244 };
245
246 var docArray = [doc_rec];
247
248 //alert(JSON.stringify(docArray));
249
250 // GSAPI already knows the collection
251 var result = gs.functions.setMetadataArray(gs.variables["c"], gs.variables["site"], docArray, "accumulate", "import|archives|index");
252
253 // clear the comment field as it has now been submitted, but not the username field
254 // as the user is logged in, so they should be able to commit again under their username.
255 doc.AddUserCommentForm.comment.value = "";
256
257 // check for locked collection error
258 var errorIndex = result.indexOf("ERROR");
259 // check for any error discovered on the server side
260 var responseErrorIndex = result.indexOf("<error");
261
262 if(errorIndex != -1) {
263 var endIndex = result.indexOf("\\n");
264 var error = result.substring(errorIndex,endIndex);
265 errormessage="ERROR: Unable to add comment. " + error;
266 doc.getElementById("usercommentfeedback").innerHTML = errormessage;
267 //alert("Result: " + result);
268 }
269 else if (responseErrorIndex != -1) {
270 var endIndex = result.indexOf("</error>");
271 var startIndex = result.indexOf(">", responseErrorIndex+1);
272 var error = result.substring(startIndex+1,endIndex);
273 errormessage="ERROR: Unable to add comment. " + error;
274 doc.getElementById("usercommentfeedback").innerHTML = errormessage;
275 //alert("Result: " + result);
276 }
277 else { // success!
278 doc.getElementById("usercommentfeedback").innerHTML = gs.variables["textcommentsubmitted"]; ///"_textcommentsubmitted_";
279
280 // update display of existing user comments to show the newly added comment
281 var usercommentdiv = document.getElementById("usercomments");
282 if(usercommentdiv != undefined) {
283 displayInUserCommentList(usercommentdiv, _username, _timestamp, _comment);
284 }
285 }
286}
287
288function commentAreaSetup() {
289 loadUserComments();
290 //$("div#commentarea").html("<textarea required=\"required\" name=\"comment\" rows=\"10\" cols=\"64\" placeholder=\"Add your comment here...\"></textarea>");
291 $("div#commentarea").html('<textarea required="required" name="comment" rows="10" cols="64" placeholder="Add your comment here..."></textarea>');
292
293}
294
295
296// "Handlers added via $(document).ready() don't overwrite each other, but rather execute in turn"
297// as explained at http://stackoverflow.com/questions/15564029/adding-to-window-onload-event
298
299$(document).ready(commentAreaSetup);
300
301/*
302// http://stackoverflow.com/questions/807878/javascript-that-executes-after-page-load
303// ensure we don't replace any other onLoad() functions, but append the loadUserComments()
304// function to the existing onLoad handlers
305
306if(window.onload) {
307 var curronload = window.onload;
308 var newonload = function() {
309 curronload();
310 loadUserComments();
311 };
312 window.onload = newonload;
313} else {
314 window.onload = loadUserComments;
315}
316*/
Note: See TracBrowser for help on using the repository browser.