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];
214 while(this.data[i][this.field_to_sort].toLowerCase() < k)
216 while(this.data[j][this.field_to_sort].toLowerCase() > k)
221 while(this.data[i][this.field_to_sort].toLowerCase() > k)
223 while(this.data[j][this.field_to_sort].toLowerCase() < k)
230 var temp = this.data[i];
231 this.data[i] = this.data[j];
235 var temp = this.data_nodes[i];
236 this.data_nodes[i] = this.data_nodes[j];
237 this.data_nodes[j] = temp;
243 this.quickSort(left, j);
245 this.quickSort(i, right);
249 * This is the Javascript natural sort function. Because of some obscure JavaScript
250 * quirck, we could not do quicsort while calling natcompare to compare, so this
251 * function will so a simple bubble sort using the natural compare algorithm.
253 nrsTable.prototype.natSort = function()
255 if(!this.data || this.data.length == 0)
258 for(i = 0; i < this.data.length - 1; i++)
260 for(j = i; j < this.data.length; j++)
264 if(natcompare(this.data[i][this.field_to_sort].toLowerCase(),
265 this.data[j][this.field_to_sort].toLowerCase()) == -1)
272 if(natcompare(this.data[i][this.field_to_sort].toLowerCase(),
273 this.data[j][this.field_to_sort].toLowerCase()) == 1)
282 var temp = this.data[i];
283 this.data[i] = this.data[j];
287 var temp = this.data_nodes[i];
288 this.data_nodes[i] = this.data_nodes[j];
289 this.data_nodes[j] = temp;
296 * This function will recolor all the the nodes to conform to the alternating
299 nrsTable.prototype.recolorRows = function()
301 if(this.even_cell_color || this.odd_cell_color)
303 DEBUG("Recoloring Rows. length = " + this.data_nodes.length);
304 for(var i = 0; i < this.data_nodes.length; i++)
308 if(this.even_cell_color)
309 this.data_nodes[i].style.backgroundColor = this.even_cell_color;
310 this.data_nodes[i].setAttribute("id", "even_row");
314 if(this.odd_cell_color)
315 this.data_nodes[i].style.backgroundColor = this.odd_cell_color;
316 this.data_nodes[i].setAttribute("id", "odd_row");
323 * This function will create the Data Nodes, which are a reference to the table
326 nrsTable.prototype.createDataNodes = function()
329 delete this.data_nodes;
330 this.data_nodes = new Array();
333 for(var i = 0; i < this.data.length; i++)
335 var curr_row = document.createElement("TR");
337 for(var j = 0; j < this.data[i].length; j++)
339 var curr_cell = document.createElement("TD");
340 //do we need to create links on every cell?
343 var fn = new Function("", this.cell_links[i][j]);
344 curr_cell.onclick = fn;
345 curr_cell.style.cursor = 'pointer';
348 curr_cell.setAttribute("className", "dataTD" + j);
352 curr_cell.style.paddingLeft = this.padding + "px";
353 curr_cell.style.paddingRight = this.padding + "px";
356 if (typeof this.data[i][j] == "object") {
357 curr_cell.appendChild(this.data[i][j]);
359 curr_cell.appendChild(document.createTextNode(this.data[i][j]));
362 curr_row.appendChild(curr_cell);
364 //do we need to create links on every row?
365 if(!this.cell_links && this.row_links)
367 var fn = new Function("", this.row_links[i]);
368 curr_row.onclick = fn;
369 curr_row.style.cursor = 'pointer';
371 //sets the id for odd and even rows.
374 curr_row.setAttribute("id", "even_row");
375 if(this.even_cell_color)
376 curr_row.style.backgroundColor = this.even_cell_color;
380 curr_row.setAttribute("id", "odd_row");
381 if(this.odd_cell_color)
382 curr_row.style.backgroundColor = this.odd_cell_color;
386 curr_row.onmouseover = new Function("", "this.style.backgroundColor='" + this.hover_color + "';");
387 curr_row.onmouseout = new Function("", "this.style.backgroundColor=(this.id=='even_row')?'" +
388 this.even_cell_color + "':'" + this.odd_cell_color + "';");
390 this.data_nodes[i] = curr_row;
395 * This function will update the nav page display.
397 nrsTable.prototype.updateNav = function()
402 if(this.foot_headers)
404 var t = document.getElementById(this.my_table);
405 var nav = t.tFoot.childNodes[p];
408 var caption = t.tFoot.childNodes[p].childNodes[0].childNodes[2];
409 caption.innerHTML = "Page " + (this.current_page + 1) + " of " + this.num_pages;
413 if(this.num_pages > 1)
416 nav = t.tFoot.childNodes[p];
421 if(this.current_page == 0)
422 this.hideLeftArrows();
424 this.showLeftArrows();
426 if(this.current_page + 1 == this.num_pages)
427 this.hideRightArrows();
429 this.showRightArrows();
435 * This function will flip the sort arrow in place. If a heading is used in the
436 * footer, then it will flip that one too.
438 nrsTable.prototype.flipSortArrow = function()
440 this.field_asc = !this.field_asc;
441 //flip the arrow on the heading.
442 var heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[this.field_to_sort];
444 heading.getElementsByTagName("IMG")[0].setAttribute("src", this.up_icon);
446 heading.getElementsByTagName("IMG")[0].setAttribute("src", this.down_icon);
447 //is there a heading in the footer?
448 if(this.foot_headers)
450 //yes, so flip that arrow too.
451 var footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[this.field_to_sort];
453 footer.getElementsByTagName("IMG")[0].setAttribute("src", this.up_icon);
455 footer.getElementsByTagName("IMG")[0].setAttribute("src", this.down_icon);
460 * This function will move the sorting arrow from the place specified in
461 * this.field_to_sort to the passed parameter. It will also set
462 * this.field_to_sort to the new value. It will also do it in the footers,
464 * \param field The new field to move it to.
466 nrsTable.prototype.moveSortArrow = function(field)
468 var heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[this.field_to_sort];
469 var img = heading.removeChild(heading.getElementsByTagName("IMG")[0]);
470 heading = document.getElementById(this.my_table).tHead.childNodes[0].childNodes[field];
471 heading.appendChild(img);
472 //are there headers in the footers.
473 if(this.foot_headers)
475 //yes, so switch them too.
476 var footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[this.field_to_sort];
477 var img = footer.removeChild(footer.getElementsByTagName("IMG")[0]);
478 footer = document.getElementById(this.my_table).tFoot.childNodes[0].childNodes[field];
479 footer.appendChild(img);
481 //finally, set the field to sort by.
482 this.field_to_sort = field;
486 * This function completely destroys a table. Should be used only when building
487 * a brand new table (ie, new headers). Else you should use a function like
488 * buildNewData which only deletes the TBody section.
490 nrsTable.prototype.emptyTable = function()
492 var t = document.getElementById(this.my_table);
493 while(t.childNodes.length != 0)
494 t.removeChild(t.childNodes[0]);
498 * This function builds a brand new table from scratch. This function should
499 * only be called when a brand new table (with headers, footers, etc) needs
500 * to be created. NOT when refreshing data or changing data.
502 nrsTable.prototype.buildTable = function()
504 //reset the sorting information.
505 this.field_to_sort = 0;
506 this.field_asc = true;
508 //remove the nodes links.
509 delete this.data_nodes;
511 //do we have to calculate the number of pages?
512 if(this.data && this.rows_per_page != -1)
515 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
516 this.current_page = 0;
519 //blank out the table.
522 //this is the table that we will be using.
523 var table = document.getElementById(this.my_table);
525 //is there a caption?
528 var caption = document.createElement("CAPTION");
529 caption.setAttribute("align", "top");
530 caption.appendChild(document.createTextNode(this.caption));
531 table.appendChild(caption);
534 //do the heading first
535 var table_header = document.createElement("THEAD");
536 var table_heading = document.createElement("TR");
537 //since this is a new table the first field is what's being sorted.
538 var curr_cell = document.createElement("TH");
539 var fn = new Function("", "nrsTables['" + this.my_table + "'].fieldSort(" + 0 + ");");
540 if(!this.disable_sorting || this.disable_sorting.indexOf(".0.") == -1)
541 curr_cell.onclick = fn;
542 if(this.header_color)
543 curr_cell.style.backgroundColor = this.header_color;
544 curr_cell.style.cursor = 'pointer';
545 var img = document.createElement("IMG");
546 img.setAttribute("src", this.up_icon);
547 img.setAttribute("border", "0");
548 img.setAttribute("height", "8");
549 img.setAttribute("width", "8");
550 curr_cell.appendChild(document.createTextNode(this.heading[0]));
551 curr_cell.appendChild(img);
552 table_heading.appendChild(curr_cell);
553 //now do the rest of the heading.
554 for(var i = 1; i < this.heading.length; i++)
556 curr_cell = document.createElement("TH");
557 var fn = new Function("", "nrsTables['" + this.my_table + "'].fieldSort(" + i + ");");
558 if(!this.disable_sorting || this.disable_sorting.indexOf("." + i + ".") == -1)
559 curr_cell.onclick = fn;
560 if(this.header_color)
561 curr_cell.style.backgroundColor = this.header_color;
562 curr_cell.style.cursor = 'pointer';
564 curr_cell.appendChild(document.createTextNode(this.heading[i]));
565 table_heading.appendChild(curr_cell);
567 table_header.appendChild(table_heading);
570 var table_body = document.createElement("TBODY");
571 this.createDataNodes();
574 if(this.natural_compare)
575 this.natSort(0, this.data.length - 1);
577 this.quickSort(0, this.data.length - 1);
581 //finally, the footer
582 var table_footer = document.createElement("TFOOT");
583 if(this.foot_headers)
585 table_footer.appendChild(table_heading.cloneNode(true));
588 if(this.page_nav && this.num_pages > 1)
590 //print out the page navigation
591 //first and previous page
592 var nav = document.createElement("TR");
593 var nav_cell = document.createElement("TH");
594 nav_cell.colSpan = this.heading.length;
596 var left = document.createElement("DIV");
597 if(document.attachEvent)
598 left.style.styleFloat = "left";
600 left.style.cssFloat = "left";
601 var img = document.createElement("IMG");
602 img.setAttribute("src", this.rew_icon);
603 img.setAttribute("border", "0");
604 img.setAttribute("height", "10");
605 img.setAttribute("width", "10");
606 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].firstPage();");
607 img.style.cursor = 'pointer';
608 left.appendChild(img);
609 //hack to space the arrows, cause IE is absolute crap
610 left.appendChild(document.createTextNode(" "));
611 img = document.createElement("IMG");
612 img.setAttribute("src", this.prev_icon);
613 img.setAttribute("border", "0");
614 img.setAttribute("height", "10");
615 img.setAttribute("width", "10");
616 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].prevPage();");
617 img.style.cursor = 'pointer';
618 left.appendChild(img);
619 //apend it to the cell
620 nav_cell.appendChild(left);
622 //next and last pages
623 var right = document.createElement("DIV");
624 if(document.attachEvent)
625 right.style.styleFloat = "right";
627 right.style.cssFloat = "right";
628 img = document.createElement("IMG");
629 img.setAttribute("src", this.next_icon);
630 img.setAttribute("border", "0");
631 img.setAttribute("height", "10");
632 img.setAttribute("width", "10");
633 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].nextPage();");
634 img.style.cursor = 'pointer';
635 right.appendChild(img);
636 //hack to space the arrows, cause IE is absolute crap
637 right.appendChild(document.createTextNode(" "));
638 img = document.createElement("IMG");
639 img.setAttribute("src", this.fwd_icon);
640 img.setAttribute("border", "0");
641 img.setAttribute("height", "10");
642 img.setAttribute("width", "10");
643 img.onclick = new Function("", "JavaScript:nrsTables['" + this.my_table + "'].lastPage();");
644 img.style.cursor = 'pointer';
645 right.appendChild(img);
646 //apend it to the cell
647 nav_cell.appendChild(right);
650 var pos = document.createElement("SPAN");
651 pos.setAttribute("id", "nav_pos");
652 pos.appendChild(document.createTextNode("Page " +
653 (this.current_page + 1) + " of " + this.num_pages));
654 //append it to the cell.
655 nav_cell.appendChild(pos);
657 nav.appendChild(nav_cell);
658 //append it to the footer
659 table_footer.appendChild(nav);
662 if(this.footer_color)
664 for(var i = 0; i < table_footer.childNodes.length; i++)
665 table_footer.childNodes[i].style.backgroundColor = this.footer_color;
669 table.appendChild(table_header);
670 table.appendChild(table_body);
671 table.appendChild(table_footer);
674 if(this.natural_compare)
675 this.natSort(0, this.data.length - 1);
677 this.quickSort(0, this.data.length - 1);
683 * This function will remove the elements in teh TBody section of the table and
684 * return an array of references of those elements. This array can then be
685 * sorted and re-inserted into the table.
686 * \return An array to references of the TBody contents.
688 nrsTable.prototype.extractElements = function()
690 var tbody = document.getElementById(this.my_table).tBodies[0];
691 var nodes = new Array();
693 while(tbody.childNodes.length > 0)
695 nodes[i] = tbody.removeChild(tbody.childNodes[0]);
702 * This function will re-insert an array of elements into the TBody of a table.
703 * Note that the array elements are stored in the this.data_nodes reference.
705 nrsTable.prototype.insertElements = function()
707 var tbody = document.getElementById(this.my_table).tBodies[0];
709 var num_elements = this.data_nodes.length;
710 if(this.rows_per_page != -1)
712 start = this.current_page * this.rows_per_page;
713 num_elements = (this.data_nodes.length - start) > this.rows_per_page?
714 this.rows_per_page + start:
715 this.data_nodes.length;
717 DEBUG("start is " + start + " and num_elements is " + num_elements);
718 for(var i = start; i < num_elements; i++)
720 tbody.appendChild(this.data_nodes[i]);
725 * This function will sort the table's data by a specific field. The field
726 * parameter referes to which field index should be sorted.
727 * \param field The field index which to sort on.
729 nrsTable.prototype.fieldSort = function(field)
731 if(this.field_to_sort == field)
733 //only need to reverse the array.
737 this.data_nodes.reverse();
739 //flip the arrow on the heading.
740 this.flipSortArrow();
744 //In this case, we need to sort the array. We'll sort it last, first
745 //make sure that the arrow images are set correctly.
746 this.moveSortArrow(field);
747 //finally, set the field to sort by.
748 this.field_to_sort = field;
751 //we'll be using our implementation of quicksort
752 if(this.natural_compare)
753 this.natSort(0, this.data.length - 1);
755 this.quickSort(0, this.data.length - 1);
758 //finally, we refresh the table.
763 * This function will refresh the data in the table. This function should be
764 * used whenever the nodes have changed, or when chanign pages. Note that
765 * this will NOT re-sort.
767 nrsTable.prototype.refreshTable = function()
769 this.extractElements();
771 this.insertElements();
772 //finally, if there is a nav, upate it.
777 * This function will advance a page. If we are already at the last page, then
778 * it will remain there.
780 nrsTable.prototype.nextPage = function()
782 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
783 if(this.current_page + 1 != this.num_pages)
788 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
792 * This function will go back a page. If we are already at the first page, then
793 * it will remain there.
795 nrsTable.prototype.prevPage = function()
797 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
798 if(this.current_page != 0)
803 DEBUG("current page is " + this.current_page + " and num_pages is " + this.num_pages);
807 * This function will go to the first page.
809 nrsTable.prototype.firstPage = function()
811 if(this.current_page != 0)
813 this.current_page = 0;
819 * This function will go to the last page.
821 nrsTable.prototype.lastPage = function()
823 DEBUG("lastPage(), current_page: " + this.current_page + " and num_pages: " + this.num_pages);
824 if(this.current_page != (this.num_pages - 1))
826 this.current_page = this.num_pages - 1;
832 * This function will go to a specific page. valid values are pages 1 to
833 * however many number of pages there are.
834 * \param page The page number to go to.
836 nrsTable.prototype.gotoPage = function(page)
839 if(page >=0 && page < this.num_pages)
841 this.current_page = page;
847 * This function can be used to change the number of entries per row displayed
849 * \param entries The number of entries per page.
851 nrsTable.prototype.changeNumRows = function(entries)
855 this.rows_per_page = entries;
857 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
863 * This function will take in a new data array and , optionally, a new cell_link
864 * array OR a new row_link array. Only one will be used, with the cell_link
865 * array taking precedence. It will then re-build the table with the new data
867 * \param new_data This is the new data array. This is required.
868 * \param cell_links This is the new cell links array, a 2D array for each cell.
869 * \param row_links This is the new row links array, a 1D array for each row.
871 nrsTable.prototype.newData = function(new_data, cell_links, row_links)
873 //extract the elements from teh table to clear the table.
874 this.extractElements();
875 //now delete all the data related to this table. I do this so that
876 //(hopefully) the memory will be freed. This is realy needed for IE, whose
877 //memory handling is almost non-existant
879 delete this.data_nodes;
880 delete this.cell_links;
881 delete this.row_links
883 this.data = new_data;
884 this.cell_links = cell_links;
885 this.row_links = row_links;
886 if(this.rows_per_page != -1)
889 this.num_pages = Math.ceil(this.data.length / this.rows_per_page);
890 if(this.num_pages <= 1 && this.page_nav)
892 else if(this.page_nav)
894 this.current_page = 0;
896 this.createDataNodes();
897 if(this.field_to_sort != 0)
898 this.moveSortArrow(0);
900 this.flipSortArrow();
901 this.insertElements();
906 * This function will remove the NAV bar (if one exists) from the table.
908 nrsTable.prototype.removeNav = function()
912 //in this case, remove the nav from the existing structure.
913 var table = document.getElementById(this.my_table);
915 if(this.foot_headers)
917 var nav = table.tFoot.childNodes[p];
920 table.tFoot.removeChild(nav);
927 * This function wil re-insert the nav into the table.
929 nrsTable.prototype.insertNav = function()
931 table = document.getElementById(this.my_table);
933 if(this.foot_headers)
935 if(this.page_nav && !table.tFoot.childNodes[p])
937 //this means there should be a nav and there isn't one.
938 //print out the page navigation
939 //first and previous page
940 var nav = document.createElement("TR");
941 var nav_cell = document.createElement("TH");
942 nav_cell.colSpan = this.heading.length;
944 var left = document.createElement("DIV");
945 if(document.attachEvent)
946 left.style.styleFloat = "left";
948 left.style.cssFloat = "left";
949 var img = document.createElement("IMG");
950 img.setAttribute("src", this.rew_icon);
951 img.setAttribute("border", "0");
952 img.setAttribute("height", "10");
953 img.setAttribute("width", "10");
954 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].firstPage();");
955 img.style.cursor = 'pointer';
956 left.appendChild(img);
957 //hack to space the arrows, cause IE is absolute crap
958 left.appendChild(document.createTextNode(" "));
959 img = document.createElement("IMG");
960 img.setAttribute("src", this.prev_icon);
961 img.setAttribute("border", "0");
962 img.setAttribute("height", "10");
963 img.setAttribute("width", "10");
964 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].prevPage();");
965 img.style.cursor = 'pointer';
966 left.appendChild(img);
967 //apend it to the cell
968 nav_cell.appendChild(left);
970 //next and last pages
971 var right = document.createElement("DIV");
972 if(document.attachEvent)
973 right.style.styleFloat = "right";
975 right.style.cssFloat = "right";
976 img = document.createElement("IMG");
977 img.setAttribute("src", this.next_icon);
978 img.setAttribute("border", "0");
979 img.setAttribute("height", "10");
980 img.setAttribute("width", "10");
981 img.onclick = new Function("", "nrsTables['" + this.my_table + "'].nextPage();");
982 img.style.cursor = 'pointer';
983 right.appendChild(img);
984 //hack to space the arrows, cause IE is absolute crap
985 right.appendChild(document.createTextNode(" "));
986 img = document.createElement("IMG");
987 img.setAttribute("src", this.fwd_icon);
988 img.setAttribute("border", "0");
989 img.setAttribute("height", "10");
990 img.setAttribute("width", "10");
991 img.onclick = new Function("", "JavaScript:nrsTables['" + this.my_table + "'].lastPage();");
992 img.style.cursor = 'pointer';
993 right.appendChild(img);
994 //apend it to the cell
995 nav_cell.appendChild(right);
998 var pos = document.createElement("SPAN");
999 pos.setAttribute("id", "nav_pos");
1000 pos.appendChild(document.createTextNode("Page " +
1001 (this.current_page + 1) + " of " + this.num_pages));
1002 //append it to the cell.
1003 nav_cell.appendChild(pos);
1005 nav.appendChild(nav_cell);
1006 //append it to the footer
1007 table.tFoot.appendChild(nav);
1012 * This function will hide the previous arrow and the rewind arrows from the
1015 nrsTable.prototype.hideLeftArrows = function()
1019 var myTable = document.getElementById(this.my_table);
1021 if(this.foot_headers)
1023 var nav = myTable.tFoot.childNodes[p];
1024 nav.childNodes[0].childNodes[0].style.display = "none";
1028 * This function will show the previous arrow and the rewind arrows from the
1031 nrsTable.prototype.showLeftArrows = function()
1035 table = document.getElementById(this.my_table);
1037 if(this.foot_headers)
1039 var nav = table.tFoot.childNodes[p];
1040 nav.childNodes[0].childNodes[0].style.display = "block";
1044 * This function will hide the next arrow and the fast foward arrows from the
1047 nrsTable.prototype.hideRightArrows = function()
1051 table = document.getElementById(this.my_table);
1053 if(this.foot_headers)
1055 var nav = table.tFoot.childNodes[p];
1056 nav.childNodes[0].childNodes[1].style.display = "none";
1060 * This function will show the next arrow and the fast foward arrows from the
1063 nrsTable.prototype.showRightArrows = function()
1067 table = document.getElementById(this.my_table);
1069 if(this.foot_headers)
1071 var nav = table.tFoot.childNodes[p];
1072 nav.childNodes[0].childNodes[1].style.display = "block";