Index: /main/trunk/greenstone2/macros/document.dm
===================================================================
--- /main/trunk/greenstone2/macros/document.dm	(revision 27256)
+++ /main/trunk/greenstone2/macros/document.dm	(revision 27257)
@@ -105,4 +105,5 @@
 <table width=_pagewidth_ cellpadding=0 cellspacing=0 border=0>
 <tr><td align=left valign=top>
+_usercomment_
 _prevarrow_
 </td><td align=right valign=top>
@@ -118,4 +119,87 @@
 _prevarrow_<br>
 _nextarrow_
+}
+
+#######################################################################
+# section for adding user comments: consists of form and its javascript
+#######################################################################
+
+# For 
+# http://stackoverflow.com/questions/4264091/input-type-submit-instead-of-input-type-button-with-ajax
+# http://stackoverflow.com/questions/8869341/ajax-form-submit-with-submit-button
+
+_usercomment_ {
+
+<form name="AddUserCommentForm">
+<p>_textcommentusername_ <input type="text" name="username"></p>
+<p>
+_textaddusercomment_
+<textarea name="comment" rows="10" cols="70"></textarea>
+<input type=hidden name="d" value="_cgiargd_">
+</p>
+
+<input type="submit" value="_textaddcomment_" onclick="addUserComment(document.AddUserCommentForm.username.value, document.AddUserCommentForm.comment.value, document.AddUserCommentForm.d.value); return false;">
+</form>
+
+<script type="text/javascript">  
+	function addUserComment(_username, _comment, _docid) \{
+
+		// Want to store username, timestamp and comment in import/metadata.xml, archives/doc.xml
+		// and index/col.gdb.
+
+		// For getting the current time, see
+		// http://stackoverflow.com/questions/3830244/get-current-date-time-in-seconds
+		var _timestamp = new Date().getTime(); // div by 1000 to get seconds. valueOf() may return string
+
+		//alert("username:" + _username
+		//+ "\\ncomment: " + _comment
+		//+ "\\ncollection: " + collection 
+		//+ "\\ndocid: " + _docid
+		//+ "\\ntimestamp: " + _timestamp); 
+
+
+		// To make individual api calls to set username meta, then timestamp then comment meta:
+		// GSAPI already knows the collection
+		//gsapi.setMetadata(_docid, "username", null, _username, "accumulate", "import|archives|index");
+ 		//gsapi.setMetadata(_docid, "usertimestamp", null, _timestamp, "accumulate", "import|archives|index");
+		//gsapi.setMetadata(_docid, "usercomment", null, _comment, "accumulate", "import|archives|index");
+
+
+		// Use the new JSON metatable format to set username, timestamp and comment meta for docid in one go
+
+		// For creating the JSON object that gets turned into a string, see
+		// http://msdn.microsoft.com/en-us/library/ie/cc836459%28v=vs.94%29.aspx
+		// http://jsfiddle.net/qmacro/W54hy/
+		
+		var username_rec = \{
+		    metaname: "username",
+		    metavals: [_username]
+		\};
+
+		var timestamp_rec = \{
+		    metaname: "timestamp",
+		    metavals: [_timestamp]
+		\};
+
+		var comment_rec = \{
+		    metaname: "comment",
+		    metavals: [_comment]
+		\};
+
+		var doc_rec = \{
+		    docid: _docid,
+		    metatable: [username_rec, timestamp_rec, comment_rec],
+		    metamode: "accumulate"
+		\};
+
+		var docArray = [doc_rec];
+
+		//alert(JSON.stringify(docArray));
+
+		// GSAPI already knows the collection
+		gsapi.setMetadataArray(docArray, "accumulate","import|archives|index");
+
+	\}
+</script>
 }
 
Index: /main/trunk/greenstone2/macros/english.dm
===================================================================
--- /main/trunk/greenstone2/macros/english.dm	(revision 27256)
+++ /main/trunk/greenstone2/macros/english.dm	(revision 27257)
@@ -336,4 +336,8 @@
 }
 
+_textcommentusername_ {User name:}
+_textaddusercomment_ {Add user comment:}
+_textaddcomment_ {add comment}
+
 _textgoto_ {go to page}
 _textintro_ { <i>(introductory text)</i>}
Index: /main/trunk/greenstone2/web/script/gsajaxapi.js
===================================================================
--- /main/trunk/greenstone2/web/script/gsajaxapi.js	(revision 27256)
+++ /main/trunk/greenstone2/web/script/gsajaxapi.js	(revision 27257)
@@ -139,8 +139,4 @@
     }
     
-
-    
-    
-    
     this.setLiveMetadata = function(id,metaname,metavalue)
     {
@@ -155,5 +151,61 @@
         this.urlGetSync(url);
     }
-    
+
+    // New
+    // The where parameter can be specified as one or more of: import, archives, index, live 
+    // separated by |. If null, it is assumed to be index which is the original default 
+    // behaviour of calling set-metadata). E.g. where=import|archives|index
+    this.setMetadata = function(docid,metaname,metapos,metavalue,metamode,where)
+    {
+        var mdserver = this.metadataserverURL();
+    
+        var params = "a=set-metadata";
+	if(where != null) {
+	    params += "&where=" + where; // if where not specified, meta-server will default to setting index meta
+	    //} else {
+	    //    params += "&where=import|archives|index";
+	}
+        params += "&c="+collect_;
+        params += "&d="+docid;
+        params += "&metaname=" + metaname;
+        if (metapos!=null) {
+            params += "&metapos=" + metapos;
+        }
+        params += "&metavalue=" + metavalue;
+	if (metamode!=null) {
+            params += "&metamode=" + metamode;
+	}
+	
+        this.urlGetSync(mdserver + "?" + params);
+        //this.urlPostSync(mdserver,params);
+    }
+
+    // New
+    // The where parameter can be specified as one or more of: import, archives, index, live 
+    // separated by |. If null, it is assumed to be index which is the original default 
+    // behaviour of calling set-metadata-array). E.g. where=import|archives|index
+    this.setMetadataArray = function(docArray,metamode,where) 
+    {
+	docArrayJSON = JSON.stringify(docArray);
+	
+	var mdserver = this.metadataserverURL();
+	
+	var params = "a=set-metadata-array";
+	if(where != null) {
+	    params += "&where=" + where; // if where not specified, meta-server will default to setting index meta
+	    //} else {
+	    //    params += "&where=import|archives|index";
+	}
+	params += "&c="+collect_;
+	params += "&json="+docArrayJSON;
+	
+	if (metamode!=null) {
+	    params += "&metamode=" + metamode;
+	}
+	
+	this.urlGetSync(mdserver + "?" + params);
+	
+    }
+
     this._setMetadata = function(mode,docid,metaname,metapos,metavalue,metamode)
     {
@@ -168,7 +220,7 @@
         }
         params += "&metavalue=" + metavalue;
-		if (metamode!=null) {
+	if (metamode!=null) {
             params += "&metamode=" + metamode;
-		}
+	}
 	
         this.urlGetSync(mdserver + "?" + params);
@@ -177,21 +229,21 @@
     
 	
-	this._setDocumentArrayMetadata = function(mode,docArray,metamode) 
-	{
-	    docArrayJSON = JSON.stringify(docArray);
-  
-		var mdserver = this.metadataserverURL();
-    
-        var params = "a=set" + mode + "-metadata-array";
-        params += "&c="+collect_;
-		params += "&json="+docArrayJSON;
-	
-		if (metamode!=null) {
-            params += "&metamode=" + metamode;
-		}
-		
-		this.urlGetSync(mdserver + "?" + params);
-   
-	}
+    this._setDocumentArrayMetadata = function(mode,docArray,metamode) 
+    {
+	docArrayJSON = JSON.stringify(docArray);
+	
+	var mdserver = this.metadataserverURL();
+	
+	var params = "a=set" + mode + "-metadata-array";
+	params += "&c="+collect_;
+	params += "&json="+docArrayJSON;
+	
+	if (metamode!=null) {
+	    params += "&metamode=" + metamode;
+	}
+	
+	this.urlGetSync(mdserver + "?" + params);
+	
+    }
 	
 	
