source: main/trunk/greenstone3/web/interfaces/default/js/berrybasket/berrycheckout.js@ 33114

Last change on this file since 33114 was 33114, checked in by ak19, 5 years ago

Basic sanity checking for berrybasket email: to and body may not be empty. Basic test for To being an email address. Added HTML5 input checking on these fields but, while they highlighted invalid fields in red outlines, they didn't prevent the send button from sending invalid data with a success message. So needed the Javascript sanity checking too.

File size: 20.5 KB
Line 
1// The default link type in the basket - "document" = greenstone version of the document, "source" = link to source file eg pdf.
2var default_link_type = "document"; // "source" or "document"
3// use the appropriate one of these to override the default for particular collections.
4var source_link_collections = new Array(); // or add list of collections like ["pdfberry", "mgppdemo"];
5var document_link_collections = new Array(); // or add list of collections as above.
6//these are the default metadata items used by berry baskets.
7var default_metas = ["Title", "root_Title", "root_assocfilepath", "root_srclinkFile", "name", "collection", "Date"];
8
9var docList = new Array();
10var urlonly = false;
11var mailinfo = new Array();
12mailinfo['address'] = gs.text.berry.to;
13mailinfo['cc'] = gs.text.berry.cc;
14mailinfo['bcc'] = gs.text.berry.bcc;
15mailinfo['subject'] = gs.text.berry.subject;
16var textwin;
17var mailwin;
18
19var options = ['fullview', 'textview', 'email'];
20
21function toggleSelectAll(selAllCheckbox) {
22 // https://stackoverflow.com/questions/386281/how-to-implement-select-all-check-box-in-html
23 var allBerriesCheckboxList = document.getElementsByName('select-berry-checkbox');
24 for (var i = 0; i < allBerriesCheckboxList.length; i++) {
25 // if the selectAllCheckbox is checked, then all the berries' checkboxes will get checked
26 // And vice-versa.
27 allBerriesCheckboxList[i].checked = selAllCheckbox.checked;
28 }
29}
30
31function deleteSelected() {
32
33 if(docList.length == 0) return; // no berries on page, nothing to delete
34
35 // https://stackoverflow.com/questions/590018/getting-all-selected-checkboxes-in-an-array
36 // https://www.w3schools.com/jsref/met_document_queryselectorall.asp
37 // https://www.w3schools.com/cssref/css_selectors.asp
38 var selectedList = document.querySelectorAll('input[name=select-berry-checkbox]:checked');
39 if(selectedList.length == 0) return; // nothing selected, so nothing to delete
40
41 // if all berries selected for deletion, can optimise
42 if(selectedList.length === docList.length) {
43 deleteAll();
44 return; // done!
45 }
46
47 // otherwise selected list of berries is a proper subset of total berries (berries in docList)
48 var idsToDelete = [];
49
50 // construct the deletion url by concatenating the ids with | which is %7C in URL-encoded form
51 var delurl = delurlPath; // var delurlPath is declared in ygDDPlayer.js.
52
53 for(var i = 0; i < selectedList.length; i++) {
54 selected_id = selectedList[i].id;
55 // Format of checkbox id: "<docid>-checkbox"
56 var end = selected_id.indexOf("-checkbox");
57 var doc_id = selected_id.substring(0, end);
58
59 idsToDelete[i] = doc_id;
60
61 // Now just need to append each doc_id to the deletion URL separated by |,
62 // but this character needs to be URL encoded, else the delete doesn't work.
63 if((i+1) == selectedList.length) { // if it's the last id to process, don't append separator
64 delurl += doc_id;
65 } else { // there's more ids to process, so append separator
66 delurl += doc_id + "%7C"; // url-encoded version of |
67 }
68
69 }
70
71 var delAll = false;
72 doDelete(delAll, delurl, selectedList, idsToDelete);
73}
74
75function deleteAll() {
76
77 if(docList.length == 0) return; // nothing to delete
78
79 var delurl = delurlPath; // var delurlPath is declared in ygDDPlayer.js.
80 // Just need to append each doc id separated by |, but this character needs to be URL encoded,
81 // else the delete doesn't work.
82
83 for(var i = 0; i < docList.length; i++) {
84 var doc = docList[i];
85 var doc_id = doc['collection']+":"+ doc['name'];
86
87 if((i+1) == docList.length) { // if it's the last id to process, don't append separator
88 delurl += doc_id;
89 } else { // there's more ids to process, so append separator (in URL encoded form!)
90 delurl += doc_id + "%7C"; // url-encoded version of |
91 }
92 }
93
94 var delAll = true;
95 doDelete(delAll, delurl, null, null);
96}
97
98
99function doDelete(deleteAll, delurl, selectedList, idsToDelete) { // given list of selected checkboxes
100
101 // The following is a modified version of methods internal to
102 // ygDDPlayer.js's ygDDPlayer.prototype.onDragDrop
103 var delSuccess = function(o) {
104 var result = o.responseXML;
105
106 if(!deleteAll) { // then we're given a selection to delete: Not deleting all berries, just a subset
107 // Remove id of selected doc to be deleted from docList.
108 // Minor optimisation to double for loop, dependent on ordering of selected berries being
109 // in order of checkboxes (i.e. order of docList ids), and order of docList ids having
110 // the same order as the checkboxes
111 var searchForNextSelectedIdFromIndex = idsToDelete.length-1;
112 for (var i = docList.length - 1; i >= 0; i--) {
113 var berry = docList[i];
114 var berry_id = berry['collection'] + ":" + berry['name'];
115
116 for(var j = searchForNextSelectedIdFromIndex; j >= 0; j--) {
117 if(idsToDelete[j] == berry_id) {
118 docList.splice(i, 1); // i indexes into docList, delete element i from docList
119 searchForNextSelectedIdFromIndex = j-1;
120 break;
121 }
122 }
123 }
124
125 // remove the selected documents' HTML display elements
126 var berryDocsList = YAHOO.util.Dom.get('berryDocsList'); // ordered list item containing the berries
127 for(var i = 0; i < selectedList.length; i++) {
128 var li = selectedList[i].parentNode; // list item parent of checkbox
129 // remove the list item from its containing orderedList
130 berryDocsList.removeChild(li);
131 }
132 }
133
134
135 // if all docs are deleted by this stage, then display "berry basket is empty" message
136 if (deleteAll || !berryDocsList.hasChildNodes()) { // 2nd clause no longer needed?, then this just becomes an else against the first if(!deleteAll) test
137
138 // if deleting all docs, just use the easy way to empty the docList array
139 docList.length = 0; // https://www.jstips.co/en/javascript/two-ways-to-empty-an-array/
140
141 // Removing all child nodes (done one at a time) is more optimal
142 // than setting innerHTML to empty string, see
143 // https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript
144 var content = YAHOO.util.Dom.get('berryBasketContent');
145 while (content.hasChildNodes()) {
146 content.removeChild(content.firstChild);
147 }
148 content.appendChild(document.createTextNode('Your berry basket is empty.'));
149
150 var trashbin = YAHOO.util.Dom.get('trashbin');
151 if ( trashbin !=null){
152 trashbin.style.background = 'url("interfaces/default/images/trash-full.png") 0 0 no-repeat';
153 }
154 }
155
156 // Ensure the select-all, delete-all and delete-selected checkboxes are deselected
157 YAHOO.util.Dom.get('select-all-checkbox').checked = false;
158 YAHOO.util.Dom.get('delete-selected-checkbox').checked = false;
159 YAHOO.util.Dom.get('delete-all-checkbox').checked = false;
160 }
161
162 var delFailure = function(o){ alert("Deletion failed" + o);}
163
164 var delcallback = {
165 success:delSuccess,
166 failure:delFailure,
167 argument:null // supposed to be the ygDDPlayer object, but don't have a ref to it here, so trying null
168 }
169
170 // Finally send the actual delete request
171 // request_type defaults to GET, which is what's used for add and del, see ygDDPlayer.js.
172 YAHOO.util.Connect.asyncRequest(request_type, delurl , delcallback);
173}
174
175function navigate(e){
176
177 var target = this;
178
179 if ( target.id.toLowerCase() == '' ) {
180 target = target.parentNode;
181 }
182
183 if (target.id.toLowerCase() == 'fullview'){
184 berryCheckoutHighlight( 'fullview' );
185 showFullView();
186 }
187
188 if (target.id.toLowerCase() == 'textview'){
189 berryCheckoutHighlight( 'textview' );
190 showTextView();
191 }
192
193 if (target.id.toLowerCase() == 'email'){
194 berryCheckoutHighlight( 'email' );
195 showEmail();
196 }
197
198 if (target.id.toLowerCase() == 'sendmail'){
199 sendMail();
200 }
201
202 if (target.id.toLowerCase() == 'urlcheck' && urlonly){
203 var urlcheck = YAHOO.util.Dom.get('urlcheck');
204 urlcheck.src = 'interfaces/default/images/check3.gif';
205 var parea =YAHOO.util.Dom.get('pretextarea');
206 urlonly = false;
207
208 this.value=gs.text.berry.url_only;
209
210 populateUrlsAndMetadata(parea);
211 return;
212 }
213
214 if (target.id.toLowerCase() == 'urlcheck' && !urlonly ){
215 var urlcheck = YAHOO.util.Dom.get('urlcheck');
216 urlcheck.src = 'interfaces/default/images/check4.gif';
217 var parea =YAHOO.util.Dom.get('pretextarea');
218 populateUrls(parea);
219 urlonly = true;
220
221 this.value=gs.text.berry.url_and_metadata;
222
223 return;
224 }
225
226 if (target.id.toLowerCase() == 'extextview' ){
227 if (textwin != null){
228 textwin.close();
229 }
230
231 textwin = window.open("","Berry basket plain text view","status=1,width=450,height=300");
232 textwin.moveTo(0,0);
233 var content = document.createElement('div');
234 buildPreview(content);
235 var body = textwin.document.getElementsByTagName('body')[0];
236 body.appendChild(content);
237 var prearea = textwin.document.getElementsByTagName('textarea')[0];
238 prearea.cols = '55';
239 prearea.rows = '15';
240 }
241
242 if (target.id.toLowerCase() == 'exemail' ){
243 if (mailwin != null){
244 mailwin.close();
245 }
246 mailwin = window.open("","Berry basket mail to a friend","status=1,width=450,height=350");
247 mailwin.moveTo(0,0);
248 var content = document.createElement('div');
249 getEmailContent(content);
250 var body = mailwin.document.getElementsByTagName('body')[0];
251 body.appendChild(content);
252 var prearea = mailwin.document.getElementsByTagName('textarea')[0];
253 prearea.cols = '50';
254 prearea.rows = '11';
255 }
256}
257
258function pageLoad(){
259 for(var j = 0; j < options.length; j++)
260 {
261 var ele = document.getElementById(options[j]);
262 YAHOO.util.Event.addListener(ele, 'click', navigate);
263 }
264
265 showFullView();
266}
267
268function showFullView(){
269
270 var content = YAHOO.util.Dom.get('berryBasketContent');
271 var fullview = YAHOO.util.Dom.get('fullview');
272 berryCheckoutPageClear();
273
274 if (docList.length == 0){
275 content.appendChild(document.createTextNode(gs.text.berry.empty_basket));
276 return;
277 }
278
279 var trashbin = document.createElement('div');
280 trashbin.id ='trashbin';
281
282 var binhandle = document.createElement('div');
283 binhandle.id = 'binhandle';
284 binhandle.appendChild(document.createElement('span'));
285 trashbin.appendChild(binhandle);
286 content.appendChild(trashbin);
287
288 var dd = new ygDDOnTop('trashbin');
289 dd.setHandleElId('binhandle');
290 new YAHOO.util.DDTarget('trashbin','trash');
291
292 var dlist = document.createElement('div');
293 content.appendChild(dlist);
294 var ol = document.createElement('ol');
295 dlist.appendChild(ol);
296
297 ol.setAttribute("id", "berryDocsList");
298
299 for (var i in docList){
300 var doc = docList[i];
301 var li = document.createElement('li');
302 var img = document.createElement('img');
303 var text ="";
304
305 var doc_id = doc['collection']+":"+ doc['name'];
306
307 img.setAttribute("src", "interfaces/default/images/berry.png");
308 img.setAttribute("id", doc_id);
309 img.setAttribute("height", "15px");
310 img.setAttribute("width", "15px");
311 li.appendChild(img);
312
313 generateDocDisplay(li, doc, doc_id)
314 li.className = 'berrydoc';
315 ol.appendChild(li);
316 new ygDDPlayer(img.id,'trash',docList);
317 }
318
319}
320
321function generateDocDisplay(li, doc, doc_id) {
322 var checkbox = document.createElement('input');
323 checkbox.setAttribute("type", "checkbox");
324 checkbox.setAttribute("id", doc_id+"-checkbox");
325 checkbox.setAttribute("name", "select-berry-checkbox");
326 checkbox.setAttribute("value", "select-"+doc_id);
327
328 var a = document.createElement('a');
329 var text="";
330 a.href=generateURL(doc);
331 a.appendChild(document.createTextNode(doc['Title']));
332
333 if (doc['root_Title']){
334 li.appendChild(document.createTextNode(doc['root_Title']+": "));
335 }
336 li.appendChild(checkbox);
337 li.appendChild(a);
338 li.appendChild(document.createTextNode(" ("+doc['collection']+")"));
339 var metadata = "";
340 for (var metaItem in doc) {
341 if ( !default_metas.includes(metaItem)){
342 metadata += " "+metaItem+": "+ doc[metaItem]+" ";
343 }
344 }
345 text +=metadata;
346 li.appendChild(document.createTextNode(text));
347
348}
349
350function showTextView(){
351
352 var content = YAHOO.util.Dom.get('berryBasketContent');
353 var textview = YAHOO.util.Dom.get('textview');
354
355 berryCheckoutPageClear();
356 if (docList.length == 0){
357 content.appendChild(document.createTextNode(gs.text.berry.empty_basket));
358 return;
359 }
360 buildPreview(content);
361
362}
363
364function getEmailContent(content){
365 var item ;
366 var tr;
367 var td;
368 var input;
369
370 table = document.createElement('table');
371 table.setAttribute("class","mailtable");
372
373 for (item in mailinfo){
374 tr = document.createElement('tr');
375 td = document.createElement('td');
376 td.setAttribute("class","mailitem");
377 td.appendChild(document.createTextNode(mailinfo[item]));
378 tr.appendChild(td);
379 td = document.createElement('td');
380 input = document.createElement('input');
381 input.setAttribute("id", item);
382 input.setAttribute("class", "mailinput");
383 if(item === "address") {
384 input.setAttribute("type", "email"); // https://html5-tutorial.net/form-validation/validating-email/
385 input.required = true; // https://stackoverflow.com/questions/18770369/how-to-set-html5-required-attribute-in-javascript
386 } else {
387 input.setAttribute("type", "text");
388 }
389 td.appendChild(input);
390 tr.appendChild(td);
391 table.appendChild(tr);
392 }
393
394 // an empty line
395 tr = document.createElement('tr');
396 td = document.createElement('td');
397 td.appendChild(document.createElement('br'));
398 tr.appendChild(td);
399 table.appendChild(tr);
400
401 content.appendChild(table);
402
403 buildPreview(content);
404
405 //send button
406 input = document.createElement('input');
407 input.setAttribute("id", 'sendmail');
408 input.setAttribute("class", "sendbutton");
409 input.setAttribute("type", "button");
410 input.setAttribute("value", gs.text.berry.send);
411 content.appendChild(input);
412}
413
414function showEmail(){
415 var content = YAHOO.util.Dom.get('berryBasketContent');
416 var email = YAHOO.util.Dom.get('email');
417
418 berryCheckoutPageClear();
419
420 if (docList.length == 0){
421 content.appendChild(document.createTextNode(gs.text.berry.empty_basket));
422 return;
423 }
424
425 var item;
426 var tr;
427 var td;
428 var input;
429
430 table = document.createElement('table');
431 table.setAttribute("class","mailtable");
432
433 for (item in mailinfo){
434 tr = document.createElement('tr');
435 td = document.createElement('td');
436 td.setAttribute("class","mailitem");
437 td.appendChild(document.createTextNode(mailinfo[item]));
438 tr.appendChild(td);
439
440 td = document.createElement('td');
441 input = document.createElement('input');
442 input.setAttribute("id", item);
443 input.setAttribute("class", "mailinput");
444 if(item === "address") {
445 input.setAttribute("type", "email"); // https://html5-tutorial.net/form-validation/validating-email/
446 input.required = true; // https://stackoverflow.com/questions/18770369/how-to-set-html5-required-attribute-in-javascript
447 } else {
448 input.setAttribute("type", "text");
449 }
450 td.appendChild(input);
451 tr.appendChild(td);
452 table.appendChild(tr);
453
454 }
455
456 // an empty line
457 tr = document.createElement('tr');
458 td = document.createElement('td');
459 td.appendChild(document.createElement('br'));
460 tr.appendChild(td);
461 table.appendChild(tr);
462
463 content.appendChild(table);
464
465 buildPreview(content);
466
467 //send button
468 input = document.createElement('input');
469 input.setAttribute("id", 'sendmail');
470 input.setAttribute("class", "sendbutton");
471 input.setAttribute("type", "button");
472 input.setAttribute("value", gs.text.berry.send);
473 content.appendChild(input);
474
475 YAHOO.util.Event.addListener(input, 'click', navigate);
476}
477
478function buildPreview(parent){
479
480 var div = document.createElement('div');
481 var cb = document.createElement('input');
482 cb.setAttribute('class', 'sendbutton');
483 cb.type = 'button';
484 cb.id = 'urlcheck';
485 if (urlonly)
486 {
487 cb.value=gs.text.berry.url_and_metadata;
488 }
489 else
490 {
491 cb.value=gs.text.berry.url_only;
492 }
493
494 YAHOO.util.Event.addListener(cb, 'click', navigate);
495
496 var img = document.createElement('img');
497 img.src = 'interfaces/default/images/check3.gif';
498 img.id = 'urlcheck';
499 div.appendChild(cb);
500 //div.appendChild(img);
501
502 var urls = document.createElement('span');
503 urls.id = 'urls';
504 urls.className = 'berrycheck';
505 //urls.appendChild(document.createTextNode('URL only'));
506 div.appendChild(urls);
507
508 // var urlsmetadata = document.createElement('span');
509 // urlsmetadata.id = 'urlsmetadata'
510 // urlsmetadata.className = 'berryradio';
511 // urlsmetadata.appendChild(document.createTextNode('URLs and Metadata'));
512 // div.appendChild(urlsmetadata);
513
514 parent.appendChild(div);
515
516 var parea = document.createElement('textarea');
517 parea.id = 'pretextarea';
518 parea.required = true; // https://www.w3schools.com/tags/att_textarea_required.asp
519 // and https://stackoverflow.com/questions/18770369/how-to-set-html5-required-attribute-in-javascript
520
521 parent.appendChild(parea);
522
523 if(urlonly)
524 {
525 populateUrls(parea);
526 }
527 else
528 {
529 populateUrlsAndMetadata(parea);
530 }
531}
532
533function getDefaultLinkType(collection) {
534 var link_type;
535 if (document_link_collections.includes(collection)) {
536 link_type = "document";
537 } else if (source_link_collections.includes(collection)) {
538 link_type = "source";
539 }
540 else {
541 link_type = default_link_type;
542 if (link_type != "source" && link_type != "document") {
543 link_type = "document"; //the default default
544 }
545 }
546 return link_type;
547}
548
549function generateURL(doc) {
550
551 var url;
552 var doc_url = document.URL;
553 var root_url = doc_url.substring(0,doc_url.indexOf('?'));
554
555 var link_type = getDefaultLinkType(doc["collection"]);
556 if (link_type == "document") {
557 url = root_url+"/collection/"+doc["collection"]+"/document/"+doc["name"];
558 } else if (link_type == "source") {
559 // remove library
560 root_url = root_url.substring(0, root_url.lastIndexOf('/'));
561 url = root_url+"/sites/"+gs.xsltParams.site_name+"/collect/"+doc['collection']+"/index/assoc/"+doc["root_assocfilepath"]+"/"+doc["root_srclinkFile"];
562 }
563 return url;
564}
565
566
567function populateUrls(parea){
568
569 var urls="";
570 for (var i in docList){
571 var doc = docList[i];
572 urls += generateURL(doc)+"\n\n";
573 }
574
575 parea.value = urls;
576
577}
578
579function populateUrlsAndMetadata(parea){
580
581 var fulltext="";
582 for (var i in docList){
583 var doc = docList[i];
584 var url = generateURL(doc)+"\n";
585
586 var metadata = "";
587 if (doc['Title']) {
588 metadata += gs.text.berry.doc_title+": "+doc['Title']+"\n";
589 }
590 if (doc['root_Title']) {
591 metadata += gs.text.berry.doc_root_title+": "+doc['root_Title']+"\n";
592
593 }
594 if (doc['name']) {
595 metadata += gs.text.berry.doc_name+": "+doc['name']+"\n";
596 }
597 if (doc['collection']) {
598 metadata += gs.text.berry.doc_collection+": "+doc['collection']+"\n";
599 }
600 if (doc['Date']) {
601 metadata += gs.text.berry.doc_date+": "+doc['Date']+"\n";
602 }
603 // allow for inclusion of custom metadata
604 for (var m in doc) {
605 if (!default_metas.includes(m)) {
606 metadata += m +":" + doc[m]+"\n";
607 }
608 }
609 fulltext +=url+metadata+"\n";
610 }
611
612 parea.value = fulltext;
613
614}
615
616function sendMail(){
617 var url = gs.xsltParams.library_name + "?a=pr&rt=r&ro=1&s=SendMail&c=";
618 var request_type = "POST";
619 var postdata = "";
620 var i;
621
622 var content = YAHOO.util.Dom.get('pretextarea').value;
623
624 // To send an email, the To address and message Body must contain data.
625 // HTML5 input checking (required attribute) would make empty fields red outlined,
626 // but did not prevent Send button submitting form. So some basic sanity checking in JS:
627 // Checking non-empty and to address field must further be a URL: checking it contains @
628 var to_address = YAHOO.util.Dom.get('address').value;
629
630 if(to_address.trim() === "") {
631 alert(gs.text.berry.invalid_to_address_empty);
632 return;
633 } else if(to_address.indexOf('@') === -1) {
634 alert(gs.text.berry.invalid_to_address);
635 return;
636 } else if(content.trim() === "") {
637 alert(gs.text.berry.invalid_msg_body_empty);
638 return;
639 }
640
641 //get checked items
642 for (i in mailinfo) {
643 var input = YAHOO.util.Dom.get(i);
644 var value = input.value;
645 postdata +="&s1."+i+"="+value;
646 }
647
648
649 content = content.replace(/&/g,'-------');
650 postdata +="&s1.content="+content;
651
652 var callback = {
653 success: function(o) {
654 var result = o.responseText;
655 alert(gs.text.berry.send_success);
656 } ,
657 failure: function(o) {
658 alert(gs.text.berry.send_fail);
659 }
660 }
661 YAHOO.util.Connect.asyncRequest(request_type , url , callback, postdata);
662}
663
664function berryCheckoutPageClear() {
665 var bbc = document.getElementById('berryBasketContent');
666 if ( bbc == null ) return;
667 bbc.innerHTML = '';
668}
669
670function berryCheckoutHighlight( id ) {
671
672 for ( var i=0; i<options.length; i++ ) {
673 var option = document.getElementById( options[i] );
674 if ( option != null ) {
675 if ( id == options[i] ) {
676 //YAHOO.util.Dom.addClass( option, 'current' );
677 option.className='current';
678 } else {
679 //YAHOO.util.Dom.removeClass( option, 'current' );
680 option.className='';
681 }
682 }
683 }
684
685 if ( option == null ) return;
686 option.style.className = 'current';
687
688}
689
690YAHOO.util.Event.addListener(window,'load', pageLoad);
691
692
Note: See TracBrowser for help on using the repository browser.