2 * Copyright 2005 New Roads School
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 * This describes the nrsTable, which is a table created in JavaScript that is
22 * able to be sorted and displayed in different ways based on teh configuration
23 * parameters passed to it.
24 * to create a new table one only needs to call the setup function like so:
28 * table_name: "table_container",
34 * Where table_name is the name of the table to build. THis must be defined in
35 * your HTML by putting a table declaration, such as <table id=table_name>
36 * </table>. This will declare where your table will be shown.
37 * All sorts of parameters can be customized here. For details look at the
44 * Debug function. Set debug to tru to view messages.
45 * \param msg Message to display in an alert.
55 * There is a memory leak problem that I can't seem to fix. I'm attching
56 * something that I found from Aaron Boodman, which will clean up all the
57 * memory leaks in the page (this can be found at http://youngpup.net/2005/0221010713
58 * ). This is a little clunky, but it will do till I track this problem.
59 * Oh, and this problem only occurrs is IE.
61 if (window.attachEvent) {
62 var clearElementProps = [
74 window.attachEvent("onunload", function() {
76 for(var d = document.all.length;d--;){
78 for(var c = clearElementProps.length;c--;){
79 el[clearElementProps[c]] = null;
87 * This is the constructor.
88 * It only needs the name of the table. This should never be called directly,
89 * instead use setup function.
90 * \param table The name of the table to create.
93 function nrsTable(table)
95 this.my_table = table;
96 this.field_to_sort = 0;
97 this.field_asc = true;
102 * This function is responsible for setting up an nrsTable. All the parameters
103 * can be configured directly from this function. The params array of this
104 * function is a class (or a associative array, depending on how you want to
105 * look at it) with the following possible parameters:
106 * - table_name: required. The id of the table tag.
107 * - table_header: required. An array containing the header names.
108 * - table_data: optional. A 2D array of strings containing the cell contents.
109 * - caption: optional. A caption to include on the table.
110 * - row_links: optional. An array with hyperlinks per row. Must be a javascript function.
111 * - cell_links: optional. A 2D array with links on every cell. Must be a javascript function
112 * - up_icon: optional. A path to the ascending sort arrow.
113 * - down_icon: optional. A path to the descending sort arrow.
114 * - prev_icon: optional. A path to the previous page icon in the navigation.
115 * - next_icon: optional. A path to the next page icon in the navigation.
116 * - rew_icon: optional. A path to the first page icon in the navigation.
117 * - fwd_icon: optional. A path to the last page icon in the navigation.
118 * - rows_per_page: optional. The number of rows per page to display at any one time.
119 * - display_nav: optional. Displays navigation (prev, next, first, last)
120 * - foot_headers: optional. Whether to display th eheaders at the foot of the table.
121 * - header_color: optional. The color of the header cells. Will default to whatever is defined in CSS.
122 * - even_cell_color: optional. The color of the even data cells. Will default to whatever is defined in CSS.
123 * - odd_cell_color: optional. The color of the odd data cells. Will default to whatever is defined in CSS.
124 * - footer_color: optional. The color of the footer cells. Will default to whatever is defined in CSS.
125 * - hover_color: optional. The color tha a row should turn when the mouse is over it.
126 * - padding: optional. Individual cell padding, in pixels.
127 * - natural_compare: optional. Uses the natural compare algorithm (separate from this program) to sort.
128 * - disable_sorting: optional. An array specifying the columns top disable sorting on (0 is the first column).
130 * \params params An array as described above.
132 nrsTable.setup = function(params)
134 //here we assign all the veriables that we are passed, or the defaults if
135 //they are not defined.
136 //Note that the only requirements are a table name and a header.
137 if(typeof params['table_name'] == "undefined")
139 alert("Error! You must supply a table name!");
142 if(typeof params['table_header'] == "undefined")
144 alert("Error! You must supply a table header!");
148 //check if the global array exists, else create it.
149 if(typeof(nrsTables) == "undefined")
151 eval("nrsTables = new Array();");
153 nrsTables[params['table_name']] = new nrsTable(params['table_name']);
154 nrsTables[params['table_name']].heading = params['table_header'].concat();
156 //now the non-required elements. Data elements first
157 nrsTables[params['table_name']].data = (typeof params['table_data'] == "undefined" || !params['table_data'])? null: params['table_data'].concat();
158 nrsTables[params['table_name']].caption = (typeof params['caption'] == "undefined")? null: params['caption'];
159 nrsTables[params['table_name']].row_links = (typeof params['row_links'] == "undefined" || !params['row_links'])? null: params['row_links'].concat();
160 nrsTables[params['table_name']].cell_links = (typeof params['cell_links'] == "undefined" || !params['row_links'])? null: params['cell_links'].concat();
162 //these are the icons.
163 nrsTables[params['table_name']].up_icon = (typeof params['up_icon'] == "undefined")? "up.gif": params['up_icon'];
164 nrsTables[params['table_name']].down_icon = (typeof params['down_icon'] == "undefined")? "down.gif": params['down_icon'];
165 nrsTables[params['table_name']].prev_icon = (typeof params['prev_icon'] == "undefined")? "left.gif": params['prev_icon'];
166 nrsTables[params['table_name']].next_icon = (typeof params['next_icon'] == "undefined")? "right.gif": params['next_icon'];
167 nrsTables[params['table_name']].rew_icon = (typeof params['rew_icon'] == "undefined")? "first.gif": params['rew_icon'];
168 nrsTables[params['table_name']].fwd_icon = (typeof params['fwd_icon'] == "undefined")? "last.gif": params['fwd_icon'];
170 //now the look and feel options.
171 nrsTables[params['table_name']].rows_per_page = (typeof params['rows_per_page'] == "undefined")? -1: params['rows_per_page'];
172 nrsTables[params['table_name']].page_nav = (typeof params['page_nav'] == "undefined")? false: params['page_nav'];
173 nrsTables[params['table_name']].foot_headers = (typeof params['foot_headers'] == "undefined")? false: params['foot_headers'];
174 nrsTables[params['table_name']].header_color = (typeof params['header_color'] == "undefined")? null: params['header_color'];
175 nrsTables[params['table_name']].even_cell_color = (typeof params['even_cell_color'] == "undefined")? null: params['even_cell_color'];
176 nrsTables[params['table_name']].odd_cell_color = (typeof params['odd_cell_color'] == "undefined")? null: params['odd_cell_color'];
177 nrsTables[params['table_name']].footer_color = (typeof params['footer_color'] == "undefined")? null: params['footer_color'];
178 nrsTables[params['table_name']].hover_color = (typeof params['hover_color'] == "undefined")? null: params['hover_color'];
179 nrsTables[params['table_name']].padding = (typeof params['padding'] == "undefined")? null: params['padding'];
180 nrsTables[params['table_name']].natural_compare = (typeof params['natural_compare'] == "undefined")? false: true;
181 nrsTables[params['table_name']].disable_sorting =
182 (typeof params['disable_sorting'] == "undefined")? false: "." + params['disable_sorting'].join(".") + ".";
183 //finally, build the table
184 nrsTables[params['table_name']].buildTable();
189 * This is the Javascript quicksort implementation. This will sort the
190 * this.data and the this.data_nodes based on the this.field_to_sort parameter.
191 * \param left The left index of the array.
192 * \param right The right index of the array
194 nrsTable.prototype.quickSort = function(left, right)
196 if(!this.data || this.data.length == 0)
198 // alert("left = " + left + " right = " + right);
201 var k = this.data[Math.round((left + right) / 2)][this.field_to_sort];
212 while(this.data[i][this.field_to_sort].toLowerCase() < k)
214 while(this.data[j][this.field_to_sort].toLowerCase() > k)
219 while(this.data[i][this.field_to_sort].toLowerCase() > k)
221 while(this.data[j][this.field_to_sort].toLowerCase() < k)
228 var temp = this.data[i];
229 this.data[i] = this.data[j];
233 var temp = this.data_nodes[i];
234 this.data_nodes[i] = this.data_nodes[j];
235 this.data_nodes[j] = temp;
241 this.quickSort(left, j);
243 this.quickSort(i, right);
247 * This is the Javascript natural sort function. Because of some obscure JavaScript
248 * quirck, we could not do quicsort while calling natcompare to compare, so this
249 * function will so a simple bubble sort using the natural compare algorithm.
251 nrsTable.prototype.natSort = function()
253 if(!this.data || this.data.length == 0)
256 for(i = 0; i < this.data.length - 1; i++)
258 for(j = i; j < this.data.length; j++)
262 if(natcompare(this.data[i][this.field_to_sort].toLowerCase(),
263 this.data[j][this.field_to_sort].toLowerCase()) == -1)
270 if(natcompare(this.data[i][this.field_to_sort].toLowerCase(),
271 this.data[j][this.field_to_sort].toLowerCase()) == 1)
280 var temp = this.data[i];
281 this.data[i] = this.data[j];
285 var temp = this.data_nodes[i];
286 this.data_nodes[i] = this.data_nodes[j];
287 this.data_nodes[j] = temp;
294 * This function will recolor all the the nodes to conform to the alternating
297 nrsTable.prototype.recolorRows = function()
299 if(this.even_cell_color || this.odd_cell_color)
301 DEBUG("Recoloring Rows. length = " + this.data_nodes.length);
302 for(var i = 0; i < this.data_nodes.length; i++)
306 if(this.even_cell_color)
307 this.data_nodes[i].style.backgroundColor = this.even_cell_color;
308 this.data_nodes[i].setAttribute("id", "even_row");
312 if(this.odd_cell_color)
313 this.data_nodes[i].style.backgroundColor = this.odd_cell_color;
314 this.data_nodes[i].setAttribute("id", "odd_row");
321 * This function will create the Data Nodes, which are a reference to the table
324 nrsTable.prototype.createDataNodes = function()
327 delete this.data_nodes;
328 this.data_nodes = new Array();
331 for(var i = 0; i < this.data.length; i++)
333 var curr_row = document.createElement("TR");
335 for(var j = 0; j < this.data[i].length; j++)
337 var curr_cell = document.createElement("TD");
338 //do we need to create links on every cell?
341 var fn = new Function("", this.cell_links[i][j]);
342 curr_cell.onclick = fn;
343 curr_cell.style.cursor = 'pointer';
346 curr_cell.setAttribute("className", "dataTD" + j);
350 curr_cell.style.paddingLeft = this.padding + "px";
351 curr_cell.style.paddingRight = this.padding + "px";
354 if (typeof this.data[i][j] == "object") {
355 curr_cell.appendChild(this.data[i][j]);
357 curr_cell.appendChild(document.createTextNode(this.data[i][j]));
360 curr_row.appendChild(curr_cell);
362 //do we need to create links on every row?
363 if(!this.cell_links && this.row_links)
365 var fn = new Function("", this.row_links[i]);
366 curr_row.onclick = fn;
367 curr_row.style.cursor = 'pointer';
369 //sets the id for odd and even rows.
372 curr_row.setAttribute("id", "even_row");
373 if(this.even_cell_color)
374 curr_row.style.backgroundColor = this.even_cell_color;
378 curr_row.setAttribute("id", "odd_row");
379 if(this.odd_cell_color)
380 curr_row.style.backgroundColor = this.odd_cell_color;
384 curr_row.onmouseover = new Function("", "this.style.backgroundColor='" + this.hover_color + "';");
385 curr_row.onmouseout = new Function("", "this.style.backgroundColor=(this.id=='even_row')?'" +
386 this.even_cell_color + "':'" + this.odd_cell_color + "';");
388 this.data_nodes[i] = curr_row;
393 * This function will update the nav page display.
395 nrsTable.prototype.updateNav = function()
400 if(this.foot_headers)
402 var t = document.getElementById(this.my_table);
403 var nav = t.tFoot.childNodes[p];
406 var caption = t.tFoot.childNodes[p].childNodes[0].childNodes[2];
407 caption.innerHTML = "Page " + (this.current_page + 1) + " of " + this.num_pages;
411 if(this.num_pages > 1)
414 nav = t.tFoot.childNodes[p];
419 if(this.current_page == 0)
420 this.hideLeftArrows();
422 this.showLeftArrows();
424 if(this.current_page + 1 == this.num_pages)
425 this.hideRightArrows();
427 this.showRightArrows();
433 * This function will flip the sort arrow in place. If a heading is used in the
434 * footer, then it will flip that one too.
436 nrsTable.prototype.flipSortArrow = function()
438 this.field_asc = !this.field_asc;
439 //flip the arrow on the heading.
440 var heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[this.field_to_sort];
442 heading.getElementsByTagName("IMG")[0].setAttribute("src", this.up_icon);
444 heading.getElementsByTagName("IMG")[0].setAttribute("src", this.down_icon);
445 //is there a heading in the footer?
446 if(this.foot_headers)
448 //yes, so flip that arrow too.
449 var footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[this.field_to_sort];
451 footer.getElementsByTagName("IMG")[0].setAttribute("src", this.up_icon);
453 footer.getElementsByTagName("IMG")[0].setAttribute("src", this.down_icon);
458 * This function will move the sorting arrow from the place specified in
459 * this.field_to_sort to the passed parameter. It will also set
460 * this.field_to_sort to the new value. It will also do it in the footers,
462 * \param field The new field to move it to.
464 nrsTable.prototype.moveSortArrow = function(field)
466 var heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[this.field_to_sort];
467 var img = heading.removeChild(heading.getElementsByTagName("IMG")[0]);
468 heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[field];
469 heading.appendChild(img);
470 //are there headers in the footers.
471 if(this.foot_headers)
473 //yes, so switch them too.
474 var footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[this.field_to_sort];
475 var img = footer.removeChild(footer.getElementsByTagName("IMG")[0]);
476 footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[field];
477 footer.appendChild(img);
479 //finally, set the field to sort by.
480 this.field_to_sort = field;
484 * This function completely destroys a table. Should be used only when building
485 * a brand new table (ie, new headers). Else you should use a function like
486 * buildNewData which only deletes the TBody section.
488 nrsTable.prototype.emptyTable = function()
490 var t = document.getElementById(this.my_table);
491 while(t.childNodes.length != 0)
492 t.removeChild(t.childNodes[0]);
496 * This function builds a brand new table from scratch. This function should
497 * only be called when a brand new table (with headers, footers, etc) needs
498 * to be created. NOT when refreshing data or changing data.
500 nrsTable.prototype.buildTable = function()
502 //reset the sorting information.
503 this.field_to_sort = 0;
504 this.field_asc = true;
506 //remove the nodes links.
507 delete this.data_nodes;
509 //do we have to calculate the number of pages?
510 if(this.data && this.rows_per_page != -1)
513 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
514 this.current_page = 0;
517 //blank out the table.
520 //this is the table that we will be using.
521 var table = document.getElementById(this.my_table);
523 //is there a caption?
526 var caption = document.createElement("CAPTION");
527 caption.setAttribute("align", "top");
528 caption.appendChild(document.createTextNode(this.caption));
529 table.appendChild(caption);
532 //do the heading first
533 var table_header = document.createElement("THEAD");
534 var table_heading = document.createElement("TR");
535 //since this is a new table the first field is what's being sorted.
536 var curr_cell = document.createElement("TH");
537 var fn = new Function("", "nrsTables['" + this.my_table + "'].fieldSort(" + 0 + ");");
538 if(!this.disable_sorting || this.disable_sorting.indexOf(".0.") == -1)
539 curr_cell.onclick = fn;
540 if(this.header_color)
541 curr_cell.style.backgroundColor = this.header_color;
542 curr_cell.style.cursor = 'pointer';
543 var img = document.createElement("IMG");
544 img.setAttribute("src", this.up_icon);
545 img.setAttribute("border", "0");
546 img.setAttribute("height", "8");
547 img.setAttribute("width", "8");
548 curr_cell.appendChild(document.createTextNode(this.heading[0]));
549 curr_cell.appendChild(img);
550 table_heading.appendChild(curr_cell);
551 //now do the rest of the heading.
552 for(var i = 1; i < this.heading.length; i++)
554 curr_cell = document.createElement("TH");
555 var fn = new Function("", "nrsTables['" + this.my_table + "'].fieldSort(" + i + ");");
556 if(!this.disable_sorting || this.disable_sorting.indexOf("." + i + ".") == -1)
557 curr_cell.onclick = fn;
558 if(this.header_color)
559 curr_cell.style.backgroundColor = this.header_color;
560 curr_cell.style.cursor = 'pointer';
562 curr_cell.appendChild(document.createTextNode(this.heading[i]));
563 table_heading.appendChild(curr_cell);
565 table_header.appendChild(table_heading);
568 var table_body = document.createElement("TBODY");
569 this.createDataNodes();
572 if(this.natural_compare)
573 this.natSort(0, this.data.length - 1);
575 this.quickSort(0, this.data.length - 1);
579 //finally, the footer
580 var table_footer = document.createElement("TFOOT");
581 if(this.foot_headers)
583 table_footer.appendChild(table_heading.cloneNode(true));
586 if(this.page_nav && this.num_pages > 1)
588 //print out the page navigation
589 //first and previous page
590 var nav = document.createElement("TR");
591 var nav_cell = document.createElement("TH");
592 nav_cell.colSpan = this.heading.length;
594 var left = document.createElement("DIV");
595 if(document.attachEvent)
596 left.style.styleFloat = "left";
598 left.style.cssFloat = "left";
599 var img = document.createElement("IMG");
600 img.setAttribute("src", this.rew_icon);
601 img.setAttribute("border", "0");
602 img.setAttribute("height", "10");
603 img.setAttribute("width", "10");
604 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].firstPage();");
605 img.style.cursor = 'pointer';
606 left.appendChild(img);
607 //hack to space the arrows, cause IE is absolute crap
608 left.appendChild(document.createTextNode(" "));
609 img = document.createElement("IMG");
610 img.setAttribute("src", this.prev_icon);
611 img.setAttribute("border", "0");
612 img.setAttribute("height", "10");
613 img.setAttribute("width", "10");
614 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].prevPage();");
615 img.style.cursor = 'pointer';
616 left.appendChild(img);
617 //apend it to the cell
618 nav_cell.appendChild(left);
620 //next and last pages
621 var right = document.createElement("DIV");
622 if(document.attachEvent)
623 right.style.styleFloat = "right";
625 right.style.cssFloat = "right";
626 img = document.createElement("IMG");
627 img.setAttribute("src", this.next_icon);
628 img.setAttribute("border", "0");
629 img.setAttribute("height", "10");
630 img.setAttribute("width", "10");
631 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].nextPage();");
632 img.style.cursor = 'pointer';
633 right.appendChild(img);
634 //hack to space the arrows, cause IE is absolute crap
635 right.appendChild(document.createTextNode(" "));
636 img = document.createElement("IMG");
637 img.setAttribute("src", this.fwd_icon);
638 img.setAttribute("border", "0");
639 img.setAttribute("height", "10");
640 img.setAttribute("width", "10");
641 img.onclick = new Function("", "JavaScript:nrsTables['" + this.my_table + "'].lastPage();");
642 img.style.cursor = 'pointer';
643 right.appendChild(img);
644 //apend it to the cell
645 nav_cell.appendChild(right);
648 var pos = document.createElement("SPAN");
649 pos.setAttribute("id", "nav_pos");
650 pos.appendChild(document.createTextNode("Page " +
651 (this.current_page + 1) + " of " + this.num_pages));
652 //append it to the cell.
653 nav_cell.appendChild(pos);
655 nav.appendChild(nav_cell);
656 //append it to the footer
657 table_footer.appendChild(nav);
660 if(this.footer_color)
662 for(var i = 0; i < table_footer.childNodes.length; i++)
663 table_footer.childNodes[i].style.backgroundColor = this.footer_color;
667 table.appendChild(table_header);
668 table.appendChild(table_body);
669 table.appendChild(table_footer);
672 if(this.natural_compare)
673 this.natSort(0, this.data.length - 1);
675 this.quickSort(0, this.data.length - 1);
681 * This function will remove the elements in teh TBody section of the table and
682 * return an array of references of those elements. This array can then be
683 * sorted and re-inserted into the table.
684 * \return An array to references of the TBody contents.
686 nrsTable.prototype.extractElements = function()
688 var tbody = document.getElementById(this.my_table).tBodies[0];
689 var nodes = new Array();
691 while(tbody.childNodes.length > 0)
693 nodes[i] = tbody.removeChild(tbody.childNodes[0]);
700 * This function will re-insert an array of elements into the TBody of a table.
701 * Note that the array elements are stored in the this.data_nodes reference.
703 nrsTable.prototype.insertElements = function()
705 var tbody = document.getElementById(this.my_table).tBodies[0];
707 var num_elements = this.data_nodes.length;
708 if(this.rows_per_page != -1)
710 start = this.current_page * this.rows_per_page;
711 num_elements = (this.data_nodes.length - start) > this.rows_per_page?
712 this.rows_per_page + start:
713 this.data_nodes.length;
715 DEBUG("start is " + start + " and num_elements is " + num_elements);
716 for(var i = start; i < num_elements; i++)
718 tbody.appendChild(this.data_nodes[i]);
723 * This function will sort the table's data by a specific field. The field
724 * parameter referes to which field index should be sorted.
725 * \param field The field index which to sort on.
727 nrsTable.prototype.fieldSort = function(field)
729 if(this.field_to_sort == field)
731 //only need to reverse the array.
735 this.data_nodes.reverse();
737 //flip the arrow on the heading.
738 this.flipSortArrow();
742 //In this case, we need to sort the array. We'll sort it last, first
743 //make sure that the arrow images are set correctly.
744 this.moveSortArrow(field);
745 //finally, set the field to sort by.
746 this.field_to_sort = field;
749 //we'll be using our implementation of quicksort
750 if(this.natural_compare)
751 this.natSort(0, this.data.length - 1);
753 this.quickSort(0, this.data.length - 1);
756 //finally, we refresh the table.
761 * This function will refresh the data in the table. This function should be
762 * used whenever the nodes have changed, or when chanign pages. Note that
763 * this will NOT re-sort.
765 nrsTable.prototype.refreshTable = function()
767 this.extractElements();
769 this.insertElements();
770 //finally, if there is a nav, upate it.
775 * This function will advance a page. If we are already at the last page, then
776 * it will remain there.
778 nrsTable.prototype.nextPage = function()
780 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
781 if(this.current_page + 1 != this.num_pages)
786 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
790 * This function will go back a page. If we are already at the first page, then
791 * it will remain there.
793 nrsTable.prototype.prevPage = function()
795 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
796 if(this.current_page != 0)
801 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
805 * This function will go to the first page.
807 nrsTable.prototype.firstPage = function()
809 if(this.current_page != 0)
811 this.current_page = 0;
817 * This function will go to the last page.
819 nrsTable.prototype.lastPage = function()
821 DEBUG("lastPage(), current_page: " + this.current_page + " and num_pages: " + this.num_pages);
822 if(this.current_page != (this.num_pages - 1))
824 this.current_page = this.num_pages - 1;
830 * This function will go to a specific page. valid values are pages 1 to
831 * however many number of pages there are.
832 * \param page The page number to go to.
834 nrsTable.prototype.gotoPage = function(page)
837 if(page >=0 && page < this.num_pages)
839 this.current_page = page;
845 * This function can be used to change the number of entries per row displayed
847 * \param entries The number of entries per page.
849 nrsTable.prototype.changeNumRows = function(entries)
853 this.rows_per_page = entries;
855 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
861 * This function will take in a new data array and , optionally, a new cell_link
862 * array OR a new row_link array. Only one will be used, with the cell_link
863 * array taking precedence. It will then re-build the table with the new data
865 * \param new_data This is the new data array. This is required.
866 * \param cell_links This is the new cell links array, a 2D array for each cell.
867 * \param row_links This is the new row links array, a 1D array for each row.
869 nrsTable.prototype.newData = function(new_data, cell_links, row_links)
871 //extract the elements from teh table to clear the table.
872 this.extractElements();
873 //now delete all the data related to this table. I do this so that
874 //(hopefully) the memory will be freed. This is realy needed for IE, whose
875 //memory handling is almost non-existant
877 delete this.data_nodes;
878 delete this.cell_links;
879 delete this.row_links
881 this.data = new_data;
882 this.cell_links = cell_links;
883 this.row_links = row_links;
884 if(this.rows_per_page != -1)
887 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
888 if(this.num_pages <= 1 && this.page_nav)
890 else if(this.page_nav)
892 this.current_page = 0;
894 this.createDataNodes();
895 if(this.field_to_sort != 0)
896 this.moveSortArrow(0);
898 this.flipSortArrow();
899 this.insertElements();
904 * This function will remove the NAV bar (if one exists) from the table.
906 nrsTable.prototype.removeNav = function()
910 //in this case, remove the nav from the existing structure.
911 var table = document.getElementById(this.my_table);
913 if(this.foot_headers)
915 var nav = table.tFoot.childNodes[p];
918 table.tFoot.removeChild(nav);
925 * This function wil re-insert the nav into the table.
927 nrsTable.prototype.insertNav = function()
929 table = document.getElementById(this.my_table);
931 if(this.foot_headers)
933 if(this.page_nav && !table.tFoot.childNodes[p])
935 //this means there should be a nav and there isn't one.
936 //print out the page navigation
937 //first and previous page
938 var nav = document.createElement("TR");
939 var nav_cell = document.createElement("TH");
940 nav_cell.colSpan = this.heading.length;
942 var left = document.createElement("DIV");
943 if(document.attachEvent)
944 left.style.styleFloat = "left";
946 left.style.cssFloat = "left";
947 var img = document.createElement("IMG");
948 img.setAttribute("src", this.rew_icon);
949 img.setAttribute("border", "0");
950 img.setAttribute("height", "10");
951 img.setAttribute("width", "10");
952 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].firstPage();");
953 img.style.cursor = 'pointer';
954 left.appendChild(img);
955 //hack to space the arrows, cause IE is absolute crap
956 left.appendChild(document.createTextNode(" "));
957 img = document.createElement("IMG");
958 img.setAttribute("src", this.prev_icon);
959 img.setAttribute("border", "0");
960 img.setAttribute("height", "10");
961 img.setAttribute("width", "10");
962 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].prevPage();");
963 img.style.cursor = 'pointer';
964 left.appendChild(img);
965 //apend it to the cell
966 nav_cell.appendChild(left);
968 //next and last pages
969 var right = document.createElement("DIV");
970 if(document.attachEvent)
971 right.style.styleFloat = "right";
973 right.style.cssFloat = "right";
974 img = document.createElement("IMG");
975 img.setAttribute("src", this.next_icon);
976 img.setAttribute("border", "0");
977 img.setAttribute("height", "10");
978 img.setAttribute("width", "10");
979 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].nextPage();");
980 img.style.cursor = 'pointer';
981 right.appendChild(img);
982 //hack to space the arrows, cause IE is absolute crap
983 right.appendChild(document.createTextNode(" "));
984 img = document.createElement("IMG");
985 img.setAttribute("src", this.fwd_icon);
986 img.setAttribute("border", "0");
987 img.setAttribute("height", "10");
988 img.setAttribute("width", "10");
989 img.onclick = new Function("", "JavaScript:nrsTables['" + this.my_table + "'].lastPage();");
990 img.style.cursor = 'pointer';
991 right.appendChild(img);
992 //apend it to the cell
993 nav_cell.appendChild(right);
996 var pos = document.createElement("SPAN");
997 pos.setAttribute("id", "nav_pos");
998 pos.appendChild(document.createTextNode("Page " +
999 (this.current_page + 1) + " of " + this.num_pages));
1000 //append it to the cell.
1001 nav_cell.appendChild(pos);
1003 nav.appendChild(nav_cell);
1004 //append it to the footer
1005 table.tFoot.appendChild(nav);
1010 * This function will hide the previous arrow and the rewind arrows from the
1013 nrsTable.prototype.hideLeftArrows = function()
1017 var myTable = document.getElementById(this.my_table);
1019 if(this.foot_headers)
1021 var nav = myTable.tFoot.childNodes[p];
1022 nav.childNodes[0].childNodes[0].style.display = "none";
1026 * This function will show the previous arrow and the rewind arrows from the
1029 nrsTable.prototype.showLeftArrows = function()
1033 table = document.getElementById(this.my_table);
1035 if(this.foot_headers)
1037 var nav = table.tFoot.childNodes[p];
1038 nav.childNodes[0].childNodes[0].style.display = "block";
1042 * This function will hide the next arrow and the fast foward arrows from the
1045 nrsTable.prototype.hideRightArrows = function()
1049 table = document.getElementById(this.my_table);
1051 if(this.foot_headers)
1053 var nav = table.tFoot.childNodes[p];
1054 nav.childNodes[0].childNodes[1].style.display = "none";
1058 * This function will show the next arrow and the fast foward arrows from the
1061 nrsTable.prototype.showRightArrows = function()
1065 table = document.getElementById(this.my_table);
1067 if(this.foot_headers)
1069 var nav = table.tFoot.childNodes[p];
1070 nav.childNodes[0].childNodes[1].style.display = "block";