Index: /main/trunk/greenstone3/web/interfaces/default/js/berrybasket/berrycheckout.js
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/js/berrybasket/berrycheckout.js	(revision 33105)
+++ /main/trunk/greenstone3/web/interfaces/default/js/berrybasket/berrycheckout.js	(revision 33106)
@@ -19,4 +19,17 @@
 var options = ['fullview', 'textview', 'email'];
 
+function deleteSelected() {
+    
+    if(docList.length == 0) return; // no berries on page, nothing to delete
+
+    // https://stackoverflow.com/questions/386281/how-to-implement-select-all-check-box-in-html
+    //https://stackoverflow.com/questions/590018/getting-all-selected-checkboxes-in-an-array
+    //https://www.w3schools.com/jsref/met_document_queryselectorall.asp
+    //https://www.w3schools.com/cssref/css_selectors.asp
+    var selectedCheckboxList = document.querySelectorAll('input[name=select-berry-checkbox]:checked');
+    if(selectedCheckboxList.length == 0) return; // nothing selected, so nothing to delete
+  
+    doDelete(selectedCheckboxList);
+}
 
 function deleteAll() {
@@ -71,4 +84,104 @@
     YAHOO.util.Connect.asyncRequest(request_type, delurl , delcallback);
     
+}
+
+
+function doDelete(selectedList) { // given list of selected checkboxes
+    
+    var idsToDelete = [];
+
+    // construct the deletion url by concatenating the ids with | which is %7C in URL-encoded form
+    var  delurl = delurlPath; // var delurlPath is declared in ygDDPlayer.js.
+    
+    for(var i = 0; i < selectedList.length; i++) {
+	selected_id = selectedList[i].id;
+	// Format of checkbox id: "<docid>-checkbox"
+	var end = selected_id.indexOf("-checkbox");
+	var doc_id = selected_id.substring(0, end);
+
+	idsToDelete[i] = doc_id;
+
+	// Now just need to append each doc_id to the deletion URL separated by |,
+	// but this character needs to be URL encoded, else the delete doesn't work.
+	if((i+1) == selectedList.length) { // if it's the last id to process, don't append separator
+	    delurl += doc_id;
+	} else { // there's more ids to process, so append separator
+	    delurl += doc_id + "%7C"; // url-encoded version of |
+	}
+	
+    }
+    
+    // The following is a modified version of methods internal to
+    // ygDDPlayer.js's ygDDPlayer.prototype.onDragDrop
+    var delSuccess = function(o) {
+	var result = o.responseXML;
+
+	var deleteAll = false;
+	if(selectedList.length === docList.length) { // deleting all berries, can optimise
+	    deleteAll = true;
+	}
+	else { // Not deleting all berries, just a subset
+	    // Remove id of selected doc to be deleted from docList.	    
+	    // No ordering of berry indexes according to the order they're added,
+	    // So can't optimise comparison further than traversing the docList array in reverse
+	    for (var i = docList.length - 1; i >= 0; i--) {
+		var berry = docList[i];
+		var berry_id = berry['collection'] + ":" + berry['name'];
+		
+		for(var j = 0; j < idsToDelete.length; j++) {
+		    if(idsToDelete[j] == berry_id) {
+			docList.splice(i, 1); // i indexes into docList, delete element i from docList
+			break;
+		    }
+		}
+	    }
+
+	    // remove the selected documents' HTML display elements
+	    var berryDocsList = YAHOO.util.Dom.get('berryDocsList'); // ordered list item containing the berries	
+	    for(var i = 0; i < selectedList.length; i++) {
+		var li = selectedList[i].parentNode; // list item parent of checkbox
+		// remove the list item from its containing orderedList		
+		berryDocsList.removeChild(li);
+	    }
+	}
+
+	// if all docs are deleted, then display "berry basket is empty" message
+	if (deleteAll || !berryDocsList.hasChildNodes()) {	    
+	    if(deleteAll) {
+		// if deleting all docs, just use the easy way to empty the docList array
+		docList.length = 0; // https://www.jstips.co/en/javascript/two-ways-to-empty-an-array/
+	    }
+
+	    // Removing all child nodes (done one at a time) is more optimal
+	    // than setting innerHTML to empty string, see
+	    // https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript
+	    var content =  YAHOO.util.Dom.get('berryBasketContent');
+	    while (content.hasChildNodes()) {
+		content.removeChild(content.firstChild);
+	    }  
+	    content.appendChild(document.createTextNode('Your berry basket is empty.'));
+	
+	    var trashbin =  YAHOO.util.Dom.get('trashbin');
+	    if ( trashbin !=null){
+		trashbin.style.background = 'url("interfaces/default/images/trash-full.png") 0 0 no-repeat';
+	    }
+	}
+
+	// deselect the delete-all and delete-selected checkboxes
+	YAHOO.util.Dom.get('delall-checkbox').checked = false; 
+	YAHOO.util.Dom.get('delselected-checkbox').checked = false; 
+    }
+
+    var delFailure = function(o){ alert("Deletion failed" + o);}
+    
+    var delcallback = {
+	success:delSuccess,
+	failure:delFailure,  
+	argument:null // supposed to be the ygDDPlayer object, but don't have a ref to it here, so trying null
+    }
+
+    // Finally send the actual delete request
+    // request_type defaults to GET, which is what's used for add and del, see ygDDPlayer.js.
+    YAHOO.util.Connect.asyncRequest(request_type, delurl , delcallback);
 }
 
@@ -195,18 +308,21 @@
 	dlist.appendChild(ol);
 
+	ol.setAttribute("id", "berryDocsList");
+    
 	for (var i in docList){
 		var doc = docList[i];
 		var li = document.createElement('li');
-		var a = document.createElement('a');
 		var img = document.createElement('img');
 		var text ="";
-		
+
+		var doc_id = doc['collection']+":"+ doc['name'];	    
+	    
 		img.setAttribute("src", "interfaces/default/images/berry.png");
-		img.setAttribute("id", doc['collection']+":"+ doc['name']);
+		img.setAttribute("id", doc_id);
 		img.setAttribute("height", "15px");
 		img.setAttribute("width", "15px");
 		li.appendChild(img);
 
-	        generateDocDisplay(li, doc)
+		generateDocDisplay(li, doc, doc_id)
 		li.className = 'berrydoc';
 		ol.appendChild(li);
@@ -216,6 +332,11 @@
 }
 
-function generateDocDisplay(li, doc) {
-
+function generateDocDisplay(li, doc, doc_id) {
+    var checkbox = document.createElement('input');
+    checkbox.setAttribute("type", "checkbox");
+    checkbox.setAttribute("id", doc_id+"-checkbox");
+    checkbox.setAttribute("name", "select-berry-checkbox");
+    checkbox.setAttribute("value", "select-"+doc_id);
+    
     var a = document.createElement('a');
     var text="";
@@ -226,4 +347,5 @@
 	li.appendChild(document.createTextNode(doc['root_Title']+": ")); 
     }
+    li.appendChild(checkbox);
     li.appendChild(a);
     li.appendChild(document.createTextNode(" ("+doc['collection']+")"));
Index: /main/trunk/greenstone3/web/interfaces/default/transform/pages/berry.xsl
===================================================================
--- /main/trunk/greenstone3/web/interfaces/default/transform/pages/berry.xsl	(revision 33105)
+++ /main/trunk/greenstone3/web/interfaces/default/transform/pages/berry.xsl	(revision 33106)
@@ -51,4 +51,5 @@
 			<div class="clear"><xsl:text> </xsl:text></div>
 		</table>
+		<input type="checkbox" name="delsel-checkbox" id="delselected-checkbox" value="delete-all" onclick="deleteSelected()">Delete Selected</input>
 		<input type="checkbox" name="delall-checkbox" id="delall-checkbox" value="delete-all" onclick="deleteAll()">Delete All</input>
 		<div id="berryBasketContent"><span><xsl:text> </xsl:text></span></div>
