source: main/trunk/greenstone3/web/interfaces/default/js/documentedit_scripts_util.js@ 32060

Last change on this file since 32060 was 32060, checked in by ak19, 6 years ago
  1. On leaving the page when there are unsaved changes, there's now a popup warning about this. 2. After a rebuild, the page is automatically reloaded to display the changes.
  • Property svn:executable set to *
File size: 34.4 KB
Line 
1/** Javascript file containing useful functions used by both documentedit_scripts.js and documentmaker_scripts.js */
2
3
4//Some "constants" to match the server constants
5var SUCCESS = 1;
6var ACCEPTED = 2;
7var ERROR = 3;
8var CONTINUING = 10;
9var COMPLETED = 11;
10var HALTED = 12;
11
12var _transactions = new Array();
13var _collectionsToBuild = new Array();
14var _allContents = new Array();
15var _deletedSections = new Array();
16var _deletedMetadata = new Array();
17var _undoOperations = new Array();
18var _baseURL;
19var _statusBar;
20var _metadataSetList = new Array();
21
22
23// If the user is attempting to leave the page, check if there are unsaved changes
24// and if so, display an "Are you sure you want to leave" message.
25// https://stackoverflow.com/questions/7080269/javascript-before-leaving-the-page
26// Newer versions of Firefox/Chrome don't display custom message (security feature):
27// https://stackoverflow.com/questions/22776544/why-is-jquery-onbeforeunload-not-working-in-chrome-and-firefox
28// and http://jsfiddle.net/XZAWS/
29// jquery bind() is deprecated: https://stackoverflow.com/questions/33654716/is-jquery-bind-deprecated
30$(window).on("beforeunload", function(event) {
31 if(gs.cgiParams.docEdit == "1") { // like document.xsl, which checks the same var upon onload
32 // shouldn't check for whether changes are saved unless on Doc Editing page (DocEdit=1)
33 // else the following pop up always ends up appearing when attempting
34 // to leave a doc view page in Doc Editing Mode (when not yet actually Doc Editing)
35 var changes = changesToUpdate();
36
37 if(changes.length > 0) {
38 return "The collection hasn't yet been saved after editing. Are you sure you want to leave?";
39 }
40
41 }
42
43});
44
45
46function encodeDelimiters(meta_value) {
47
48 var new_value = meta_value.replace(/;/g, "%253B");
49 return new_value.replace(/&/g, "%2526");
50}
51
52function getElementsByClassName(cl, parent)
53{
54 var elemArray = [];
55 var classRegEx = new RegExp("\\b" + cl + "\\b");
56 var elems;
57 if(parent)
58 {
59 elems = parent.getElementsByTagName("*");
60 }
61 else
62 {
63 elems = document.getElementsByTagName("*");
64 }
65
66 for (var i = 0; i < elems.length; i++)
67 {
68 var classeName = elems[i].className;
69 if (classRegEx.test(classeName)) elemArray.push(elems[i]);
70 }
71
72 return elemArray;
73};
74
75function getNextSiblingOfType(elem, type)
76{
77 if(elem == null)
78 {
79 return null;
80 }
81
82 var current = elem.nextSibling;
83 while(current != null)
84 {
85 if(current.nodeName.toLowerCase() == type)
86 {
87 return current;
88 }
89
90 current = current.nextSibling;
91 }
92 return null;
93}
94
95function getPrevSiblingOfType(elem, type)
96{
97 if(elem == null)
98 {
99 return null;
100 }
101
102 var current = elem.previousSibling;
103 while(current != null)
104 {
105 if(current.nodeName.toLowerCase() == type)
106 {
107 return current;
108 }
109
110 current = current.previousSibling;
111 }
112 return null;
113}
114
115function saveTransaction(transaction)
116{
117 console.log(transaction);
118 _transactions.push(transaction);
119}
120
121function undo()
122{
123 if(_undoOperations.length == 0)
124 {
125 return;
126 }
127
128 var undoOp = _undoOperations.pop();
129
130 //Create/Duplicate undo
131 if(undoOp.op == "del")
132 {
133 if(undoOp.srcElem.childList)
134 {
135 removeFromParent(undoOp.srcElem.childList);
136 }
137 if(undoOp.srcElem.parentItem)
138 {
139 undoOp.srcElem.parentItem.menu.newSectionLink.style.display = "inline";
140 undoOp.srcElem.parentItem.childList = null;
141 }
142 removeFromParent(undoOp.srcElem);
143 }
144
145 if(undoOp.op == "delMeta")
146 {
147 if(undoOp.srcElem.childList)
148 {
149 removeFromParent(undoOp.srcElem.childList);
150 }
151 if(undoOp.srcElem.parentItem)
152 {
153 undoOp.srcElem.parentItem.menu.newSectionLink.style.display = "inline";
154 undoOp.srcElem.parentItem.childList = null;
155 }
156 de.doc.unregisterEditSection(undoOp.srcElem);
157 removeFromParent(undoOp.srcElem);
158 }
159
160 //Move undo (mva is move after, mvb is move before, mvi is move into)
161 else if(undoOp.op == "mva" || undoOp.op == "mvb" || undoOp.op == "mvi")
162 {
163 if(undoOp.op == "mvb")
164 {
165 undoOp.refElem.parentNode.insertBefore(undoOp.srcElem, undoOp.refElem);
166 }
167 else if(undoOp.op == "mva")
168 {
169 insertAfter(undoOp.srcElem, undoOp.refElem);
170 }
171 else
172 {
173 undoOp.refElem.removeChild(undoOp.refElem.firstChild);
174 undoOp.refElem.appendChild(undoOp.srcElem);
175 }
176
177 if(undoOp.srcElem.textDiv)
178 {
179 insertAfter(undoOp.srcElem.textDiv, undoOp.srcElem);
180 }
181 if(undoOp.srcElem.childList)
182 {
183 insertAfter(undoOp.srcElem.childList, undoOp.srcElem.textDiv);
184 }
185
186 if(undoOp.srcElem.onmouseout)
187 {
188 //Uncolour the section if it coloured
189 undoOp.srcElem.onmouseout();
190 }
191 updateFromTop();
192 }
193 else if(undoOp.op == "display")
194 {
195 undoOp.srcElem.style.display = undoOp.subOp;
196 }
197
198 if(undoOp.removeDeletedMetadata)
199 {
200 _deletedMetadata.pop();
201 }
202
203 if(undoOp.removeTransaction)
204 {
205 _transactions.pop();
206 }
207}
208
209function enableSaveButtons(enabled) {
210 if (enabled) {
211 $("#saveButton, #quickSaveButton").html(gs.text.de.save_changes);
212 $("#saveButton, #quickSaveButton").removeAttr("disabled");
213
214 } else {
215 $("#saveButton, #quickSaveButton").html(gs.text.de.saving + "...");
216 $("#saveButton, #quickSaveButton").attr("disabled", "disabled");
217
218 }
219}
220function addCollectionToBuild(collection)
221{
222 for(var i = 0; i < _collectionsToBuild.length; i++)
223 {
224 if(collection == _collectionsToBuild[i])
225 {
226 return;
227 }
228 }
229 _collectionsToBuild.push(collection);
230}
231
232function save() {
233 saveAndRebuild(false);
234}
235
236function rebuildCurrentCollection() {
237
238 console.log(gs.text.de.rebuilding_collection);
239 enableSaveButtons(false);
240 var collection = gs.cgiParams.c;
241
242 var collectionsArray = new Array();
243 collectionsArray.push(collection);
244 buildCollections(collectionsArray, null, reloadUponRebuild); // passing in callback to reload the page after build, as requested by Kathy
245}
246
247
248function reloadUponRebuild() {
249 // finished rebuilding - reload the page after rebuild, but first
250 // clear transactions array of saved changes, now that we're done processing these changes during rebuild,
251 // since we don't want the "are you sure to leave page" popup which appears on _transactions array being non-empty
252 _transactions = null;
253 location.reload(true); // force reload, not from cache, https://www.w3schools.com/jsref/met_loc_reload.asp
254}
255
256
257function saveAndRebuild(rebuild)
258{
259//This works in most cases but will not work when taking a doc from one collection to another, will need to be fixed at some point
260 var collection;
261 if(gs.cgiParams.c && gs.cgiParams.c != "") {
262
263 collection = gs.cgiParams.c;
264 }
265 else {
266 collection = gs.cgiParams.p_c;
267 }
268
269 var sendBuildRequest = function()
270 {
271 var request = "[";
272 for(var i = 0; i < _transactions.length; i++)
273 {
274 request += _transactions[i];
275 if(i != _transactions.length - 1)
276 {
277 request += ",";
278 }
279 }
280 request += "]";
281
282 var statusID;
283 var ajax = new gs.functions.ajaxRequest();
284 ajax.open("POST", gs.xsltParams.library_name, true);
285 ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
286 ajax.onreadystatechange = function()
287 {
288 if(ajax.readyState == 4 && ajax.status == 200)
289 {
290 var text = ajax.responseText;
291 var xml = validateXML(text);
292
293 var errorElems;
294 if(!xml || checkForErrors(xml))
295 {
296 alert(gs.text.dse.error_saving);
297
298 enableSaveButtons(true);
299
300 if(_statusBar)
301 {
302 _statusBar.removeStatus(statusID);
303 }
304 return;
305 }
306
307 if(_statusBar)
308 {
309 _statusBar.removeStatus(statusID);
310 }
311 if (rebuild) {
312 buildCollections(_collectionsToBuild, null, reloadUponRebuild);
313 } else {
314 // reset the save button here
315 enableSaveButtons(true);
316 // saving to archives is now done, clear the transactions
317 // that were keeping track of the full text changes that have now
318 // been performed to archives (no member var keeps track of meta changes, only a local var)
319 _transactions = new Array();
320 }
321 }
322 }
323
324 if(_collectionsToBuild.length > 0)
325 {
326 enableSaveButtons(false);
327
328 if(_statusBar)
329 {
330 statusID = _statusBar.addStatus(gs.text.dse.modifying_archives + "...");
331 }
332 ajax.send("a=g&rt=r&s=DocumentExecuteTransaction&s1.transactions=" + request);
333 }
334 } // end sendBuildRequest definition
335
336 var metadataChanges = new Array();
337 if (_deletedMetadata.length > 0) {
338 addCollectionToBuild(collection);
339
340 for(var i = 0; i < _deletedMetadata.length; i++) {
341
342 var currentRow = _deletedMetadata[i];
343
344 //Get document ID
345 var currentElem = currentRow;
346 while((currentElem = currentElem.parentNode).tagName != "TABLE");
347 var docID = currentElem.getAttribute("id").substring(4);
348
349 //Get metadata name
350 var cells = currentRow.getElementsByTagName("TD");
351 var nameCell = cells[0];
352 var name = nameCell.innerHTML;
353 var valueCell = cells[1];
354 var value = valueCell.getElementsByTagName("TEXTAREA")[0].value;
355 metadataChanges.push({type:'delete', docID:docID, name:name, value:value});
356 removeFromParent(currentRow);
357 }
358 }
359
360 var changes = changesToUpdate();
361 //Clean changes
362 editableInitStates = editableLastStates;
363 for(var i = 0; i < changes.length; i++)
364 {
365 var changedElem = changes[i];
366 //Save metadata
367 if(gs.functions.hasClass(changedElem, "metaTableCellArea"))
368 {
369 //Get document ID
370 var currentElem = changedElem;
371 while((currentElem = currentElem.parentNode).tagName != "TABLE");
372 var docID = currentElem.getAttribute("id").substring(4);
373
374 //Get metadata name
375 var row = changedElem.parentNode.parentNode;
376 var cells = row.getElementsByTagName("TD");
377 var nameCell = cells[0];
378 var name = nameCell.innerHTML;
379 var value = changedElem.value;
380 value = value.replace(/&nbsp;/g, " ");
381
382 var orig = changedElem.originalValue;
383 if (orig) {
384 orig = orig.replace(/&nbsp;/g, " ");
385 }
386 metadataChanges.push({collection:collection, docID:docID, name:name, value:value, orig:orig});
387 changedElem.originalValue = changedElem.value;
388 addCollectionToBuild(collection);
389 }
390 //Save content
391 else if(gs.functions.hasClass(changedElem, "renderedText"))
392 {
393 var section = changedElem.parentDiv.parentItem;
394 saveTransaction('{"operation":"setText", "text":"' + CKEDITOR.instances[changedElem.getAttribute("id")].getData().replace(/%/g, "%25").replace(/"/g, "\\\"").replace(/&/g, "%26") + '", "collection":"' + section.collection + '", "oid":"' + section.nodeID + '"}'); //'
395 addCollectionToBuild(section.collection);
396 }
397 else if(gs.functions.hasClass(changedElem, "sectionText"))
398 {
399 var id = changedElem.getAttribute("id");
400 var sectionID = id.substring(4);
401 saveTransaction('{"operation":"setText", "text":"' + CKEDITOR.instances[changedElem.getAttribute("id")].getData().replace(/%/g, "%25").replace(/"/g, "\\\"").replace(/&/g, "%26") + '", "collection":"' + gs.cgiParams.c + '", "oid":"' + sectionID + '"}'); //'
402 addCollectionToBuild(gs.cgiParams.c);
403 }
404 }
405
406
407 var processChangesLoop = function(index)
408 {
409
410 var change = metadataChanges[index];
411
412 var callbackFunction;
413 if(index + 1 == metadataChanges.length)
414 {
415 callbackFunction = sendBuildRequest;
416 }
417 else
418 {
419 callbackFunction = function(){processChangesLoop(index + 1)};
420 }
421 if (change.type == "delete") {
422 gs.functions.removeArchivesMetadata(collection, gs.xsltParams.site_name, change.docID, change.name, null, encodeDelimiters(change.value), function(){callbackFunction();});
423 } else {
424 if(change.orig)
425 {
426 gs.functions.setArchivesMetadata(change.collection, gs.xsltParams.site_name, change.docID, change.name, null, encodeDelimiters(change.value), encodeDelimiters(change.orig), "override", function(){callbackFunction();});
427 }
428 else
429 {
430 gs.functions.setArchivesMetadata(change.collection, gs.xsltParams.site_name, change.docID, change.name, null, encodeDelimiters(change.value), null, "accumulate", function(){callbackFunction();});
431 }
432 }
433 }
434 if (metadataChanges.length>0) {
435 // this will process each change one by one, and then send the build request
436 processChangesLoop(0);
437 }
438 else if(_collectionsToBuild.length > 0) {
439 // if there are no metadata changes, but some other changes eg text have happened, then we need to send the build request.
440 sendBuildRequest();
441 }
442
443 /* need to clear the changes from the page so that we don't process them again next time */
444 while (_deletedMetadata.length>0) {
445 _deletedMetadata.pop();
446 }
447
448}
449
450
451function buildCollections(collections, documents, callback)
452{
453 if(!collections || collections.length == 0)
454 {
455 console.log(gs.text.dse.empty_collection_list);
456 enableSaveButtons(true);
457 return;
458 }
459
460 var docs = "";
461 var buildOperation = "";
462 if(documents)
463 {
464 buildOperation = "ImportCollection";
465 docs += "&s1.documents=";
466 for(var i = 0; i < documents.length; i++)
467 {
468 docs += documents[i];
469 if(i < documents.length - 1)
470 {
471 docs += ",";
472 }
473 }
474 }
475 else
476 {
477 buildOperation = "BuildAndActivateCollection";
478 }
479
480 var counter = 0;
481 var statusID = 0;
482 var buildFunction = function()
483 {
484 var ajax = new gs.functions.ajaxRequest();
485 ajax.open("GET", gs.xsltParams.library_name + "?a=g&rt=r&ro=1&s=" + buildOperation + "&s1.incremental=true&s1.collection=" + collections[counter] + docs);
486 ajax.onreadystatechange = function()
487 {
488 if(ajax.readyState == 4 && ajax.status == 200)
489 {
490 var text = ajax.responseText;
491 var xml = validateXML(text);
492
493 if(!xml || checkForErrors(xml))
494 {
495 alert(gs.text.dse.could_not_build_p1 + " " + collections[counter] + gs.text.dse.could_not_build_p2);
496
497 if(_statusBar)
498 {
499 _statusBar.removeStatus(statusID);
500 }
501 enableSaveButtons(true);
502
503 return;
504 }
505
506 var status = xml.getElementsByTagName("status")[0];
507 var pid = status.getAttribute("pid");
508
509 startCheckLoop(pid, buildOperation, statusID, function()
510 {
511 /*
512 var localAjax = new gs.functions.ajaxRequest();
513 localAjax.open("GET", gs.xsltParams.library_name + "?a=g&rt=r&ro=1&s=ActivateCollection&s1.collection=" + collections[counter], true);
514 localAjax.onreadystatechange = function()
515 {
516 if(localAjax.readyState == 4 && localAjax.status == 200)
517 {
518 var localText = localAjax.responseText;
519 var localXML = validateXML(localText);
520
521 if(!xml || checkForErrors(xml))
522 {
523 alert(gs.text.dse.could_not_activate_p1 + " " + collections[counter] + gs.text.dse.could_not_activate_p2);
524
525 if(_statusBar)
526 {
527 _statusBar.removeStatus(statusID);
528 }
529 enableSaveButtons(true);
530
531 return;
532 }
533
534 var localStatus = localXML.getElementsByTagName("status")[0];
535 if(localStatus)
536 {
537 var localPID = localStatus.getAttribute("pid");
538 startCheckLoop(localPID, "ActivateCollection", statusID, function()
539 {
540 */
541 if(counter == collections.length - 1)
542 {
543 removeCollectionsFromBuildList(collections);
544 if(callback)
545 {
546 callback();
547 }
548 }
549 else
550 {
551 counter++;
552 buildFunction();
553 }
554
555 _transactions = new Array();
556
557 if(_statusBar)
558 {
559 _statusBar.removeStatus(statusID);
560 }
561 enableSaveButtons(true);
562 /*
563 });
564 }
565 }
566 }
567 if(_statusBar)
568 {
569 _statusBar.changeStatus(statusID, gs.text.dse.activating + " " + collections[counter] + "...");
570 }
571 localAjax.send();
572 */
573 });
574 }
575 }
576 if(_statusBar)
577 {
578 statusID = _statusBar.addStatus(gs.text.dse.building + " " + collections[counter] + "...");
579 }
580 ajax.send();
581 }
582 buildFunction();
583}
584
585function startCheckLoop(pid, serverFunction, statusID, callbackFunction)
586{
587 var ajaxFunction = function()
588 {
589 var ajax = new gs.functions.ajaxRequest();
590 ajax.open("GET", gs.xsltParams.library_name + "?a=g&rt=s&ro=1&s=" + serverFunction + "&s1.pid=" + pid, true);
591 ajax.onreadystatechange = function()
592 {
593 if(ajax.readyState == 4 && ajax.status == 200)
594 {
595 var text = ajax.responseText;
596 var xml = validateXML(text);
597
598 if(!xml || checkForErrors(xml))
599 {
600 alert(gs.text.dse.could_not_check_status_p1 + " " + serverFunction + gs.text.dse.could_not_check_status_p2a);
601
602 if(_statusBar)
603 {
604 _statusBar.removeStatus(statusID);
605 }
606 enableSaveButtons(true);
607
608 return;
609 }
610
611 var status = xml.getElementsByTagName("status")[0];
612 var code = status.getAttribute("code");
613
614 if (code == COMPLETED || code == SUCCESS)
615 {
616 callbackFunction();
617 }
618 else if (code == HALTED || code == ERROR)
619 {
620 alert(gs.text.dse.could_not_check_status_p1 + " " + serverFunction + gs.text.dse.could_not_check_status_p2b);
621
622 if(_statusBar)
623 {
624 _statusBar.removeStatus(statusID);
625 }
626 enableSaveButtons(true);
627 }
628 else
629 {
630 setTimeout(ajaxFunction, 1000);
631 }
632 }
633 }
634 ajax.send();
635 }
636 ajaxFunction();
637}
638
639function removeCollectionsFromBuildList(collections)
640{
641 var tempArray = new Array();
642 for(var i = 0; i < _collectionsToBuild.length; i++)
643 {
644 var found = false;
645 for(var j = 0; j < collections.length; j++)
646 {
647 if(collections[j] == _collectionsToBuild[i])
648 {
649 found = true;
650 break;
651 }
652 }
653
654 if(!found)
655 {
656 tempArray.push(_collectionsToBuild[i]);
657 }
658 }
659 _collectionsToBuild = tempArray;
660}
661
662function checkForErrors(xml)
663{
664 var errorElems = xml.getElementsByTagName("error");
665
666 if(errorElems && errorElems.length > 0)
667 {
668 var errorString = gs.text.dse.error_saving_changes + ": ";
669 for(var i = 0; i < errorElems.length; i++)
670 {
671 errorString += " " + errorElems.item(i).firstChild.nodeValue;
672 }
673 alert(errorString);
674 return true;
675 }
676 return false; //No errors
677}
678
679function validateXML(txt)
680{
681 // code for IE
682 if (window.ActiveXObject)
683 {
684 var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
685 xmlDoc.async = "false";
686 xmlDoc.loadXML(document.all(txt).value);
687
688 if(xmlDoc.parseError.errorCode!=0)
689 {
690 txt = dse.error_code + ": " + xmlDoc.parseError.errorCode + "\n";
691 txt = txt + dse.error_reason + ": " + xmlDoc.parseError.reason;
692 txt = txt + dse.error_line + ": " + xmlDoc.parseError.line;
693 console.log(txt);
694 return null;
695 }
696
697 return xmlDoc;
698 }
699 // code for Mozilla, Firefox, Opera, etc.
700 else if (document.implementation.createDocument)
701 {
702 var parser = new DOMParser();
703 var xmlDoc = parser.parseFromString(txt,"text/xml");
704
705 if (xmlDoc.getElementsByTagName("parsererror").length > 0)
706 {
707 console.log(gs.text.dse.xml_error);
708 return null;
709 }
710
711 return xmlDoc;
712 }
713 else
714 {
715 console.log(gs.text.dse.browse_cannot_validate_xml);
716 }
717 return null;
718}
719
720function onVisibleMetadataSetChange()
721{
722 var metadataList = document.getElementById("metadataSetList");
723 var index = metadataList.selectedIndex;
724 var options = metadataList.getElementsByTagName("OPTION");
725 var selectedOption = options[index];
726
727 var selectedSet = selectedOption.value;
728 changeVisibleMetadata(selectedSet);
729}
730
731function changeVisibleMetadata(metadataSetName)
732{
733 var metaSetList = metadataSetName.split(",");
734 var tables = document.getElementsByTagName("TABLE");
735 for(var i = 0; i < tables.length; i++)
736 {
737 var id = tables[i].getAttribute("id");
738 if(id && id.search(/^meta/) != -1)
739 {
740 var rows = tables[i].getElementsByTagName("TR");
741 for(var j = 0; j < rows.length; j++)
742 {
743 if(metadataSetName == "All")
744 {
745 rows[j].style.display = "table-row";
746 }
747 else
748 {
749 var cells = rows[j].getElementsByTagName("TD");
750 var cellName = cells[0].innerHTML;
751
752 if(cellName.indexOf(".") == -1)
753 {
754 rows[j].style.display = "none";
755 }
756 else
757 {
758 var setName = cellName.substring(0, cellName.lastIndexOf("."));
759 if (metaSetList.indexOf(setName)!= -1)
760 {
761 rows[j].style.display = "table-row";
762 }
763 else
764 {
765 rows[j].style.display = "none";
766 }
767 }
768 }
769 }
770 }
771 }
772}
773
774function asyncRegisterEditSection(cell)
775{
776 //This registering can cause a sizeable delay so we'll thread it (effectively) so the browser is not paused
777 cell.originalValue = cell.value;
778 setTimeout(function(){addEditableState(cell, editableInitStates)}, 0);
779}
780
781function addOptionToList(list, optionvalue, optiontext, selected) {
782 var newOption = $("<option>");
783 if (optiontext) {
784 newOption.html(optiontext);
785 newOption.attr("value", optionvalue);
786 } else {
787 newOption.html(optionvalue);
788 }
789 if (selected) {
790 newOption.attr("selected", true);
791 }
792 list.append(newOption);
793}
794
795/* returns either an input or a select element. Data based on
796 availableMetadataElements var. */
797function createMetadataElementSelector() {
798 var metaNameField;
799 if (new_metadata_field_input_type == "fixedlist") {
800 metaNameField = $("<select>", {"class": "ui-state-default"});
801 for(var i=0; i<availableMetadataElements.length; i++) {
802 addOptionToList(metaNameField, availableMetadataElements[i]);
803 }
804 return metaNameField;
805 }
806 metaNameField = $("<input>", {"type": "text","style":"margin: 5px; border: 1px solid #000;"});
807 if (new_metadata_field_input_type == "autocomplete") {
808 metaNameField.autocomplete({
809 minLength: 0,
810 source: availableMetadataElements
811 });
812 metaNameField.attr("title", gs.text.de.enter_meta_dropdwon); //"Enter a metadata name, or use the down arrow to select one, then click 'Add New Metadata'");
813 } else {
814 metaNameField.attr("title", gs.text.de.enter_meta_name); //"Enter a metadata name, then click 'Add New Metadata'");
815 }
816
817 return metaNameField;
818}
819
820
821
822function addFunctionalityToTable(table)
823{
824 table.find("tr").each(function()
825 {
826 var cells = $(this).find("td");
827 var metadataName = $(cells[0]).html();
828
829 if(dynamic_metadata_set_list == true && metadataName.indexOf(".") != -1)
830 {
831 var metadataSetName = metadataName.substring(0, metadataName.lastIndexOf("."));
832
833 var found = false;
834 for(var j = 0; j < _metadataSetList.length; j++)
835 {
836 if(metadataSetName == _metadataSetList[j])
837 {
838 found = true;
839 break;
840 }
841 }
842
843 if(!found)
844 {
845 _metadataSetList.push(metadataSetName);
846 addOptionToList( $("#metadataSetList"), metadataSetName);
847 }
848 }
849
850 asyncRegisterEditSection(cells[1].getElementsByTagName("textarea")[0]);
851 addRemoveLinkToRow(this);
852 });
853
854 // set up autocomplete values
855 var value_cells = $(".metaTableCellArea");
856 for (var k=0; k<autocompleteMetadata.length; k++) {
857 var source_name = autocompleteMetadata[k].replace(/[\.-]/g, "");
858 var source_obj = window[source_name+"_values"];
859 if (source_obj) {
860 value_cells.filter("."+source_name).autocomplete({
861 minLength: 0,
862 source: source_obj
863 });
864 }
865 }
866 var metaNameField = createMetadataElementSelector();
867 table.after(metaNameField);
868 table.metaNameField = metaNameField;
869
870 /* add the buttons */
871 // check enable_add_all_button - only valid for fixedlist and autocomplete
872 if (enable_add_all_metadata_button == true) {
873 if (new_metadata_field_input_type != "fixedlist" && new_metadata_field_input_type != "autocomplete") {
874 enable_add_all_metadata_button = false;
875 }
876 }
877
878 // add single metadata button
879 var addRowButton = $("<button>",{"class": "ui-state-default ui-corner-all", "style": "margin: 5px;"});
880
881 addRowButton.html(gs.text.de.add_new_metadata);
882 addRowButton.click(function()
883 {
884 var name = metaNameField.val();
885 if(!name || name == "")
886 {
887 console.log(gs.text.de.no_meta_name_given);
888 return;
889 }
890 addNewMetadataRow(table, name);
891
892
893 });
894 table.addRowButton = addRowButton;
895 metaNameField.after(addRowButton);
896
897 // add all metadata button
898 if (enable_add_all_metadata_button == true) {
899 var addAllButton = $("<button>",{"class": "ui-state-default ui-corner-all", "style": "margin: 5px;"});
900 addAllButton.html(gs.text.de.add_all_metadata);
901 addAllButton.click(function()
902 {
903 for(var i=0; i<availableMetadataElements.length; i++) {
904
905 addNewMetadataRow(table, availableMetadataElements[i])
906 }
907
908 });
909 table.addAllButton = addAllButton;
910 addRowButton.after(addAllButton);
911
912 }
913
914}
915
916function addNewMetadataRow(table, name) {
917
918 var clean_name = name.replace(/[\.-]/g, "");
919 var newRow = $("<tr>", {"style": "display: table-row;"});
920 var nameCell = $("<td>" + name + "</td>");
921 nameCell.attr("class", "metaTableCellName");
922 var valueCell = $("<td>", {"class": "metaTableCell"});
923 var textValue = $("<textarea>", {"class": "metaTableCellArea "+ clean_name});
924
925 if (jQuery.inArray(name, autocompleteMetadata) != -1) {
926 var source_obje = window[clean_name +"_values"];
927 if (source_obje) {
928 textValue.autocomplete({
929 minLength: 0,
930 source: source_obje
931 });
932 }
933 }
934 valueCell.append(textValue);
935 newRow.append(nameCell);
936 newRow.append(valueCell);
937 addRemoveLinkToRow(newRow.get(0));
938 table.append(newRow);
939
940 var undo = new Array();
941 undo.op = "delMeta";
942 undo.srcElem = newRow;
943 undo.removeTransaction = false;
944 _undoOperations.push(undo);
945 if ( hierarchyStorage && hierarchyStorage[name])
946 {
947 setHierarchyEventsWrappers(name);
948 }
949}
950
951function addRemoveLinkToRow(row)
952{
953 var newCell = $("<td>");
954 var removeLink = $("<a>"+gs.text.de.remove+"</a>", {"href": "javascript:;"});
955 removeLink.click(function()
956 {
957 var undo = new Array();
958 undo.srcElem = row;
959 undo.op = "display";
960 undo.subOp = "table-row";
961 undo.removeDeletedMetadata = true;
962 _undoOperations.push(undo);
963 _deletedMetadata.push(row);
964 //row.css("display", "none");
965 $(row).hide();
966 });
967 newCell.append(removeLink);
968 newCell.attr({"class": "metaTableCellRemove", "style": "font-size:0.6em; padding-left: 3px; padding-right: 3px;"});
969 $(row).append(newCell);
970}
971
972/* This is for 'edit structure' menu bar */
973function createTopMenuBar()
974{
975 //Create the top menu bar
976 var headerTable = document.createElement("TABLE");
977 var tableBody = document.createElement("TBODY");
978 var row = document.createElement("TR");
979 var newDocCell = document.createElement("TD");
980 var newSecCell = document.createElement("TD");
981 var saveCell = document.createElement("TD");
982 var undoCell = document.createElement("TD");
983 var metadataListCell = document.createElement("TD");
984
985 var metadataListLabel = document.createElement("SPAN");
986 metadataListLabel.innerHTML = gs.text.de.visible_metadata;
987 var metadataList = document.createElement("SELECT");
988 metadataList.setAttribute("id", "metadataSetList");
989 metadataList.onchange = onVisibleMetadataSetChange;
990 var allMetadataOption = document.createElement("OPTION");
991 metadataList.appendChild(allMetadataOption);
992 allMetadataOption.innerHTML = gs.text.de.all_metadata;
993 metadataListCell.appendChild(metadataListLabel);
994 metadataListCell.appendChild(metadataList);
995
996 metadataListCell.setAttribute("class", "headerTableTD");
997 newDocCell.setAttribute("class", "headerTableTD");
998 newSecCell.setAttribute("class", "headerTableTD");
999 undoCell.setAttribute("class", "headerTableTD");
1000 saveCell.setAttribute("class", "headerTableTD");
1001
1002 headerTable.appendChild(tableBody);
1003 tableBody.appendChild(row);
1004 row.appendChild(saveCell);
1005 row.appendChild(undoCell);
1006 row.appendChild(newDocCell);
1007 row.appendChild(newSecCell);
1008 row.appendChild(metadataListCell);
1009
1010 //The "Save changes" button
1011 var saveButton = document.createElement("BUTTON");
1012 saveButton.innerHTML = gs.text.de.save_changes;
1013 saveButton.setAttribute("onclick", "saveAndRebuild();");
1014 saveButton.setAttribute("id", "saveButton");
1015 saveCell.appendChild(saveButton);
1016
1017 //The "Undo" button
1018 var undoButton = document.createElement("BUTTON");
1019 undoButton.innerHTML = gs.text.dse.undo;
1020 undoButton.setAttribute("onclick", "undo();");
1021 undoCell.appendChild(undoButton);
1022
1023 //The "Create new document" button
1024 var newDocButton = document.createElement("BUTTON");
1025 newDocButton.innerHTML = gs.text.dse.create_new_document;
1026 newDocButton.setAttribute("onclick", "createNewDocumentArea();");
1027 newDocButton.setAttribute("id", "createNewDocumentButton");
1028 newDocCell.appendChild(newDocButton);
1029
1030 //The "Insert new section" LI
1031 var newSecLI = createDraggableNewSection(newSecCell);
1032
1033 return headerTable;
1034}
1035
1036function getMetadataFromNode(node, name)
1037{
1038 var currentNode = node.firstChild;
1039 while(currentNode != null)
1040 {
1041 if(currentNode.nodeName == "metadataList")
1042 {
1043 currentNode = currentNode.firstChild;
1044 break;
1045 }
1046
1047 currentNode = currentNode.nextSibling;
1048 }
1049
1050 while(currentNode != null)
1051 {
1052 if(currentNode.nodeName == "metadata" && currentNode.getAttribute("name") == name)
1053 {
1054 return currentNode.firstChild.nodeValue;
1055 }
1056
1057 currentNode = currentNode.nextSibling;
1058 }
1059 return "";
1060}
1061
1062function storeMetadata(node, listItem)
1063{
1064 listItem.metadata = new Array();
1065
1066 var currentNode = node.firstChild;
1067 while(currentNode != null)
1068 {
1069 if(currentNode.nodeName == "metadataList")
1070 {
1071 currentNode = currentNode.firstChild;
1072 break;
1073 }
1074
1075 currentNode = currentNode.nextSibling;
1076 }
1077
1078 while(currentNode != null)
1079 {
1080 if(currentNode.nodeName == "metadata")
1081 {
1082 listItem.metadata[currentNode.getAttribute("name")] = currentNode.firstChild.nodeValue;
1083 }
1084
1085 currentNode = currentNode.nextSibling;
1086 }
1087}
1088
1089function getNodeContent(node)
1090{
1091 var currentNode = node.firstChild;
1092 while(currentNode != null)
1093 {
1094 if(currentNode.nodeName == "nodeContent")
1095 {
1096 return currentNode.firstChild;
1097 }
1098
1099 currentNode = currentNode.nextSibling;
1100 }
1101 return null;
1102}
1103
1104function containsDocumentNode(node)
1105{
1106 var currentNode = node.firstChild;
1107 while(currentNode != null)
1108 {
1109 if(currentNode.nodeName == "documentNode")
1110 {
1111 return true;
1112 }
1113
1114 currentNode = currentNode.nextSibling;
1115 }
1116 return false;
1117}
1118
1119function isExpanded(textDiv)
1120{
1121 if(typeof textDiv.style == "undefined" || typeof textDiv.style.display == "undefined" || textDiv.style.display == "block")
1122 {
1123 return true;
1124 }
1125 return false;
1126}
1127
1128function toggleTextDiv(section)
1129{
1130 var textDiv = section.textDiv;
1131 if(textDiv)
1132 {
1133 if(isExpanded(textDiv))
1134 {
1135 textDiv.style.display = "none";
1136 section.menu.editTextLink.innerHTML = gs.text.dse.edit;
1137 }
1138 else
1139 {
1140 textDiv.style.display = "block";
1141 section.menu.editTextLink.innerHTML = gs.text.dse.hide;
1142 }
1143 }
1144}
1145
1146function updateFromTop()
1147{
1148 updateRecursive(document.getElementById("dbDiv"), null, null, 0);
1149}
1150
1151function insertAfter(elem, refElem)
1152{
1153 if(refElem.nextSibling)
1154 {
1155 refElem.parentNode.insertBefore(elem, refElem.nextSibling);
1156 }
1157 else
1158 {
1159 refElem.parentNode.appendChild(elem);
1160 }
1161}
1162
1163function removeFromParent(elem)
1164{
1165 elem.parentNode.removeChild(elem);
1166}
1167
1168function createSectionTitle(text)
1169{
1170 var textSpan = document.createElement("SPAN");
1171 if(text)
1172 {
1173 textSpan.appendChild(document.createTextNode(" " + text + " "));
1174 }
1175 else
1176 {
1177 textSpan.appendChild(document.createTextNode(" [" + gs.text.dse.untitled_section + "] "));
1178 }
1179 return textSpan;
1180}
1181
1182function setMouseOverAndOutFunctions(section)
1183{
1184 //Colour the list item and display the menu on mouse over
1185 section.onmouseover = function(e)
1186 {
1187 if(this.menu){this.menu.style.display = "inline";}
1188 this.style.background = "rgb(255, 200, 0)";
1189 };
1190 //Uncolour the list item and hide the menu on mouse out
1191 section.onmouseout = function(e)
1192 {
1193 if(this.menu){this.menu.style.display = "none";}
1194 this.style.background = "none";
1195 };
1196}
1197
1198function createDraggableNewSection(parent)
1199{
1200 var newSecLI = document.createElement("LI");
1201 var newSpan = document.createElement("SPAN");
1202 newSpan.innerHTML = gs.text.dse.insert_new_section + " ";
1203
1204 newSecLI.sectionTitle = newSpan;
1205 newSecLI.appendChild(newSpan);
1206 newSecLI.setAttribute("class", "dragItem newSection");
1207 newSecLI.newSection = true;
1208 newSecLI.parent = parent;
1209 newSecLI.index = -1;
1210 new YAHOO.example.DDList(newSecLI);
1211 parent.appendChild(newSecLI);
1212}
1213
1214function closeAllOpenContents()
1215{
1216 for(var i = 0; i < _allContents.length; i++)
1217 {
1218 if(isExpanded(_allContents[i].textDiv))
1219 {
1220 toggleTextDiv(_allContents[i]);
1221 }
1222 }
1223 DDM.refreshCache();
1224}
1225
1226//Status Bar class (initialised with new StatusBar(elem);)
1227function StatusBar(mainElem)
1228{
1229 var _statusMap = new Array();
1230 var _statusIDCounter = 0;
1231 var _mainElem = mainElem;
1232 var _activeMessages = 0;
1233
1234 _mainElem.style.display = "none";
1235
1236 this.addStatus = function(newStatus)
1237 {
1238 _mainElem.style.display = "block";
1239 var newStatusDiv = document.createElement("DIV");
1240 var newStatusSpan = document.createElement("SPAN");
1241
1242 var workingImage = document.createElement("IMG");
1243 workingImage.setAttribute("src", gs.imageURLs.loading);
1244 workingImage.setAttribute("height", "16px");
1245 workingImage.setAttribute("width", "16px");
1246 newStatusDiv.appendChild(workingImage);
1247
1248 newStatusDiv.appendChild(newStatusSpan);
1249 newStatusSpan.innerHTML = " " + newStatus;
1250 newStatusDiv.setAttribute("class", "statusMessage");
1251 newStatusDiv.span = newStatusSpan;
1252
1253 _mainElem.appendChild(newStatusDiv);
1254 _statusMap["status" + _statusIDCounter] = newStatusDiv;
1255 _activeMessages++;
1256 return _statusIDCounter++;
1257 }
1258
1259 this.changeStatus = function(id, newStatus)
1260 {
1261 if(_statusMap["status" + id])
1262 {
1263 _statusMap["status" + id].span.innerHTML = " " + newStatus;
1264 }
1265 }
1266
1267 this.removeStatus = function(id)
1268 {
1269 if(_statusMap["status" + id])
1270 {
1271 removeFromParent(_statusMap["status" + id]);
1272
1273 if(--_activeMessages == 0)
1274 {
1275 _mainElem.style.display = "none";
1276 }
1277 }
1278 }
1279
1280 this.clear = function()
1281 {
1282 for(var p in _statusMap)
1283 {
1284 if(_statusMap.hasOwnProperty(p))
1285 {
1286 if(_statusMap[p] && _statusMap[p].parentNode)
1287 {
1288 removeFromParent(_statusMap[p]);
1289 }
1290
1291 if(--_activeMessages == 0)
1292 {
1293 _mainElem.style.display = "none";
1294 }
1295 }
1296 }
1297 }
1298}
1299
1300/*
1301function toggleEdit(e)
1302{
1303 var mousePos = de.events.getXYInWindowFromEvent(e);
1304 var cDesc = de.cursor.getCursorDescAtXY(mousePos.x, mousePos.y, de.events.getEventTarget(e));
1305 de.cursor.setCursor(cDesc);
1306}
1307*/
Note: See TracBrowser for help on using the repository browser.