// Heads up! August 2003 - Geir Bækholt // This file now requires the javascript variable portal_url to be set // in the plone_javascript_variables.js file. Any other variables from Plone // that you want to pass into these scripts should be placed there. /* (this is for http compression) */ function registerPloneFunction(func){ // registers a function to fire onload. // Turned out we kept doing this all the time // Use this for initilaizing any javascript that should fire once the page has been loaded. // if (window.addEventListener) window.addEventListener("load",func,false); else if (window.attachEvent) window.attachEvent("onload",func); } function getContentArea(){ // to end all doubt on where the content sits. It also felt a bit silly doing this over and over in every // function, even if it is a tiny operation. Just guarding against someone changing the names again, in the name // of semantics or something.... ;) node = document.getElementById('region-content') if (! node){ node = document.getElementById('content') } return node } function wrapNode(node, wrappertype, wrapperclass){ // utility function to wrap a node "node" in an arbitrary element of type "wrappertype" , with a class of "wrapperclass" wrapper = document.createElement(wrappertype) wrapper.className = wrapperclass; innerNode = node.parentNode.replaceChild(wrapper,node); wrapper.appendChild(innerNode) } function minimizeCookiePortlets(){ var portlets = new String() var portletsarray = new Array() portlets = readCookie('mmploneportlets') //alert(portlets) if (portlets){ portletsarray = portlets.split('::') for (var i=0; (p=portletsarray[i]); i++){ //alert(portletsarray[p]) togglePortlet(p) } } } registerPloneFunction(minimizeCookiePortlets) function savePortletToggle(portletid, remove){ // debugger // for when we need to clear the cookies for debugging // createCookie('mmploneportlets',"",-1) var portlets = new String() var portletsarray = new Array() var newportletsarray = new Array() portlets = readCookie('mmploneportlets') if (portlets){ portletsarray = portlets.split('::') for (var i=0; (p=portletsarray[i]); i++){ if (p != portletid){ newportletsarray.push(p) } } } // duplicate the array of portlets, but leave out the current portlet // if we are adding a portlet, append it to the array if (! remove){ newportletsarray.push(portletid) } portlets = newportletsarray.join('::') // alert(portlets) createCookie('mmploneportlets', portlets) } function togglePortlet(pt){ // this is the function that collapses/expands portlets. if (typeof(pt) == 'string'){ // probably from the script detecting cookies. look up the object portlet = document.getElementById(pt) if (! portlet){ return false } icon = portlet.getElementsByTagName('A')[0] node = icon } else if (!pt.nodeType){ // e is probably an event on the image var node = window.event ? window.event.srcElement : pt.currentTarget; } else { // finally , it might just be the icon node itself. node = pt } //debugger if (! icon){var icon = node} if (! portlet){var portlet = node.parentNode.parentNode} for (var f = 0; f < portlet.childNodes.length; f++) { child = portlet.childNodes[f] if (child.nodeName=='DIV'){ if(child.className ==('portletBody')){portletContents=child;} break //else if (child.className.indexOf('portlet-collapsed-info')!=-1){replacementContents=child} } } if( icon.firstChild.nodeValue == "+"){ icon.firstChild.nodeValue="-" portletContents.style.display = 'block' //replacementContents.style.display = 'none' savePortletToggle(portlet.getAttribute('id'),"remove") }else{ icon.firstChild.nodeValue="+" portletContents.style.display = 'none' //replacementContents.style.display = 'block' savePortletToggle(portlet.getAttribute('id')) } return false } // The calendar popup show/hide: function showDay(date) { document.getElementById('day' + date).style.visibility = 'visible'; return true; } function hideDay(date) { document.getElementById('day' + date).style.visibility = 'hidden'; return true; } // Focus on error or tabindex=1 function setFocus() { var xre = new RegExp(/\berror\b/); // Search only forms to avoid spending time on regular text for (var f = 0; (formnode = document.getElementsByTagName('form').item(f)); f++) { // Search for errors first, focus on first error if found for (var i = 0; (node = formnode.getElementsByTagName('div').item(i)); i++) { if (xre.exec(node.className)) { for (var j = 0; (inputnode = node.getElementsByTagName('input').item(j)); j++) { inputnode.focus(); return; } } } // If no error, focus on input element with tabindex 1 // uncomment to reactivate // this part works as intended, but there are too many places where this function causes pain, moving // focus away from a field in whuch the user is already typing //for (var i = 0; (node = formnode.getElementsByTagName('input').item(i)); i++) { // if (node.getAttribute('tabindex') == 1) { // node.focus(); // return; // } //} } } registerPloneFunction(setFocus) /********* Table sorter script *************/ // Table sorter script, thanks to Geir Bækholt for this. // DOM table sorter originally made by Paul Sowden function compare(a,b) { au = new String(a); bu = new String(b); if (au.charAt(4) != '-' && au.charAt(7) != '-') { var an = parseFloat(au) var bn = parseFloat(bu) } if (isNaN(an) || isNaN(bn)) {as = au.toLowerCase() bs = bu.toLowerCase() if (as > bs) {return 1;} else {return -1;} } else { return an - bn; } } function getConcatenedTextContent(node) { var _result = ""; if (node == null) { return _result; } var childrens = node.childNodes; var i = 0; while (i < childrens.length) { var child = childrens.item(i); switch (child.nodeType) { case 1: // ELEMENT_NODE case 5: // ENTITY_REFERENCE_NODE _result += getConcatenedTextContent(child); break; case 3: // TEXT_NODE case 2: // ATTRIBUTE_NODE case 4: // CDATA_SECTION_NODE _result += child.nodeValue; break; case 6: // ENTITY_NODE case 7: // PROCESSING_INSTRUCTION_NODE case 8: // COMMENT_NODE case 9: // DOCUMENT_NODE case 10: // DOCUMENT_TYPE_NODE case 11: // DOCUMENT_FRAGMENT_NODE case 12: // NOTATION_NODE // skip break; } i ++; } return _result; } function sort(e) { var el = window.event ? window.event.srcElement : e.currentTarget; // a pretty ugly sort function, but it works nonetheless var a = new Array(); // check if the image or the th is clicked. Proceed to parent id it is the image // NOTE THAT nodeName IS UPPERCASE if (el.nodeName == 'IMG') el = el.parentNode; //var name = el.firstChild.nodeValue; // This is not very robust, it assumes there is an image as first node then text var name = el.childNodes.item(1).nodeValue; var dad = el.parentNode; var node; // kill all arrows for (var im = 0; (node = dad.getElementsByTagName("th").item(im)); im++) { // NOTE THAT nodeName IS IN UPPERCASE if (node.lastChild.nodeName == 'IMG') { lastindex = node.getElementsByTagName('img').length - 1; node.getElementsByTagName('img').item(lastindex).setAttribute('src',portal_url + '/arrowBlank.gif'); } } for (var i = 0; (node = dad.getElementsByTagName("th").item(i)); i++) { var xre = new RegExp(/\bnosort\b/); // Make sure we are not messing with nosortable columns, then check second node. if (!xre.exec(node.className) && node.childNodes.item(1).nodeValue == name) { //window.alert(node.childNodes.item(1).nodeValue; lastindex = node.getElementsByTagName('img').length -1; node.getElementsByTagName('img').item(lastindex).setAttribute('src',portal_url + '/arrowUp.gif'); break; } } var tbody = dad.parentNode.parentNode.getElementsByTagName("tbody").item(0); for (var j = 0; (node = tbody.getElementsByTagName("tr").item(j)); j++) { // crude way to sort by surname and name after first choice a[j] = new Array(); a[j][0] = getConcatenedTextContent(node.getElementsByTagName("td").item(i)); a[j][1] = getConcatenedTextContent(node.getElementsByTagName("td").item(1)); a[j][2] = getConcatenedTextContent(node.getElementsByTagName("td").item(0)); a[j][3] = node; } if (a.length > 1) { a.sort(compare); // not a perfect way to check, but hell, it suits me fine if (a[0][0] == getConcatenedTextContent(tbody.getElementsByTagName("tr").item(0).getElementsByTagName("td").item(i)) && a[1][0] == getConcatenedTextContent(tbody.getElementsByTagName("tr").item(1).getElementsByTagName("td").item(i))) { a.reverse(); lastindex = el.getElementsByTagName('img').length - 1; el.getElementsByTagName('img').item(lastindex).setAttribute('src', portal_url + '/arrowDown.gif'); } } for (var j = 0; j < a.length; j++) { tbody.appendChild(a[j][3]); } } function initalizeTableSort(e) { var tbls = document.getElementsByTagName('table'); for (var t = 0; t < tbls.length; t++) { // elements of class="listing" can be sorted var re = new RegExp(/\blisting\b/) // elements of class="nosort" should not be sorted var xre = new RegExp(/\bnosort\b/) if (re.exec(tbls[t].className) && !xre.exec(tbls[t].className)) { try { var tablename = tbls[t].getAttribute('id'); var thead = document.getElementById(tablename).getElementsByTagName("thead").item(0); var node; // set up blank spaceholder gifs blankarrow = document.createElement('img'); blankarrow.setAttribute('src', portal_url + '/arrowBlank.gif'); blankarrow.setAttribute('height',6); blankarrow.setAttribute('width',9); // the first sortable column should get an arrow initially. initialsort = false; for (var i = 0; (node = thead.getElementsByTagName("th").item(i)); i++) { // check that the columns does not have class="nosort" if (!xre.exec(node.className)) { node.insertBefore(blankarrow.cloneNode(1), node.firstChild); if (!initialsort) { initialsort = true; uparrow = document.createElement('img'); uparrow.setAttribute('src', portal_url + '/arrowUp.gif'); uparrow.setAttribute('height',6); uparrow.setAttribute('width',9); node.appendChild(uparrow); } else { node.appendChild(blankarrow.cloneNode(1)); } if (node.addEventListener) node.addEventListener("click",sort,false); else if (node.attachEvent) node.attachEvent("onclick",sort); } } } catch(er) {} } } } // **** End table sort script *** registerPloneFunction(initalizeTableSort) // Actions used in the folder_contents view function submitFolderAction(folderAction) { document.folderContentsForm.action = document.folderContentsForm.action+'/'+folderAction; document.folderContentsForm.submit(); } function submitFilterAction() { document.folderContentsForm.action = document.folderContentsForm.action+'/folder_contents'; filter_selection=document.getElementById('filter_selection'); for (var i =0; i < filter_selection.length; i++){ if (filter_selection.options[i].selected) { if (filter_selection.options[i].value=='#') { document.folderContentsForm.filter_state.value='clear_view_filter'; } else { document.folderContentsForm.filter_state.value='set_view_filter'; } } } document.folderContentsForm.submit(); } // Functions for selecting all checkboxes in folder_contents/search_form view function selectAll(id, formName) { // get the elements. if formName is p rovided, get the elements inside the form if (formName==null) { checkboxes = document.getElementsByName(id) for (i = 0; i < checkboxes.length; i++) checkboxes[i].checked = true ; } else { for (i=0; i