.PHONY: tags
-########## make sync PLCHOST=hostname
+########## sync
+# 2 forms are supported
+# (*) if your plc root context has direct ssh access:
+# make sync PLC=private.one-lab.org
+# (*) otherwise, entering through the root context
+# make sync PLCHOST=testbox1.inria.fr GUEST=vplc03.inria.fr
+
+ifdef GUEST
ifdef PLCHOST
-PLCSSH:=root@$(PLCHOST)
+SSHURL:=root@$(PLCHOST):/vservers/$(GUEST)
+SSHCOMMAND:=ssh root@$(PLCHOST) vserver $(GUEST)
+endif
+endif
+ifdef PLC
+SSHURL:=root@$(PLC):/
+SSHCOMMAND:=ssh root@$(PLC)
endif
LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc'
RSYNC := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES)
sync:
-ifeq (,$(PLCSSH))
- echo "sync: You must define target host as PLCHOST on the command line"
- echo " e.g. make sync PLCHOST=private.one-lab.org" ; exit 1
+ifeq (,$(SSHURL))
+ @echo "sync: You must define, either PLC, or PLCHOST & GUEST, on the command line"
+ @echo " e.g. make sync PLC=private.one-lab.org"
+ @echo " or make sync PLCHOST=testbox1.inria.fr GUEST=vplc03.inria.fr"
+ @exit 1
else
- +$(RSYNC) planetlab modules $(PLCSSH):/plc/root/var/www/html/
+ +$(RSYNC) planetlab modules $(SSHURL)/var/www/html/
endif
+#################### convenience, for debugging only
+# make +foo : prints the value of $(foo)
+# make ++foo : idem but verbose, i.e. foo=$(foo)
+++%: varname=$(subst +,,$@)
+++%:
+ @echo "$(varname)=$($(varname))"
++%: varname=$(subst +,,$@)
++%:
+ @echo "$($(varname))"
$slice_item .= '<ul>';
if( $is_admin || $is_pi ) {
$slice_item .= "<li><a href='/db/slices/add_slice.php'>Create Slice</a></li>";
- $slice_item .= "<li><a href='/db/slices/attributes.php'>Attribute Types</a></li>";
}
if( !( $is_tech && ! $is_user && ! $is_pi && ! $is_admin ) )
$slice_item .= '<li><a href="/db/sirius/index.php">Sirius</a></li>';
$slice_item .= '</ul>';
$items [] = $slice_item;
+ if( $is_admin || $is_pi ) {
+ $tag_item = '';
+ $tag_item .= '<a href="/db/slices/tags.php?type=all">Tags</a>';
+ $tag_item .= '<ul>';
+ $tag_item .= "<li><a href='/db/slices/tags.php?type=node'>Node Tags</a></li>";
+ $tag_item .= "<li><a href='/db/slices/tags.php?type=interface'>Interface Tags</a></li>";
+ $tag_item .= "<li><a href='/db/slices/tags.php?type=slice'>Slice Tags</a></li>";
+ $tag_item .= '</ul>';
+ $items [] = $tag_item;
+ }
+
+
if ( $is_admin )
$items[] = l(t('Peers'),'db/peers/');
--- /dev/null
+/*
+ Add the following to your CSS file should you wish the cursor to
+ "wait" while the script is processing the sort
+
+body.sort-active *
+ {
+ cursor:wait;
+ }
+*/
+
+body
+ {
+ padding:0;
+ border:0;
+ margin:0;
+ text-align:center;
+ font-size:12px;
+ font-family: verdana,arial,sans-serif;
+ color:#545454;
+ min-width: 800px;
+ }
+h2 span
+ {
+ font-variant:small-caps;
+ }
+p a
+ {
+ font-weight:normal;
+ outline:none;
+ }
+p a:link,
+p a:visited
+ {
+ color:#333;
+ text-decoration:underline;
+ }
+p a:hover
+ {
+ color:#fff;
+ text-decoration:none;
+ background:#000;
+ }
+p a:active
+ {
+ color:#000;
+ text-decoration:underline;
+ }
+code
+ {
+ font-family:'andale mono','lucida console','courier new',monospace;
+ font-size:1em;
+ }
+p
+ {
+ line-height:1.6em;
+ margin:0 0 1em 0;
+ }
+h1
+ {
+ font-weight:lighter;
+ font-family:georgia, times new roman, times, georgia, palatino, serif;
+ text-align:center;
+ margin-top:0.6em;
+ color:#000;
+ font-size:2em;
+ }
+h2
+ {
+ font-weight:lighter;
+ font-family:verdana,arial,sans-serif;
+ text-align:center;
+ margin-top:1em;
+ color:#333;
+ text-transform:uppercase;
+ letter-spacing:1px;
+ font-size:1.2em;
+ }
+h2 span
+ {
+ font-variant:small-caps;
+ text-transform:none;
+ }
+table
+ {
+ width: auto;
+ padding: 0;
+ margin: 0 auto 1.5em auto;
+ border-left: 1px solid #C1DAD7;
+ border-collapse:collapse;
+ }
+.cs1
+ {
+ width:30em;
+ }
+.cs2
+ {
+ width:20em;
+ }
+.cs1 td,
+.cs2 td,
+#scientificNotation
+ {
+ text-align:right;
+ }
+caption
+ {
+ padding: 0 0 5px 0;
+ margin:0 auto;
+ width:auto;
+ font: italic 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ text-align: right;
+ }
+th
+ {
+ font: bold 10px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ color: #4f6b72;
+ border-right: 1px solid #C1DAD7;
+ border-bottom: 1px solid #C1DAD7;
+ border-top: 1px solid #C1DAD7;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ text-align: left;
+ padding: 8px 12px 4px 12px;
+ background: #CAE8EA url(../media/bg_header.jpg) no-repeat;
+ vertical-align:middle;
+ }
+td.total
+ {
+ border-top: 0;
+ border-left: 0;
+ border-right: 1px solid #C1DAD7;
+ background: none;
+ text-align:right;
+ font-weight:bold;
+ text-transform:uppercase;
+ letter-spacing:1px;
+ }
+th.sortable,
+th.sortable-text,
+th.sortable-date,
+th.sortable-keep,
+th.sortable-date-dmy,
+th.sortable-numeric,
+th.sortable-currency,
+th.sortable-sortByTwelveHourTimestamp,
+th.sortable-sortIPAddress,
+th.sortable-sortEnglishLonghandDateFormat,
+th.sortable-sortScientificNotation,
+th.sortable-sortImage,
+th.sortable-sortFileSize,
+th.sortable-sortAlphaNumeric,
+th.sortable-sortEnglishDateTime
+
+ {
+ cursor:pointer;
+ background: #CAE8EA url(../media/bg_header_sortable.jpg) no-repeat;
+ padding: 8px 12px 4px 16px;
+ }
+th.forwardSort
+ {
+ background:#CAE8EA url(../media/bg_header_down.jpg) no-repeat 0 0;
+ }
+th.reverseSort
+ {
+ background:#CAE8EA url(../media/bg_header_up.jpg) no-repeat 0 0;
+ }
+table thead th.forwardSort a,
+table thead th.reverseSort a
+ {
+ color:#000;
+ text-decoration:none;
+ }
+/*
+These styles should be added when very long tables are expected
+th.sort-active
+ {
+ background:#CAE8EA url(../media/bg_header_sorting.jpg) no-repeat 0 0;
+ cursor:wait;
+ }
+th.sort-active a
+ {
+ color:#a80000 !important;
+ cursor:wait;
+ }
+*/
+th a
+ {
+ text-decoration:none;
+ color: #4f6b72;
+ background:transparent;
+ }
+td a
+ {
+ text-decoration:none;
+ color:#239;
+ background:transparent;
+ }
+td img
+ {
+ margin:0 auto;
+ border:3px solid #ddd;
+ }
+td a:hover
+ {
+ color:#a84444;
+ border-bottom:1px dotted #a80000;
+ background:transparent;
+ }
+td
+ {
+ font: normal 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ border-right: 1px solid #C1DAD7;
+ border-bottom: 1px solid #C1DAD7;
+ padding: 6px 12px 6px 12px;
+ color: #4f6b72;
+ }
+td.lft
+ {
+ text-align:left;
+ }
+tr.alt
+ {
+ background: #F5FAFA;
+ color: #797268;
+ }
+
+/* Poor old Internet Explorer 6 has a bug that means we can't use background images for the table rows
+ as it trys to download the image each and every time that it is used (which means a 1000 row table
+ will produce 1000 http requests for the image in question) */
+tr[class="alt"] td
+ {
+ background: #F5FAFA url(../media/td_alt.jpg) no-repeat;
+ }
+td[class~="alt"]
+ {
+ background: #edf3f3 url(../media/col_alt.jpg) no-repeat !important;
+ }
+/* Poor old Internet Explorer won't see the next two rules either as it doesn't get :first-child */
+tbody tr.alt td:first-child
+ {
+ background: #F5FAFA url(../media/bullet2.gif) no-repeat;
+ font-weight:bold;
+ }
+tbody tr td:first-child
+ {
+ background: #fff url(../media/bullet1.gif) no-repeat;
+ font-weight:bold;
+ }
+/* Image free rules for Internet Explorer < 7 */
+* html tr.alt td
+ {
+ background-color:#F5FAFA;
+ }
+* html tr td.alt,
+* html tr.alt td.alt
+ {
+ background-color:#edf3f3;
+ }
--- /dev/null
+/*
+ Add the following to your CSS file should you wish the cursor to
+ "wait" while the script is processing the sort
+
+body.sort-active *
+ {
+ cursor:wait;
+ }
+*/
+
+body
+ {
+ padding:0;
+ border:0;
+ margin:0;
+ text-align:center;
+ font-size:12px;
+ font-family: verdana,arial,sans-serif;
+ color:#545454;
+ min-width: 800px;
+ }
+h2 span
+ {
+ font-variant:small-caps;
+ }
+p a
+ {
+ font-weight:normal;
+ outline:none;
+ }
+p a:link,
+p a:visited
+ {
+ color:#333;
+ text-decoration:underline;
+ }
+p a:hover
+ {
+ color:#fff;
+ text-decoration:none;
+ background:#000;
+ }
+p a:active
+ {
+ color:#000;
+ text-decoration:underline;
+ }
+code
+ {
+ font-family:'andale mono','lucida console','courier new',monospace;
+ font-size:1em;
+ }
+p
+ {
+ line-height:1.6em;
+ margin:0 0 1em 0;
+ }
+h1
+ {
+ font-weight:lighter;
+ font-family:georgia, times new roman, times, georgia, palatino, serif;
+ text-align:center;
+ margin-top:0.6em;
+ color:#000;
+ font-size:2em;
+ }
+h2
+ {
+ font-weight:lighter;
+ font-family:verdana,arial,sans-serif;
+ text-align:center;
+ margin-top:1em;
+ color:#333;
+ text-transform:uppercase;
+ letter-spacing:1px;
+ font-size:1.2em;
+ }
+h2 span
+ {
+ font-variant:small-caps;
+ text-transform:none;
+ }
+table
+ {
+ width: auto;
+ padding: 0;
+ margin: 0 auto 1.5em auto;
+ border-left: 1px solid #C1DAD7;
+ border-collapse:collapse;
+ }
+.cs1
+ {
+ width:30em;
+ }
+.cs2
+ {
+ width:20em;
+ }
+.cs1 td,
+.cs2 td,
+#scientificNotation
+ {
+ text-align:right;
+ }
+caption
+ {
+ padding: 0 0 5px 0;
+ margin:0 auto;
+ width:auto;
+ font: italic 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ text-align: right;
+ }
+th
+ {
+ font: bold 10px/22px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ color: #4f6b72;
+ border-right: 1px solid #C1DAD7;
+ border-bottom: 1px solid #C1DAD7;
+ border-top: 1px solid #C1DAD7;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ text-align: left;
+ padding: 8px 12px 4px 12px;
+ background: #CAE8EA url(../media/bg_header.jpg) no-repeat;
+ vertical-align:middle;
+ }
+td.total
+ {
+ border-top: 0;
+ border-left: 0;
+ border-right: 1px solid #C1DAD7;
+ background: none;
+ text-align:right;
+ font-weight:bold;
+ text-transform:uppercase;
+ letter-spacing:1px;
+ }
+th.sortable,
+th.sortable-text,
+th.sortable-date,
+th.sortable-keep,
+th.sortable-date-dmy,
+th.sortable-numeric,
+th.sortable-currency,
+th.sortable-sortByTwelveHourTimestamp,
+th.sortable-sortIPAddress,
+th.sortable-sortEnglishLonghandDateFormat,
+th.sortable-sortScientificNotation,
+th.sortable-sortImage,
+th.sortable-sortFileSize,
+th.sortable-sortAlphaNumeric,
+th.sortable-sortEnglishDateTime
+
+ {
+ cursor:pointer;
+ background: #CAE8EA url(../media/bg_header_sortable.jpg) no-repeat;
+ padding: 8px 12px 4px 16px;
+ }
+th.forwardSort
+ {
+ background:#CAE8EA url(../media/bg_header_down.jpg) no-repeat 0 0;
+ }
+th.reverseSort
+ {
+ background:#CAE8EA url(../media/bg_header_up.jpg) no-repeat 0 0;
+ }
+table thead th.forwardSort a,
+table thead th.reverseSort a
+ {
+ color:#000;
+ text-decoration:none;
+ }
+/*
+These styles should be added when very long tables are expected
+th.sort-active
+ {
+ background:#CAE8EA url(../media/bg_header_sorting.jpg) no-repeat 0 0;
+ cursor:wait;
+ }
+th.sort-active a
+ {
+ color:#a80000 !important;
+ cursor:wait;
+ }
+*/
+th a
+ {
+ text-decoration:none;
+ color: #4f6b72;
+ background:transparent;
+ }
+td a
+ {
+ text-decoration:none;
+ color:#239;
+ background:transparent;
+ }
+td img
+ {
+ margin:0 auto;
+ border:3px solid #ddd;
+ }
+td a:hover
+ {
+ color:#a84444;
+ border-bottom:1px dotted #a80000;
+ background:transparent;
+ }
+td
+ {
+ font: normal 11px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ border-right: 1px solid #C1DAD7;
+ border-bottom: 1px solid #C1DAD7;
+ padding: 6px 12px 6px 12px;
+ color: #4f6b72;
+ }
+td.lft
+ {
+ text-align:left;
+ }
+tr.alt
+ {
+ background: #F5FAFA;
+ color: #797268;
+ }
+
+/* Poor old Internet Explorer 6 has a bug that means we can't use background images for the table rows
+ as it trys to download the image each and every time that it is used (which means a 1000 row table
+ will produce 1000 http requests for the image in question) */
+tr[class="alt"] td
+ {
+ background: #F5FAFA url(../media/td_alt.jpg) no-repeat;
+ }
+td[class~="alt"]
+ {
+ background: #edf3f3 url(../media/col_alt.jpg) no-repeat !important;
+ }
+/* Poor old Internet Explorer won't see the next two rules either as it doesn't get :first-child */
+tbody tr.alt td:first-child
+ {
+ background: #F5FAFA url(../media/bullet2.gif) no-repeat;
+ font-weight:bold;
+ }
+tbody tr td:first-child
+ {
+ background: #fff url(../media/bullet1.gif) no-repeat;
+ font-weight:bold;
+ }
+/* Image free rules for Internet Explorer < 7 */
+* html tr.alt td
+ {
+ background-color:#F5FAFA;
+ }
+* html tr td.alt,
+* html tr.alt td.alt
+ {
+ background-color:#edf3f3;
+ }
} else {
- // // xxx this of any use at all ?
- // drupal_set_html_head('<script type="text/javascript" src="/planetlab/includes/js/bsn.Ajax.js"></script>
- // <script type="text/javascript" src="/planetlab/includes/js/bsn.DOM.js"></script>
- // <script type="text/javascript" src="/planetlab/includes/js/bsn.AutoSuggest.js"></script>');
-
// handle dates
list($from_date,$from_time,$until_date,$until_time) = parse_dates ();
if ( ($from_time != 0) && ($until_time != 0) && ($from_time > $until_time) ) {
// Mark Huang <mlhuang@cs.princeton.edu>
// Copyright (C) 2006 The Trustees of Princeton University
//
-// $Id: plc_drupal.php 144 2007-03-28 07:52:20Z thierry $ $
+// $Id$ $
//
if (!function_exists('drupal_set_title')) {
// Mark Huang <mlhuang@cs.princeton.edu>
// Copyright (C) 2006 The Trustees of Princeton University
//
-// $Id: plc_footer.php 144 2007-03-28 07:52:20Z thierry $ $
+// $Id$ $
//
require_once 'plc_drupal.php';
<?php
+// $Id$
+
function plc_person_link ($person_id) {
if ( empty ($person_id)) {
return "";
// attempt to normalize the delete buttons and confirmations
function plc_delete_button($width=15) {
- return '<span title="Delete this entry"><img width=' . $width . ' alt="Delete this entry" src="/planetlab/includes/delete.png"></span>';
+ return '<span title="Delete this entry"><img width=' . $width . ' alt="Delete this entry" src="/planetlab/icons/delete.png"></span>';
}
function plc_js_confirm($message) {
}
function plc_event_button($type,$param,$id) {
- return '<a href="/db/events/index.php?type=' . $type . '&' . $param . '=' . $id . '"> <span title="Related events"> <img src="/planetlab/includes/event.png" width=18></span></a>';
+ return '<a href="/db/events/index.php?type=' . $type . '&' . $param . '=' . $id . '"> <span title="Related events"> <img src="/planetlab/icons/event.png" width=18></span></a>';
}
function plc_comon_button ($field, $value,$target="") {
$result.='target="' . $target . '" ';
}
$result.='href="/db/nodes/comon.php?' . $field . "=" . $value . '">';
- $result.='<span title="Link to Comon"> <img src="/planetlab/includes/comon.png" width="18"></span></a>';
+ $result.='<span title="Link to Comon"> <img src="/planetlab/icons/comon.png" width="18"></span></a>';
return $result;
}
// Mark Huang <mlhuang@cs.princeton.edu>
// Copyright (C) 2006 The Trustees of Princeton University
//
-// $Id: plc_header.php 144 2007-03-28 07:52:20Z thierry $ $
+// $Id$ $
//
require_once 'plc_drupal.php';
-drupal_set_html_head('<link href="/planetlab/includes/plc_style.css" rel="stylesheet" type="text/css"/>');
+drupal_set_html_head('<link href="/planetlab/css/plc_style.css" rel="stylesheet" type="text/css"/>');
if (!function_exists('drupal_page_header')) {
$title = drupal_get_title();
// Mark Huang <mlhuang@cs.princeton.edu>
// Copyright (C) 2006 The Trustees of Princeton University
//
-// $Id: plc_login.php 144 2007-03-28 07:52:20Z thierry $ $
+// $Id$ $
//
require_once 'plc_session.php';
function addLoadEvent(func) {
- if (!document.getElementById | !document.getElementsByTagName) return
- var oldonload=window.onload
- if (typeof window.onload != 'function') { window.onload=func }
- else {
- window.onload=function() { oldonload(); func() }
- }
+ if (!document.getElementById | !document.getElementsByTagName) return;
+ var oldonload=window.onload
+ if (typeof window.onload != 'function') {
+ window.onload=func
+ } else {
+ window.onload=function() { oldonload(); func() }
+ }
}
// ----------------------------------------------------------------------------- //
-function show(id){
- if (!document.getElementsByTagName) return
- if (document.getElementById(id).style.display=='block'){
- document.getElementById(id).style.display='none'
- }
- else{
- document.getElementById(id).style.display='block'
- }
- // focus is moved by the href of the link to the start of the help
+function show (id) {
+ if (!document.getElementsByTagName) return;
+ if (document.getElementById(id).style.display=='block') {
+ document.getElementById(id).style.display='none';
+ } else{
+ document.getElementById(id).style.display='block';
+ }
+ // focus is moved by the href of the link to the start of the help
}
-
-function hide(id){
- if (document.getElementById) {document.getElementById(id).style.display='none'}
+function hide(id) {
+ if (document.getElementById) {
+ document.getElementById(id).style.display='none';
+ }
}
function copyValue (id1,id2) {
- if (document.getElementById) {document.getElementById(id2).value=document.getElementById(id1).value}
+ if (document.getElementById) {
+ document.getElementById(id2).value=document.getElementById(id1).value;
+ }
}
-
// ----------------------------------------------------------------------------- //
// Mark Huang <mlhuang@cs.princeton.edu>
// Copyright (C) 2006 The Trustees of Princeton University
//
-// $Id: plc_session.php 804 2007-08-31 13:58:58Z thierry $ $
+// $Id$ $
//
// Usually in /etc/planetlab/php
<?php
+// $Id$
+
// person sort on last name, first name, email
function __cmp_persons($a, $b) {
$persona = $a['last_name'] . $a['first_name'] . $a['email'];
return usort($persons, "__cmp_persons");
}
+function topdomain ($hostname) {
+ $exploded=array_reverse(explode(".",$hostname));
+ return $exploded[0];
+}
function __cmp_nodes($a, $b) {
$as = array_reverse(explode(".", $a['hostname']));
{
$success= 1;
- // add new node and its network
+ // add new node and its interface
$optional_vals= array( "hostname"=>$hostname, "model"=>$model );
$site_id= $_person['site_ids'][0];
$nodes=$api->GetNodes(array("node_id"=>array($node_id)),$fields);
} else if ($_GET['site_id']) {
$site_id=intval($_GET['site_id']);
- $nodes=$api->GetNodes(array("site_id"=>array($site_id)),$fields);
+ $nodes=$api->GetNodes(array("node_type"=>"regular","site_id"=>array($site_id)),$fields);
} else if ($_GET['slice_id']) {
$slice_id=intval($_GET['slice_id']);
$return=$api->GetSlices(array("slice_id"=>array($slice_id)),array("node_ids"));
$node_ids=$return[0]['node_ids'];
- $nodes=$api->GetNodes(array("node_id"=>$node_ids),$fields);
+ $nodes=$api->GetNodes(array("node_type"=>"regular","node_id"=>$node_ids),$fields);
} else if (isset($_GET['peer_id'])) {
$peer_id=intval($_GET['peer_id']);
if ( ($peer_id == 0) || ($peer_id == "") )
$peer_id=NULL;
- $nodes=$api->GetNodes(array("peer_id"=>$peer_id),$fields);
+ $nodes=$api->GetNodes(array("node_type"=>"regular","peer_id"=>$peer_id),$fields);
} else {
echo "<div class='plc-warning'> Unexpected args in comon.php </div>\n";
exit();
// The set of columns to fetch
// and the filter applied for fetching sites
$columns = array( "node_id", "hostname", "boot_state", "peer_id" ) ;
-$filter = array();
+$filter = array("node_type"=>"regular");
if ( in_array( '10', $_roles ) || in_array('20', $_roles) || in_array('40',$_roles)) {
// admins, PIs and techs can see interface details
$columns [] = "interface_ids";
$nodes = array_map(layout_node,$nodes);
sort_nodes( $nodes );
- drupal_set_html_head('<script type="text/javascript" src="/planetlab/includes/js/bsn.Ajax.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.DOM.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.AutoSuggest.js"></script>');
+ drupal_set_html_head('<script type="text/javascript" src="/planetlab/bsn/bsn.Ajax.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.DOM.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.AutoSuggest.js"></script>');
echo "<div>\n
<form method=get action='index.php'>\n";
if( !empty( $conf_file_ids ) )
$conf_files= $api->GetConfFiles( $conf_file_ids );
- // get node network info
+ // get interface info
if( !empty( $interface_ids ) )
$interfaces= $api->GetInterfaces( $interface_ids );
echo "<hr />\n";
- // display node networks
+ // display interfaces
if( $interfaces ) {
echo "<p><table class='list_set' border=0 cellpadding=2>\n";
- echo "<caption class='list_set'>Node Networks</caption>\n";
+ echo "<caption class='list_set'>Interfaces</caption>\n";
echo "<thead><tr class='list_set'>";
// placeholder for the delete buttons
if ( $is_admin || ($is_pi && $in_site)) {
if ( $is_admin || ($is_pi && $in_site)) {
echo "<td class='list_set'>";
if (!$nn_primary) {
- echo plc_delete_link_button('interfaces.php?id=' . $nn_id . '&delete=1&submitted=1', '\\nNode Network ' . $nn_ip);
+ echo plc_delete_link_button('interfaces.php?id=' . $nn_id . '&delete=1&submitted=1', '\\nInterface ' . $nn_ip);
} else {
- echo '<span title="This node network is primary"> P </span>';
+ echo '<span title="This interface is primary"> P </span>';
}
echo "</td>";
}
echo "</tbody></table>\n";
} else {
- echo "<p><span class='plc-warning'>No Node Network</span>. Please add a node network to make this a usable PLC node</p>.\n";
+ echo "<p><span class='plc-warning'>No interface</span>. Please add an interface to make this a usable PLC node</p>.\n";
}
- echo "<br /><a href='interfaces.php?node_id=$node_id'>Add a node network</a>.\n";
+ echo "<br /><a href='interfaces.php?node_id=$node_id'>Add an interface</a>.\n";
echo "<br /><hr />\n";
}
</form>
EOF;
-// displays related settings, if supported by the API
-if (method_exists ($api,'GetInterfaceTags')) {
-
- $is_admin=in_array( 10, $_roles );
- $is_pi=in_array( 20, $_roles );
- print "<hr />";
-
- if (empty ($interface['interface_tag_ids'])) {
- print "<p> This network interface has no additional setting</p>";
- if( $is_admin || $is_pi )
- echo "<p><a href='settings.php?add=$id'>Add a Network Setting</a></p>\n";
- } else {
- $interface_tags = $api->GetInterfaceTags($interface['interface_tag_ids']);
- sort_interface_tags ($interface_tags);
- print "<table cellpadding='5' cellspacing='5' class='list_set'><caption class='list_set'>Additional Settings</caption>";
- print "<thead><tr class='list_set'>";
- // the column for the delete button
- if( $is_admin )
- print "<th></th>";
- print "<th class='list_set'>Name</th><th class='list_set'>Category</th><th class='list_set'>Description</th><th class='list_set'>Value</th></tr></thead><tbody>";
- foreach ($interface_tags as $setting) {
- echo "<tr class='list_set'>";
- if ($is_admin) {
- echo("<td>");
- echo plc_delete_link_button('setting_action.php?rem_id=' . $setting['interface_tag_id'],
- '\\n [ ' . $setting['name'] . ' = ' . $setting['value']);
- echo("</td>");
+$is_admin=in_array( 10, $_roles );
+$is_pi=in_array( 20, $_roles );
+print "<hr />";
+
+if (empty ($interface['interface_tag_ids'])) {
+ print "<p> This network interface has no additional setting</p>";
+ if( $is_admin || $is_pi )
+ echo "<p><a href='settings.php?add=$id'>Add an Interface Setting</a></p>\n";
+ } else {
+ $interface_tags = $api->GetInterfaceTags($interface['interface_tag_ids']);
+ sort_interface_tags ($interface_tags);
+ print "<table cellpadding='5' cellspacing='5' class='list_set'><caption class='list_set'>Additional Settings</caption>";
+ print "<thead><tr class='list_set'>";
+ // the column for the delete button
+ if( $is_admin )
+ print "<th></th>";
+ print "<th class='list_set'>Name</th><th class='list_set'>Category</th><th class='list_set'>Description</th><th class='list_set'>Value</th></tr></thead><tbody>";
+ foreach ($interface_tags as $setting) {
+ echo "<tr class='list_set'>";
+ if ($is_admin) {
+ echo("<td>");
+ echo plc_delete_link_button('setting_action.php?rem_id=' . $setting['interface_tag_id'],
+ '\\n [ ' . $setting['tagname'] . ' = ' . $setting['value']);
+ echo("</td>");
}
- if ($is_admin || $is_pi)
- printf ("<td class='list_set'> <a href='settings.php?id=%s'>%s </a></td>",$setting['interface_tag_id'],$setting['name']);
- else
- printf ("<td class='list_set'> %s </td>",$setting['name']);
- printf ("<td class='list_set'> %s</td><td class='list_set'> %s</td><td class='list_set'> %s </td></tr>",
- $setting['category'],
- $setting['description'],
- $setting['value']);
- }
- if( $is_admin || $is_pi )
- echo "<tr><td colspan=4><a href='settings.php?add=$id'>Add a Network Setting</td</tr>\n";
-
- print "</tbody></table>";
+ if ($is_admin || $is_pi)
+ printf ("<td class='list_set'> <a href='settings.php?id=%s'>%s </a></td>",$setting['interface_tag_id'],$setting['tagname']);
+ else
+ printf ("<td class='list_set'> %s </td>",$setting['tagname']);
+ printf ("<td class='list_set'> %s</td><td class='list_set'> %s</td><td class='list_set'> %s </td></tr>",
+ $setting['category'],
+ $setting['description'],
+ $setting['value']);
}
+ if( $is_admin || $is_pi )
+ echo "<tr><td colspan=4><a href='settings.php?add=$id'>Add a Network Setting</td</tr>\n";
+
+ print "</tbody></table>";
}
echo <<<EOF
--- /dev/null
+<?php
+
+// $Id: index.php 1175 2008-02-07 16:20:15Z thierry $
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api, $adm;
+
+// Print header
+require_once 'plc_drupal.php';
+drupal_set_title('New Nodes');
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+
+// find person roles
+$_person= $plc->person;
+$_roles= $_person['role_ids'];
+
+$header_js='
+<script type="text/javascript" src="/planetlab/tablesort/tablesort.js"></script>
+<script type="text/javascript" src="/planetlab/tablesort/customsort.js"></script>
+<script type="text/javascript" src="/planetlab/tablesort/paginate.js"></script>
+<script type="text/javascript" src="/planetlab/tablesort/more.js"></script>
+<body OnLoad="init();">
+';
+$header_css='
+<link href="/planetlab/css/demo.css" rel="stylesheet" type="text/css" />
+<link href="/planetlab/css/more.css" rel="stylesheet" type="text/css" />
+<!--[if IE]>
+<style type="text/css">
+ul.fdtablePaginater {display:inline-block;}
+mul.fdtablePaginater {display:inline;}
+ul.fdtablePaginater li {float:left;}
+ul.fdtablePaginater {text-align:center;}
+table { border-bottom:1px solid #C1DAD7; }
+</style>
+<![endif]-->
+';
+
+$header_unused='
+';
+
+drupal_set_html_head($header_js);
+drupal_set_html_head($header_css);
+
+$site_columns=array("site_id","login_base");
+$site_filter=array("login_base"=>"*");
+$sites=$api->GetSites($site_filter,$site_columns);
+
+$site_hash=array();
+foreach ($sites as $site) {
+ $site_hash[$site["site_id"]]=$site;
+}
+
+$node_columns=array("hostname","site_id","node_id","boot_state");
+$node_filter=array("hostname"=>"*");
+$nodes=$api->GetNodes($node_filter,$node_columns);
+
+$interface_columns=array("ip","node_id");
+$interface_filter=array("is_primary"=>TRUE);
+$interfaces=$api->GetInterfaces($interface_filter,$interface_columns);
+
+$interface_hash=array();
+foreach ($interfaces as $interface) {
+ $interface_hash[$interface['node_id']]=$interface;
+}
+
+?>
+
+<table id="theTable" cellpadding="0" cellspacing="0" border="0"
+class="sortable-onload-2 rowstyle-alt colstyle-alt no-arrow paginate-50 max-pages-10">
+<thead>
+<tr>
+<th align=top>Select </th>
+<th class="sortable">State</th>
+<th class="sortable">Hostname</th>
+<th class="sortable">Site</th>
+<th class="sortable">Region</th>
+<th class="sortable-sortIPAddress">IP</th>
+<th class="sortable">Load</th>
+<th class="sortable">Avg Load</th>
+</tr>
+</thead>
+<tbody>
+
+<?php
+
+foreach ($nodes as $node) {
+ $hostname=$node['hostname'];
+ $site=$site_hash[$node['site_id']];
+ $login_base = $site['login_base'];
+ $node_id=$node['node_id'];
+ $ip=$interface_hash[$node['node_id']]['ip'];
+ printf ('<tr id="%s">',$hostname);
+ printf ('<td> <input type="checkbox" id="%s"></td>',$hostname);
+ printf ('<td> %s </td>',$node['boot_state']);
+ printf ('<td> %s </td>',$hostname);
+ printf ('<td> %s </td>',$login_base);
+ printf ('<td> %s </td>',topdomain($hostname));
+ printf ('<td> %s </td>',$ip);
+ printf ('<td> 1.0 </td>');
+ printf ('<td> 10.0 </td>');
+ printf ( '</tr>');
+}
+
+?>
+</tbody>
+<tfoot>
+</tfoot>
+</table>
+
go into debug mode.
<p>In order to create a configuration file for this node using this page,
-all the node network settings must be up to date. Below is summary of these
+all the interface settings must be up to date. Below is summary of these
values. Any missing values must be entered before this can be used.
EOF;
show_download_confirm_button($api, $node_id, $action, $can_gen_config, false);
print ("<p>");
- print ("<h3>Current node network settings</h3>\n");
+ print ("<h3>Current interface settings</h3>\n");
if( $has_primary ) {
print( "<table border=\"0\" cellspacing=\"4\">\n" );
print( "<td>" . $node_detail['hostname'] . "</td></tr>\n" );
$nn_id = $interface_detail['interface_id'];
- print( "<tr><th colspan=2><a href='interfaces.php?id=$nn_id'>Node Network Details</a></th></tr>" );
+ print( "<tr><th colspan=2><a href='interfaces.php?id=$nn_id'>Interface Details</a></th></tr>" );
print( "<tr><th>Method:</th>" );
print( "<td>" . $interface_detail['method'] . "</td></tr>\n" );
$settings=$api->GetInterfaceTags(array("interface_id" => array($nn_id)));
foreach ($settings as $setting) {
$category=$setting['category'];
- $name=$setting['name'];
+ $name=$setting['tagname'];
$value=$setting['value'];
print (" <tr><th> $category $name </th><td> $value </td></tr>\n");
}
print( "</table>\n" );
} else {
- print( "<p class='plc-warning'>This node has no configured primary network.</p>\n" );
+ print( "<p class='plc-warning'>This node has no configured primary interface.</p>\n" );
}
show_download_confirm_button($api, $node_id, $action, $can_gen_config, true);
elseif( $_GET['id'] ) {
$nodegroup_id= $_GET['id'];
- $nodegroup_info= $api->GetNodeGroups( array( intval( $nodegroup_id ) ), array( "name", "nodegroup_id", "node_ids" ) );
+ $nodegroup_info= $api->GetNodeGroups( array( intval( $nodegroup_id ) ),
+ array( "name", "nodegroup_id", "node_ids" ) );
$node_info= $api->GetNodes( $nodegroup_info[0]['node_ids'], array( "node_id", "hostname" ) );
//display info
$api->UpdateNodeGroup( intval( $node_group_id ), $fields );
// get node_group info
- $group_info= $api->GetNodeGroups( array( intval( $node_group_id ) ), array( "node_ids", "name", "conf_file_ids", "description" ) );
+ $group_info= $api->GetNodeGroups( array( intval( $node_group_id ) ),
+ array( "node_ids", "name", "conf_file_ids", "description" ) );
$node_ids = $group_info[0]['node_ids'];
$name = $group_info[0]['name'];
// get node info
if( !empty( $node_ids ) )
- $node_info= $api->GetNodes( $node_ids, array( "hostname", "node_id" ) );
+ $node_info= $api->GetNodes( $node_ids,
+ array( "hostname", "node_id" ) );
// get site names and ids
$site_info= $api->GetSites( NULL, array( "site_id", "name" ) );
//plc_debug('GET',$_GET);
//plc_debug('POST',$_POST);
-// attribute type updates
+// tag type updates
if( $_POST['edit_type'] ) {
$setting_type_id= intval( $_POST['interface_tag_type_id'] );
$setting_type = array ('category' => $_POST['category'],
exit();
}
-// attribute type adds
+// tag type adds
if( $_POST['add_type'] ) {
$setting_type = array ('category' => $_POST['category'],
'name' => $_POST['name'],
}
-// attribute deletion
+// tag deletion
if( $_GET['rem_id'] ) {
- // get the id of the attrib to remove from GET
+ // get the id of the tag to remove from GET
$setting_id= intval( $_GET['rem_id'] );
// get interface_id
$setting= $api->GetInterfaceTags( array( $setting_id ), array( "interface_id" ) );
$interface_id= $setting[0]['interface_id'];
- // delete the attribute
+ // delete the tag
$api->DeleteInterfaceTag( $setting_id );
header( "location: interfaces.php?id=$interface_id" );
exit();
}
-// attribute adds
+// tag adds
if( $_POST['add_setting'] ) {
- // get the interface_id, attribute_type_id, and value from POST
+ // get the interface_id, tag_type_id, and value from POST
$interface_id= intval( $_POST['interface_id'] );
$interface_tag_type_id= intval( $_POST['interface_tag_type_id'] );
$value= $_POST['value'];
exit();
}
-// attribute updates
+// tag updates
if( $_POST['edit_setting'] ) {
// get the id of the setting to update and the value from POST
$setting_id= intval( $_POST['setting_id'] );
exit();
}
-// down here is some code from attrib_action.php that was not converted yet
// Settings -------------------------------------------------
-// ATTRIBUTE TYPES ---------------------------------------------------
+// TAG TYPES ---------------------------------------------------
-// delete attribute types
+// delete tag types
if( $_GET['del_type'] ) {
// get vars
$type_id= intval( $_GET['del_type'] );
header( "location: settings.php" );
exit();
}
-
-
/*
// Print footer
//plc_debug("person", $_person );
-$columns=array( "interface_tag_type_id", "category", "name", "description", "min_role_id" );
+$columns=array( "tag_type_id", "category", "tagname", "description", "min_role_id" );
// prepare dict role_id => role_name
global $roles;
return $setting_type;
}
-// if no id, display list of attributes types
+// if no id, display list of tag types
if( !$_GET['id'] && !$_GET['add'] && !$_GET['add_type'] && !$_GET['edit_type'] ) {
// get types
global $person_role;
- $filter = array (']min_role_id'=>$person_role);
+ $filter = array (']min_role_id'=>$person_role,'category'=>'interface*');
$setting_types= $api->GetTagTypes( $filter, $columns );
$setting_types = array_map(layout_setting_type,$setting_types);
sort_interface_tags ($setting_types);
// if admin display delete links
if( in_array( "10", $_person['role_ids'] ) ) {
echo "<td>";
- echo plc_delete_link_button('setting_action.php?del_type='. $type['interface_tag_type_id'],
- $type['name']);
+ echo plc_delete_link_button('setting_action.php?del_type='. $type['tag_type_id'],
+ $type['tagname']);
echo "</td>";
}
// if admin, the name is a link to edition
if (in_array( "10", $_person['role_ids'])) {
- echo "<td><a href='settings.php?edit_type=". $type['interface_tag_type_id'] . "'>" . $type['name'] . "</a></td>";
+ echo "<td><a href='settings.php?edit_type=". $type['tag_type_id'] . "'>" . $type['tagname'] . "</a></td>";
} else {
- echo "<td>" . $type['name'] . "</td>";
+ echo "<td>" . $type['tagname'] . "</td>";
}
echo "<td>" . $type['category'] . "</td>";
echo "<td>" . $type['min_role'] . "</td><td>" . $type['min_role_id'] . "</td><td>" . $type['description'] . "</td>";
}
elseif( $_GET['add_type'] || $_GET['edit_type'] ) {
- // if its edit get the attribute info
+ // if its edit get the tag info
if( $_GET['edit_type'] ) {
$type_id= intval( $_GET['edit_type'] );
$type= $api->GetTagTypes( array( $type_id ) );
$category=$type[0]['category'];
- $name= $type[0]['name'];
+ $name= $type[0]['tagname'];
$min_role_id= $type[0]['min_role_id'];
$description= $type[0]['description'];
echo "</td></tr>\n";
echo "<tr><td colspan=2 align=center>";
if( $_GET['edit_type'] ) {
- echo "<input type=hidden name='interface_tag_type_id' value='$type_id'>\n";
+ echo "<input type=hidden name='tag_type_id' value='$type_id'>\n";
echo "<input type=submit name='edit_type' value='Edit Setting Type'>\n";
} else {
echo "<input type=submit name='add_type' value='Add Interface Type'>\n";
// get all setting types
global $person_role;
- $filter = array (']min_role_id'=>$person_role);
- $setting_types= $api->GetTagTypes( $filter, array( "interface_tag_type_id", "name" , "category") );
+ $filter = array (']min_role_id'=>$person_role,'category'=>'interface*');
+ $setting_types= $api->GetTagTypes( $filter, array( "tag_type_id", "tagname" , "category") );
sort_interface_tags($setting_types);
// get interface's settings
echo "<table cellpadding='2'> <caption> New Setting </caption>";
- echo "<tr><th>Select</th><td><select name='interface_tag_type_id'><option value=''>Choose a type to add</option>\n";
+ echo "<tr><th>Select</th><td><select name='tag_type_id'><option value=''>Choose a type to add</option>\n";
foreach( $setting_types as $setting_type ) {
- echo "<option value='". $setting_type['interface_tag_type_id'] ."'>". $setting_type['category'] . ":" . $setting_type['name'] ."</option>\n";
+ echo "<option value='". $setting_type['tag_type_id'] ."'>". $setting_type['category'] . ":" . $setting_type['tagname'] ."</option>\n";
}
echo "</select></td</tr>\n";
// interface info
$interface= $api->GetInterfaces( array( $setting[0]['interface_id'] ), array( "ip" ) );
- drupal_set_title("Edit setting ". $setting[0]['name'] ." on ". $interface[0]['ip']);
+ drupal_set_title("Edit setting ". $setting[0]['tagname'] ." on ". $interface[0]['ip']);
// start form and put values in to be edited.
echo "<form action='setting_action.php' method='post'>\n";
echo "<table cellpadding='2'> <caption> Edit Setting </caption>";
echo "<tr><th> Category </th> <td>" . $setting[0]['category'] . "</td></tr>";
- echo "<tr><th> Name </th> <td>" . $setting[0]['name'] . "</td></tr>";
+ echo "<tr><th> Name </th> <td>" . $setting[0]['tagname'] . "</td></tr>";
echo "<tr><th> Value </th> <td><input type=text name='value' value='" . $setting[0]['value'] . "'> </td></tr>";
echo "<tr><td colspan=2> <input type=submit value='Edit Setting' name='edit_setting'></td></tr>";
echo "</table>";
if( !empty( $_POST['add_sub'] ) ) {
- $attrib_type= $_POST['sliver'];
+ $tag_type= $_POST['sliver'];
$value= $_POST['value'];
$node_id= $_POST['node_id'];
$slice_id= $_POST['slice_id'];
- $api->AddSliceTag( intval( $slice_id ), intval( $attrib_type ), $value, intval( $node_id ) );
+ $api->AddSliceTag( intval( $slice_id ), intval( $tag_type ), $value, intval( $node_id ) );
header( "location: slivers.php?slice=$slice_id&node=$node_id" );
exit();
//
if( $_GET['rem_id'] ) {
- $attrib_id= $_GET['rem_id'];
+ $tag_id= $_GET['rem_id'];
// get the slivers for this node
- $sliver_info= $api->GetSliceTags( array( "slice_tag_id"=>intval( $attrib_id ) ), array( "slice_id", "node_id" ) );
+ $sliver_info= $api->GetSliceTags( array( "slice_tag_id"=>intval( $tag_id ) ), array( "slice_id", "node_id" ) );
- $api->DeleteSliceTag( intval( $attrib_id ) );
+ $api->DeleteSliceTag( intval( $tag_id ) );
header( "location: slivers.php?slice=". $sliver_info[0]['slice_id'] ."&node=". $sliver_info[0]['node_id'] );
exit();
// node info
$node_info= $api->GetNodes( array( intval( $node_id ) ), array( "hostname" ) );
- // get attribute types
- $type_info= $api->GetSliceTagTypes( NULL, array( "attribute_type_id", "name" ) );
+ // get tag types
+ $type_info= $api->GetTagTypes( NULL, array( "tag_type_id", "tagname" ) );
// get the slivers for this node
- $sliver_info= $api->GetSliceTags( array( "node_id"=>intval( $node_id ), "slice_id"=>intval( $slice_id ) ), array( "attribute_type_id", "name" ) );
+ $sliver_info= $api->GetSliceTags( array( "node_id"=>intval( $node_id ), "slice_id"=>intval( $slice_id ) ), array( "tag_type_id", "name" ) );
$types_left= $type_info;
// start form
echo "<form action='sliver_action.php' method=post>\n
- <h2>Add a Sliver Attribute to ". $slice_info[0]['name'] ." on node ". $node_info[0]['hostname'] ."</h2>\n
+ <h2>Add a Sliver Tag to ". $slice_info[0]['name'] ." on node ". $node_info[0]['hostname'] ."</h2>\n
<table class='list_set' border=0 cellpadding=2><tbody>\n
- <tr class='list_set'><th class='list_set'>Attribute: </th><td class='list_set'><select name='sliver'>\n";
+ <tr class='list_set'><th class='list_set'>Tag: </th><td class='list_set'><select name='sliver'>\n";
foreach( $types_left as $type ) {
- echo "<option value='". $type['attribute_type_id'] ."'>". $type['name'] ."</option>\n";
+ echo "<option value='". $type['tag_type_id'] ."'>". $type['name'] ."</option>\n";
}
<tr class='list_set'><th class='list_set'>Value: </th><td class='list_set'><input type=text name='value'></td></tr>\n
</tbody></table>\n
<input type=hidden name='node_id' value='$node_id'><input type=hidden name='slice_id' value='$slice_id'>
- <p><input type=submit name='add_sub' value='Add Sliver Attribute'>\n";
+ <p><input type=submit name='add_sub' value='Add Sliver Tag'>\n";
echo "<p><a href='index.php?id=$node_id'>Back to Node</a>\n</form>\n";
}
-// if slice and node ids are passed display slivers and attribs
+// if slice and node ids are passed display slivers and tags
if( $_GET['slice'] && $_GET['node'] ) {
$slice_id= $_GET['slice'];
$node_id= $_GET['node'];
$sliver_info= $api->GetSliceTags( array( "node_id"=>intval( $node_id ), "slice_id"=>intval( $slice_id ) ), array( "slice_tag_id", "name", "value", "min_role_id", "description" ) );
// get the attrbibutes for this slice
- $attrib_info= $api->GetSliceTags( array( intval( $slice_id ) ), array( "slice_tag_id", "name", "value", "min_role_id", "description" ) );
+ $tag_info= $api->GetSliceTags( array( intval( $slice_id ) ), array( "slice_tag_id", "name", "value", "min_role_id", "description" ) );
// start form
echo "<form action='slivers.php' method=post>\n<h2>Sliver Details for slice ". $slice_info[0]['name'] ." on node ". $node_info[0]['hostname'] ."</h2>\n";
- // sliver attributes of slice
+ // sliver tags of slice
if( empty( $sliver_info ) )
// if no sliver exists tell user
- echo "No sliver attribute for this node/slice sliver combination.\n";
+ echo "No sliver tag for this node/slice sliver combination.\n";
else {
echo "<p><table class='list_set' border=0 cellpadding=2>\n<caption class='list_set'>Slivers</caption>\n<thead><tr class='list_set'><th class='list_set'>Name</th><th class='list_set'>Value</th><th class='list_set'>Min Roll</th><th class='list_set'>Description</th>";
if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<th></th><th></th>";
foreach( $sliver_info AS $sliver ) {
echo "<tr><td>". $sliver['name'] ."</td><td>". $sliver['value'] ."</td><td>". $sliver['min_role_id'] ."</td><td>". $sliver['description'] ."</td>";
- if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<td><a href='/db/slices/attributes.php?id=". $sliver['slice_tag_id'] ."'>Edit</a></td><td><a href='sliver_action.php?rem_id=". $sliver['slice_tag_id'] ."' onclick=\"javascript:return confirm('Are you sure you want to remove ". $sliver['name'] ." from node ". $node_info[0]['hostname'] ."?')\">Remove</a></td>";
+ if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<td><a href='/db/slices/tags.php?type=slice&id=". $sliver['slice_tag_id'] ."'>Edit</a></td><td><a href='sliver_action.php?rem_id=". $sliver['slice_tag_id'] ."' onclick=\"javascript:return confirm('Are you sure you want to remove ". $sliver['name'] ." from node ". $node_info[0]['hostname'] ."?')\">Remove</a></td>";
echo "</tr>\n";
}
- if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<p><a href='slivers.php?add=$node_id&slice=$slice_id'>Add Sliver Attribute</a>\n";
+ if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<p><a href='slivers.php?add=$node_id&slice=$slice_id'>Add Sliver Tag</a>\n";
echo "<br /><hr />";
- // regular attributes of slice
- if( empty( $attrib_info ) )
- // if no attributes exist tell user
- echo "No Attributes for this slice.\n";
+ // regular tags of slice
+ if( empty( $tag_info ) )
+ // if no tags exist tell user
+ echo "No Tags for this slice.\n";
else {
- echo "<p><table class='list_set' border=0 cellpadding=2>\n<caption class='list_set'>Attributes</caption>\n<thead><tr class='list_set'><th class='list_set'>Name</th><th class='list_set'>Value</th><th class='list_set'>Min Roll</th><th class='list_set'>Description</th>";
+ echo "<p><table class='list_set' border=0 cellpadding=2>\n<caption class='list_set'>Tags</caption>\n<thead><tr class='list_set'><th class='list_set'>Name</th><th class='list_set'>Value</th><th class='list_set'>Min Roll</th><th class='list_set'>Description</th>";
if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<th></th>";
echo "</tr></thead><tbody>\n";
- foreach( $attrib_info AS $attrib ) {
- echo "<tr><td>". $attrib['name'] ."</td><td>". $attrib['value'] ."</td><td>". $attrib['min_role_id'] ."</td><td>". $attrib['description'] ."</td>";
- if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<td><a href='attributes.php?id=". $attrib['slice_tag_id'] ."'>Edit</a></td>";
+ foreach( $tag_info AS $tag ) {
+ echo "<tr><td>". $tag['name'] ."</td><td>". $tag['value'] ."</td><td>". $tag['min_role_id'] ."</td><td>". $tag['description'] ."</td>";
+ if ( in_array( 10, $_roles ) || ( in_array( 20, $_roles ) && in_array( $node_info, $_person['site_ids'] ) ) ) echo "<td><a href='tags.php?type=slice&id=". $tag['slice_tag_id'] ."'>Edit</a></td>";
echo "</tr>\n";
$persons= array_map(layout_person,$persons);
sort_persons( $persons );
- drupal_set_html_head('<script type="text/javascript" src="/planetlab/includes/js/bsn.Ajax.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.DOM.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.AutoSuggest.js"></script>');
+ drupal_set_html_head('<script type="text/javascript" src="/planetlab/bsn/bsn.Ajax.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.DOM.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.AutoSuggest.js"></script>');
echo "<div>\n
<form method=get action='index.php'>\n";
} else {
sort_sites( $sites );
- drupal_set_html_head('<script type="text/javascript" src="/planetlab/includes/js/bsn.Ajax.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.DOM.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.AutoSuggest.js"></script>');
+ drupal_set_html_head('<script type="text/javascript" src="/planetlab/bsn/bsn.Ajax.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.DOM.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.AutoSuggest.js"></script>');
echo "<div>\n
<form method=get action='index.php'>\n";
+++ /dev/null
-<?php
-
-// Require login
-require_once 'plc_login.php';
-
-// Get session and API handles
-require_once 'plc_session.php';
-global $plc, $api;
-
-/*
-// Print header
-require_once 'plc_drupal.php';
-drupal_set_title('Slices');
-include 'plc_header.php';
-*/
-
-// Common functions
-require_once 'plc_functions.php';
-require_once 'plc_sorts.php';
-
-// find person roles
-$_person= $plc->person;
-$_roles= $_person['role_ids'];
-
-
-// ATTRIBUTES -------------------------------------------------
-
-// attribute deletion
-if( $_GET['rem_id'] ) {
- // get the id of the attrib to remove from GET
- $attribute_id= intval( $_GET['rem_id'] );
-
- // get slice_id
- $attrib_info= $api->GetSliceTags( array( $attribute_id ), array( "slice_id" ) );
- $slice_id= $attrib_info[0]['slice_id'];
-
- // delete the attribute
- $api->DeleteSliceTag( $attribute_id );
-
-
- header( "location: index.php?id=$slice_id" );
- exit();
-}
-
-
-// attirbute updates
-if( $_POST['edit_attribute'] ) {
- // get the id of the attrib to update and teh value from POST
- $attribute_id= intval( $_POST['attribute_id'] );
- $value= $_POST['value'];
- $slice_id= $_POST['slice_id'];
-
- // update it!
- $api->UpdateSliceTag( $attribute_id, $value );
-
- header( "location: index.php?id=$slice_id" );
- exit();
-}
-
-
-// attribute adds
-if( $_POST['add_attribute'] ) {
- // get the slice_id, attribute_type_id, and value from POST
- $slice_id= intval( $_POST['slice_id'] );
- $attribute_type_id= intval( $_POST['attribute_type_id'] );
- $value= $_POST['value'];
-
- // add it!
- $api->AddSliceTag( $slice_id, $attribute_type_id, $value );
-
- header( "location: index.php?id=$slice_id" );
- exit();
-}
-
-// ATTRIBUTE TYPES ---------------------------------------------------
-
-// attribute type adds
-if( $_POST['add_type'] ) {
- // get post vars
- $name= $_POST['name'];
- $min_role_id= intval( $_POST['min_role_id'] );
- $description= $_POST['description'];
-
- // make the attribute_type_fields dict
- $attribute_type_fields= array( "min_role_id" => $min_role_id, "name" => $name, "description" => $description );
-
- // add it!!
- $api->AddSliceTagType( $attribute_type_fields );
-
- header( "location: attributes.php" );
- exit();
-}
-
-
-// attribute type updates
-if( $_POST['edit_type'] ) {
- // get post vars
- $name= $_POST['name'];
- $min_role_id= intval( $_POST['min_role_id'] );
- $description= $_POST['description'];
- $attribute_type_id= intval( $_POST['attribute_type_id'] );
-
- // make attribute_type_fields dict
- $attribute_type_fields= array( "min_role_id" => $min_role_id, "name" => $name, "description" => $description );
-
- // Update it!
- $api->UpdateSliceTagType( $attribute_type_id, $attribute_type_fields );
-
- header( "location: attributes.php" );
- exit();
-}
-
-
-// delete attribute types
-if( $_GET['del_type'] ) {
- // get vars
- $type_id= intval( $_GET['del_type'] );
-
- // delete it!
- $api->DeleteSliceTagType( $type_id );
-
- header( "location: attributes.php" );
- exit();
-}
-
-
-
-/*
-// Print footer
-include 'plc_footer.php';
-*/
-
-?>
+++ /dev/null
-<?php
-
-// Require login
-require_once 'plc_login.php';
-
-// Get session and API handles
-require_once 'plc_session.php';
-global $plc, $api;
-
-// Print header
-require_once 'plc_drupal.php';
-drupal_set_title('Attributes');
-include 'plc_header.php';
-
-// Common functions
-require_once 'plc_functions.php';
-require_once 'plc_sorts.php';
-
-// find person roles
-$_person= $plc->person;
-$_roles= $_person['role_ids'];
-
-//print_r( $_person );
-
-// if no id, display list of attributes types
-if( !$_GET['id'] && !$_GET['add'] && !$_GET['add_type'] && !$_GET['edit_type'] ) {
- // get types
- $attrib_types= $api->GetSliceTagTypes( NULL, array( "attribute_type_id", "name", "description", "min_role_id" ) );
-
- // get role names for the min role_ids
- foreach( $attrib_types as $attrib_type ) {
- $roles= $api->GetRoles();
- foreach( $roles as $role ) {
- if( $attrib_type['min_role_id'] == $role['role_id'] )
- $role_name= $role['name'];
- }
-
- $attrib_type_info[]= array( "attribute_type_id" => $attrib_type['attribute_type_id'], "name" => $attrib_type['name'], "description" => $attrib_type['description'], "min_role" => $role_name );
- }
-
- // list them
- echo "<h2>Slice Attribute Types</h2>\n";
-
- echo "<table cellpadding=2><thead><tr><th>Name</th><th>Min Role</th><th>Description</th>";
- // if admin we need to more cells
- if( in_array( "10", $_person['role_ids'] ) )
- echo "<th></th><th></th>";
- echo "</thead><tbody>";
-
- foreach( $attrib_type_info as $type ) {
- echo "<tr><td>". $type['name'] ."</td><td>". $type['min_role'] ."</td><td>". $type['description'] ."</td>";
- // if admin display edit/delet links
- if( in_array( "10", $_person['role_ids'] ) ) {
- echo "<td><a href='attributes.php?edit_type=". $type['attribute_type_id'] ."'>Edit</a></td>";
- echo "<td>";
- echo plc_delete_link_button ('attrib_action.php?del_type='. $type['attribute_type_id'],
- $type['name']);
- echo "</td>";
- }
- echo "</tr>\n";
-
- }
-
- echo "</tbody></table>\n";
-
- if( in_array( "10", $_person['role_ids'] ) )
- echo "<p><a href='attributes.php?add_type=1'>Add an Attribute Type</a>";
-
-}
-elseif( $_GET['add_type'] || $_GET['edit_type'] ) {
- // if its edit get the attribute info
- if( $_GET['edit_type'] ) {
- $type_id= intval( $_GET['edit_type'] );
- $type_info= $api->GetSliceTagTypes( array( $type_id ) );
-
- $name= $type_info[0]['name'];
- $min_role_id= $type_info[0]['min_role_id'];
- $description= $type_info[0]['description'];
-
- }
-
- // display form for attribute types
- echo "<form action='attrib_action.php' method='post'>\n";
- echo "<h2>Add Attribute Type</h2>\n";
- echo "<p><strong>Name: </strong> <input type=text name='name' size=20 value='$name'>\n";
- echo "<p><strong>Min Role: </strong><select name='min_role_id'>\n";
- echo "<option value='10'"; if( $min_role_id == 10 ) echo " selected"; echo ">Admin</option>\n";
- echo "<option value='20'"; if( $min_role_id == 20 ) echo " selected"; echo ">PI</option>\n";
- echo "<option value='30'"; if( $min_role_id == 30 ) echo " selected"; echo ">User</option>\n";
- echo "<option value='40'"; if( $min_role_id == 40 ) echo " selected"; echo ">Tech</option>\n";
- echo "</select>\n";
- echo "<p><strong>Description: </strong><br>\n";
- echo "<textarea name='description' cols=40 rows=5>$description</textarea>\n";
- echo "<p><input type=submit ";
- if( $_GET['edit_type'] ) {
- echo "name='edit_type' value='Edit Attribute Type'>\n";
- echo "<input type=hidden name='attribute_type_id' value='$type_id'>\n";
- }
- else
- echo "name='add_type' value='Add Attribute Type'>\n";
-
- echo "</form>\n";
-
-}
-elseif( $_GET['add'] ) {
- // get slice id from GET
- $slice_id= intval( $_GET['add'] );
-
- // get all attribute types
- $attrib_types= $api->GetSliceTagTypes( NULL, array( "attribute_type_id", "name" ) );
-
- foreach( $attrib_types as $attrib_type ) {
- $all_attribs[$attrib_type['attribute_type_id']]= $attrib_type['name'];
- }
-
- // get slice's attribute types
- $slice_info= $api->GetSlices( array( $slice_id ), array( "slice_tag_ids" ) );
- $attrib_info= $api->GetSliceTags( $slice_info[0]['slice_tag_ids'], array( "attribute_type_id", "name" ) );
-
- foreach( $attrib_info as $info ) {
- $slice_attrib_types[$info['attribute_type_id']]= $info['name'];
- }
-
-
- $attribute_types= $all_attribs;
-
- // start form
- echo "<form action='attrib_action.php' method='post'>\n";
- echo "<h2>Edit ". $slice_info[0]['name'] ." attribute: ". $attrib_type[0]['name'] ."</h2>\n";
-
- echo "<select name='attribute_type_id'><option value=''>Choose a type to add</option>\n";
-
- foreach( $attribute_types as $key => $val ) {
- echo "<option value='". $key ."'>". $val ."</option>\n";
-
- }
- echo "</select>\n";
-
- echo "<p><strong>Value: </strong><input type=text name='value'>\n";
-
- echo "<p><input type=submit name='add_attribute' value='Add Attribute'>\n";
- echo "<input type=hidden name='slice_id' value='$slice_id'>\n";
- echo "</form>\n";
-
-}
-else {
- $attribute_id= intval( $_GET['id'] );
-
- // get attribute info
- $slice_attib= $api->GetSliceTags( array( $attribute_id ), array( "slice_id", "slice_tag_id", "attribute_type_id", "value", "description", "min_role_id" ) );
-
- // get type info
- $attrib_type= $api->GetSliceTagTypes( array( $slice_attib[0]['attribute_type_id'] ), array( "attribute_type_id", "name", "description" ) );
-
- // slice info
- $slice_info= $api->GetSlices( array( $slice_attib[0]['slice_id'] ), array( "name" ) );
-
- // start form and put values in to be edited.
- echo "<form action='attrib_action.php' method='post'>\n";
- echo "<h2>Edit ". $slice_info[0]['name'] ." attribute: ". $attrib_type[0]['name'] ."</h2>\n";
-
- echo $slice_attib[0]['description'] ."<br />\n";
- echo "<strong>Value:</strong> <input type=text name=value value='". $slice_attib[0]['value'] ."'><br /><br />\n";
-
- echo "<input type=submit value='Edit Attribute' name='edit_attribute'>\n";
- echo "<input type=hidden name='slice_id' value='". $slice_attib[0]['slice_id'] ."'>\n";
- echo "<input type=hidden name='attribute_id' value='". $attribute_id ."'>\n";
- echo "</form>\n";
-
-}
-
-echo "<p><a href='index.php?id=$slice_id'>Back to Slices</a>\n";
-
-// Print footer
-include 'plc_footer.php';
-
-?>
if( in_array( 10, $_roles ) ) {
// auto complete box for finding a slice
- drupal_set_html_head('<script type="text/javascript" src="/planetlab/includes/js/bsn.Ajax.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.DOM.js"></script>
- <script type="text/javascript" src="/planetlab/includes/js/bsn.AutoSuggest.js"></script>');
+ drupal_set_html_head('<script type="text/javascript" src="/planetlab/bsn/bsn.Ajax.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.DOM.js"></script>
+ <script type="text/javascript" src="/planetlab/bsn/bsn.AutoSuggest.js"></script>');
echo "<div>\n
<form method=post action='index.php'>\n";
echo "<p><strong>No slice found, or all are expired.</strong>";
} else {
- $slice_info= $api->GetSlices( $slice_ids, array( "slice_id", "name", "site_id", "state", "person_ids", "expires", "peer_id" ) );
+ $slice_info= $api->GetSlices( $slice_ids, array( "slice_id", "name", "site_id", "person_ids", "expires", "peer_id" ) );
//print '<pre>'; print_r( $api->trace() ) ; print '</pre>';
if ( ! $slice_info) {
foreach( $slice_info as $slice ) {
$slice_id= $slice['slice_id'];
$slice_name= $slice['name'];
- $slice_state= $slice['state'];
$slice_expires= date( "M j, Y", $slice['expires'] );
$peer_id = $slice['peer_id'];
}
}
- // slice attribute info
+ // slice tag info
if( !empty( $slice_tag_ids ) )
$slice_attibs= $api->GetSliceTags( $slice_tag_ids,
- array( "slice_tag_id", "attribute_type_id", "value", "description", "min_role_id", "node_id" ) );
+ array( "slice_tag_id", "tag_type_id", "value", "description", "min_role_id", "node_id" ) );
- // gets attrib type info and combines it to form all attrib info array
+ // gets tag type info and combines it to form all tag info array
if( $slice_attibs ) {
foreach( $slice_attibs as $slice_attib ) {
- $attrib_type= $api->GetSliceTagTypes( array( $slice_attib['attribute_type_id'] ),
- array( "attribute_type_id", "name", "description" ) );
+ $tag_type= $api->GetTagTypes( array( $slice_attib['tag_type_id'] ),
+ array( "tag_type_id", "tagname", "description" ) );
- $attributes[]= array( "slice_tag_id" => $slice_attib['slice_tag_id'],
- "attribute_type_id" => $slice_attib['attribute_type_id'],
- "name" => $attrib_type[0]['name'],
- "value" => $slice_attib['value'],
- "description" => $slice_attib['description'],
- "min_role_id" => $slice_attib['min_role_id'],
- "node_id" => $slice_attib['node_id'] );
+ $tags[]= array( "slice_tag_id" => $slice_attib['slice_tag_id'],
+ "tag_type_id" => $slice_attib['tag_type_id'],
+ "tagname" => $tag_type[0]['tagname'],
+ "value" => $slice_attib['value'],
+ "description" => $slice_attib['description'],
+ "min_role_id" => $slice_attib['min_role_id'],
+ "node_id" => $slice_attib['node_id'] );
}
}
echo "<br /><hr />\n";
- // slice attributes
- if( $attributes ) {
+ // slice tags
+ if( $tags ) {
- // builds 2 arrays, one for attribs,one for slivers
- foreach( $attributes as $attribute ) {
- if( empty( $attribute['node_id'] ) ) {
- $slice_attrib[]= $attribute;
+ // builds 2 arrays, one for tags, one for slivers
+ foreach( $tags as $tag ) {
+ if( empty( $tag['node_id'] ) ) {
+ $slice_tag[]= $tag;
}
else {
- $sliver_attrib[]= $attribute;
- $sliver_nodes[]= $attribute['node_id'];
+ $sliver_tag[]= $tag;
+ $sliver_nodes[]= $tag['node_id'];
}
}
}
echo "<br /></div>\n";
}
- // slice attributes
+ // slice tags
$is_admin=in_array( 10, $_roles );
$is_in_slice=in_array( $slice_id, $_person['slice_ids'] );
$is_pi=in_array( 20, $_roles );
- if( $slice_attrib ) {
- echo "<table cellpadding=3><caption class='list_set'>Slice Attributes</caption>";
+ if( $slice_tag ) {
+ echo "<table cellpadding=3><caption class='list_set'>Slice Tags</caption>";
echo "<thead><tr>";
if( $is_admin )
echo "<th></th>";
- echo "<th>Attribute</th><th>Value</th><th>Description</th>";
+ echo "<th>Tag</th><th>Value</th><th>Description</th>";
echo "</tr></thead><tbody>\n";
- foreach( $attributes as $attribute ) {
- // ignore sliver attributes at this stage
- if( empty( $attribute['node_id'] ) ) {
+ foreach( $tags as $tag ) {
+ // ignore sliver tags at this stage
+ if( empty( $tag['node_id'] ) ) {
echo("<tr>");
if( $is_admin ) {
printf("<td>");
- sprintf($label,"\\n [ %s = %s] \\n from %s",$attribute['name'],$attribute['value'],$name);
- echo plc_delete_link_button ('attrib_action.php?rem_id=' . $attribute['slice_tag_id'],
+ sprintf($label,"\\n [ %s = %s] \\n from %s",$tag['tagname'],$tag['value'],$name);
+ echo plc_delete_link_button ('tag_action.php?rem_id=' . $tag['slice_tag_id'],
$label);
echo "</td>";
}
if( $is_admin || ($is_pi && $is_in_slice) ) {
- printf ("<td><a href='attributes.php?id=%s'>%s</a></td>",
- $attribute['slice_tag_id'],$attribute['name']);
+ printf ("<td><a href='tags.php?type=slice?id=%s'>%s</a></td>",
+ $tag['slice_tag_id'],$tag['tagname']);
} else {
- printf("<td>%s</td>",$attribute['name']);
+ printf("<td>%s</td>",$tag['tagname']);
}
printf("<td align=center>%s</td><td>%s</td>",
- $attribute['value'],$attribute['description']);
+ $tag['value'],$tag['description']);
echo "</tr>";
}
}
}
if( $is_admin || ($is_pi && $is_in_slice) )
- echo "<a href='attributes.php?add=$slice_id'>Add a Slice Attribute\n";
+ echo "<a href='tags.php?type=slice&add=$slice_id'>Add a Slice Tag</a>\n";
- // sliver attributes
- if( $sliver_attrib ) {
- echo "<table cellpadding=3><caption class='list_set'>Sliver Attributes</caption>";
+ // sliver tags
+ if( $sliver_tag ) {
+ echo "<table cellpadding=3><caption class='list_set'>Sliver Tags</caption>";
echo "<thead><tr>";
if( $is_admin )
echo "<th></th>";
- echo "<th>Attribute</th><th>Value</th><th>Description</th><th>Node</th>";
+ echo "<th>Tag</th><th>Value</th><th>Description</th><th>Node</th>";
echo "</tr></thead><tbody>\n";
- foreach( $attributes as $attribute ) {
- $nodename=$new_sliver_node_info[$attribute['node_id']]['hostname'];
- // consider only sliver attributes at this stage
- if( !empty( $attribute['node_id'] ) ) {
+ foreach( $tags as $tag ) {
+ $nodename=$new_sliver_node_info[$tag['node_id']]['hostname'];
+ // consider only sliver tags at this stage
+ if( !empty( $tag['node_id'] ) ) {
echo("<tr>");
if( $is_admin ) {
echo("<td>");
$label=sprintf("\\n [ %s = %s ] \\n from %s \\n on node %s",
- $attribute['name'],$attribute['value'],$name,$nodename);
- echo plc_delete_link_label('/db/nodes/sliver_action.php?rem_id=' . $attribute['slice_tag_id'],
+ $tag['tagname'],$tag['value'],$name,$nodename);
+ echo plc_delete_link_label('/db/nodes/sliver_action.php?rem_id=' . $tag['slice_tag_id'],
$label);
echo "</td>";
}
if( $is_admin ) {
- printf("<td><a href='attributes.php?id=%s'>%s</a></td>",$attribute['slice_tag_id'],$attribute['name']);
+ printf("<td><a href='tags.php?type=slice&id=%s'>%s</a></td>",$tag['slice_tag_id'],$tag['tagname']);
} else {
- printf("<td>%s</td>",$attribute['name']);
+ printf("<td>%s</td>",$tag['tagname']);
}
printf("<td align=center>%s</td><td>%s</td><td><a href='/db/nodes/index.php?id=%s'>%s</a></td>",
- $attribute['value'],$attribute['description'],$attribute['node_id'],$nodename);
+ $tag['value'],$tag['description'],$tag['node_id'],$nodename);
echo "</tr>";
}
// get site nodes for $site_id
if( $site_id == 'all_site' ) {
- $full_node_info= $adm->GetNodes( NULL, array( "hostname", "node_id" , "peer_id", "boot_state","last_updated") );
+ $full_node_info= $adm->GetNodes( array("node_type","regular"),
+ array( "hostname", "node_id" , "peer_id", "boot_state","last_updated") );
- $snode_info= array();
- foreach( $full_node_info as $full_node ) {
- if( !in_array( $full_node['node_id'], $slice_info[0]['node_ids'] ) )
- $snode_info[]= $full_node;
- }
+ $snode_info= array();
+ foreach( $full_node_info as $full_node ) {
+ if( !in_array( $full_node['node_id'], $slice_info[0]['node_ids'] ) )
+ $snode_info[]= $full_node;
+ }
}
else {
- $sid= intval( $site_id );
- $site_node_info= $adm->GetSites( array( $sid ), array( "node_ids" ) );
- $site_nodes= $site_node_info[0]['node_ids'];
+ $sid= intval( $site_id );
+ $site_node_info= $adm->GetSites( array( $sid ), array( "node_ids" ) );
+ $site_nodes= $site_node_info[0]['node_ids'];
- // gets all node_ids from site that arent already associated with the slice
- foreach( $site_nodes as $snode) {
- if( !in_array( $snode, $slice_info[0]['node_ids'] ) )
- $snodes[]= $snode;
- }
+ // gets all node_ids from site that arent already associated with the slice
+ foreach( $site_nodes as $snode) {
+ if( !in_array( $snode, $slice_info[0]['node_ids'] ) )
+ $snodes[]= $snode;
+ }
- // Get node info from new list
- if( !empty( $snodes ) )
- $snode_info= $adm->GetNodes( $snodes, array( "hostname", "node_id" , "peer_id", "boot_state","last_updated" ) );
-
+ // Get node info from new list
+ if( !empty( $snodes ) )
+ $snode_info= $adm->GetNodes( $snodes, array( "hostname", "node_id" , "peer_id", "boot_state","last_updated" ) );
+
}
// start form
echo "</td><td>";
}
echo "<select name='site_id' onChange='submit()'>\n";
- echo "<option value='all_site'";
- if( $site_id == 'all_site' )
- echo " selected";
- echo ">--All Sites--</option>\n";
+ echo "<option value='all_site'";
+ if( $site_id == 'all_site' )
+ echo " selected";
+ echo ">--All Sites--</option>\n";
foreach( $site_info as $site ) {
echo "<option value=". $site['site_id'];
--- /dev/null
+<?php
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+/*
+// Print header
+require_once 'plc_drupal.php';
+drupal_set_title('Slices');
+include 'plc_header.php';
+*/
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+
+// find person roles
+$_person= $plc->person;
+$_roles= $_person['role_ids'];
+
+
+// TAGS -------------------------------------------------
+
+// tag deletion
+if( $_GET['rem_id'] ) {
+ // get the id of the tag to remove from GET
+ $tag_id= intval( $_GET['rem_id'] );
+
+ // get slice_id
+ $tag_info= $api->GetSliceTags( array( $tag_id ), array( "slice_id" ) );
+ $slice_id= $tag_info[0]['slice_id'];
+
+ // delete the tag
+ $api->DeleteSliceTag( $tag_id );
+
+
+ header( "location: index.php?id=$slice_id" );
+ exit();
+}
+
+
+// tag updates
+if( $_POST['edit_tag'] ) {
+ // get the id of the tag to update and teh value from POST
+ $tag_id= intval( $_POST['tag_id'] );
+ $value= $_POST['value'];
+ $slice_id= $_POST['slice_id'];
+
+ // update it!
+ $api->UpdateSliceTag( $tag_id, $value );
+
+ header( "location: index.php?id=$slice_id" );
+ exit();
+}
+
+
+// tag adds
+if( $_POST['add_tag'] ) {
+ // get the slice_id, tag_type_id, and value from POST
+ $slice_id= intval( $_POST['slice_id'] );
+ $tag_type_id= intval( $_POST['tag_type_id'] );
+ $value= $_POST['value'];
+
+ // add it!
+ $api->AddSliceTag( $slice_id, $tag_type_id, $value );
+
+ header( "location: index.php?id=$slice_id" );
+ exit();
+}
+
+// TAG TYPES ---------------------------------------------------
+
+// tag type adds
+if( $_POST['add_type'] ) {
+ // get post vars
+ $name= $_POST['name'];
+ $min_role_id= intval( $_POST['min_role_id'] );
+ $description= $_POST['description'];
+
+ // make the tag_type_fields dict
+ // xxx misses category
+ $tag_type_fields= array( "min_role_id" => $min_role_id,
+ "tagname" => $name,
+ "description" => $description );
+
+ // add it!!
+ $api->AddTagType( $tag_type_fields );
+
+ header( "location: tags.php?type=slice" );
+ exit();
+}
+
+
+// tag type updates
+if( $_POST['edit_type'] ) {
+ // get post vars
+ $name= $_POST['name'];
+ $min_role_id= intval( $_POST['min_role_id'] );
+ $description= $_POST['description'];
+ $tag_type_id= intval( $_POST['tag_type_id'] );
+
+ // make tag_type_fields dict
+ $tag_type_fields= array( "min_role_id" => $min_role_id, "tagname" => $name, "description" => $description );
+
+ // Update it!
+ $api->UpdateTagType( $tag_type_id, $tag_type_fields );
+
+ header( "location: tags.php?type=slice" );
+ exit();
+}
+
+
+// delete tag types
+if( $_GET['del_type'] ) {
+ // get vars
+ $type_id= intval( $_GET['del_type'] );
+
+ // delete it!
+ $api->DeleteTagType( $type_id );
+
+ header( "location: tags.php?type=slice" );
+ exit();
+}
+
+
+
+/*
+// Print footer
+include 'plc_footer.php';
+*/
+
+?>
--- /dev/null
+<?php
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+if (! isset($_GET['type']) || $_GET['type']=='all') {
+ $title="All tag types";
+ $tag_type_filter=array("-SORT"=>"tagname");
+ } else {
+ $title="Tag Types for " . $_GET['type'] . "s";
+ $pattern=$_GET['type'] . '*';
+ $tag_type_filter=array("category"=>$pattern,"-SORT"=>"tagname");
+ }
+
+
+// Print header
+require_once 'plc_drupal.php';
+drupal_set_title($title);
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_sorts.php';
+
+// find person roles
+$_person= $plc->person;
+$_roles= $_person['role_ids'];
+
+//print_r( $_person );
+
+// if no id, display list of tag types
+if( !$_GET['id'] && !$_GET['add'] && !$_GET['add_type'] && !$_GET['edit_type'] ) {
+ // get types
+ $tag_types= $api->GetTagTypes($tag_type_filter,
+ array( "tag_type_id", "tagname", "category", "description", "min_role_id" ) );
+
+ // get role names for the min role_ids
+ foreach( $tag_types as $tag_type ) {
+ $roles= $api->GetRoles();
+ foreach( $roles as $role ) {
+ if( $tag_type['min_role_id'] == $role['role_id'] )
+ $role_name= $role['name'];
+ }
+
+ $tag_type_info[]= array( "tag_type_id" => $tag_type['tag_type_id'],
+ "tagname" => $tag_type['tagname'],
+ "description" => $tag_type['description'],
+ "min_role" => $role_name,
+ "category" => $tag_type['category']);
+ }
+
+ // list them
+ echo "<h2>Tag Types</h2>\n";
+
+ echo "<table cellpadding=2><thead><tr><th>Name</th><th>Category></th><th>Min Role</th><th>Description</th>";
+ // if admin we need to more cells
+ if( in_array( "10", $_person['role_ids'] ) )
+ echo "<th></th><th></th>";
+ echo "</thead><tbody>";
+
+ foreach( $tag_type_info as $type ) {
+ echo "<tr>";
+ echo "<td>". $type['tagname'] ."</td>";
+ echo "<td>". $type['category'] ."</td>";
+ echo "<td>". $type['min_role'] ."</td>";
+ echo "<td>". $type['description'] ."</td>";
+ // if admin display edit/delet links
+ if( in_array( "10", $_person['role_ids'] ) ) {
+ echo "<td><a href='tags.php?type=slice&edit_type=". $type['tag_type_id'] ."'>Edit</a></td>";
+ echo "<td>";
+ echo plc_delete_link_button ('tag_action.php?del_type='. $type['tag_type_id'],
+ $type['tagname']);
+ echo "</td>";
+ }
+ echo "</tr>\n";
+
+ }
+
+ echo "</tbody></table>\n";
+
+ if( in_array( "10", $_person['role_ids'] ) )
+ echo "<p><a href='tags.php?type=slice&add_type=1'>Add a Tag Type</a>";
+
+ }
+elseif( $_GET['add_type'] || $_GET['edit_type'] ) {
+ // if its edit get the tag info
+ if( $_GET['edit_type'] ) {
+ $type_id= intval( $_GET['edit_type'] );
+ $type_info= $api->GetTagTypes( array( $type_id ) );
+
+ $tagname= $type_info[0]['tagname'];
+ $min_role_id= $type_info[0]['min_role_id'];
+ $description= $type_info[0]['description'];
+ $category=$type_info[0]['category'];
+
+ }
+
+ // display form for tag types
+ echo "<form action='tag_action.php' method='post'>\n";
+ echo "<h2>Add Tag Type</h2>\n";
+ echo "<p><strong>Name: </strong> <input type=text name='name' size=20 value='$tagname'>\n";
+ echo "<p><strong>Category: </strong><input type=text name='category' size=30 value='$category'>\n";
+ echo "<p><strong>Min Role: </strong><select name='min_role_id'>\n";
+ echo "<option value='10'"; if( $min_role_id == 10 ) echo " selected"; echo ">Admin</option>\n";
+ echo "<option value='20'"; if( $min_role_id == 20 ) echo " selected"; echo ">PI</option>\n";
+ echo "<option value='30'"; if( $min_role_id == 30 ) echo " selected"; echo ">User</option>\n";
+ echo "<option value='40'"; if( $min_role_id == 40 ) echo " selected"; echo ">Tech</option>\n";
+ echo "</select>\n";
+ echo "<p><strong>Description: </strong><br>\n";
+ echo "<textarea name='description' cols=40 rows=5>$description</textarea>\n";
+ echo "<p><input type=submit ";
+ if( $_GET['edit_type'] ) {
+ echo "name='edit_type' value='Edit Tag Type'>\n";
+ echo "<input type=hidden name='tag_type_id' value='$type_id'>\n";
+ }
+ else
+ echo "name='add_type' value='Add Tag Type'>\n";
+
+ echo "</form>\n";
+
+}
+elseif( $_GET['add'] ) {
+ // get slice id from GET
+ $slice_id= intval( $_GET['add'] );
+
+ // get all tag types
+ $tag_types= $api->GetTagTypes( $tag_type_filter , array( "tag_type_id", "tagname" ) );
+
+ foreach( $tag_types as $tag_type ) {
+ $all_tags[$tag_type['tag_type_id']]= $tag_type['tagname'];
+ }
+
+ // get slice's tag types
+ $slice_info= $api->GetSlices( array( $slice_id ), array( "slice_tag_ids" ) );
+ $tag_info= $api->GetSliceTags( $slice_info[0]['slice_tag_ids'], array( "tag_type_id", "tagname" ) );
+
+ foreach( $tag_info as $info ) {
+ $slice_tag_types[$info['tag_type_id']]= $info['tagname'];
+ }
+
+
+ $tag_types= $all_tags;
+
+ // start form
+ echo "<form action='tag_action.php' method='post'>\n";
+ echo "<h2>Edit ". $slice_info[0]['name'] ." tag: ". $tag_type[0]['tagname'] ."</h2>\n";
+
+ echo "<select name='tag_type_id'><option value=''>Choose a type to add</option>\n";
+
+ foreach( $tag_types as $key => $val ) {
+ echo "<option value='". $key ."'>". $val ."</option>\n";
+
+ }
+ echo "</select>\n";
+
+ echo "<p><strong>Value: </strong><input type=text name='value'>\n";
+
+ echo "<p><input type=submit name='add_tag' value='Add Tag'>\n";
+ echo "<input type=hidden name='slice_id' value='$slice_id'>\n";
+ echo "</form>\n";
+
+}
+else {
+ $tag_id= intval( $_GET['id'] );
+
+ // get tag
+ $slice_tag= $api->GetSliceTags( array( $tag_id ), array( "slice_id", "slice_tag_id", "tag_type_id", "value", "description", "min_role_id" ) );
+
+ // get type info
+ $tag_type= $api->GetTagTypes( array( $slice_tag[0]['tag_type_id'] ), array( "tag_type_id", "tagname", "description" ) );
+
+ // slice info
+ $slice_info= $api->GetSlices( array( $slice_tag[0]['slice_id'] ), array( "name" ) );
+
+ // start form and put values in to be edited.
+ echo "<form action='tag_action.php' method='post'>\n";
+ echo "<h2>Edit ". $slice_info[0]['name'] ." tag: ". $tag_type[0]['tagname'] ."</h2>\n";
+
+ echo $slice_tag[0]['description'] ."<br />\n";
+ echo "<strong>Value:</strong> <input type=text name=value value='". $slice_tag[0]['value'] ."'><br /><br />\n";
+
+ echo "<input type=submit value='Edit Tag' name='edit_tag'>\n";
+ echo "<input type=hidden name='slice_id' value='". $slice_tag[0]['slice_id'] ."'>\n";
+ echo "<input type=hidden name='tag_id' value='". $tag_id ."'>\n";
+ echo "</form>\n";
+
+}
+
+echo "<p><a href='index.php?id=$slice_id'>Back to Slices</a>\n";
+
+// Print footer
+include 'plc_footer.php';
+
+?>
--- /dev/null
+/*\r
+ sortEnglishDateTime\r
+ -----------------------\r
+\r
+ This function sorts English dateTime vaues such as:\r
+\r
+ 1st January 2003, 23:32:01\r
+ 23/03/1972 Ã 10:22:22\r
+ 1970/13/03 at 23:22:01\r
+ \r
+ The function is "safe" i.e. non-dateTime data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortEnglishDateTime = fdTableSort.sortNumeric;\r
+\r
+function sortEnglishDateTimePrepareData(tdNode, innerText) {\r
+ // You can localise the function here\r
+ var months = ['january','february','march','april','may','june','july','august','september','october','november','december','jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];\r
+\r
+ // Lowercase the text\r
+ var aa = innerText.toLowerCase();\r
+\r
+ // Replace the longhand months with an integer equivalent\r
+ for(var i = 0; i < months.length; i++) {\r
+ aa = aa.replace(months[i], (i+13)%12);\r
+ };\r
+\r
+ // Replace multiple spaces and anything that is not valid in the parsing of the date, then trim\r
+ aa = aa.replace(/\s+/g, " ").replace(/([^\d\s\/-:.])/g, "").replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
+\r
+ // No timestamp at the end, then return -1\r
+ if(aa.search(/(\d){2}:(\d){2}(:(\d){2})?$/) == -1) { return -1; };\r
+\r
+ // Grab the timestamp\r
+ var timestamp = aa.match(/(\d){2}:(\d){2}(:(\d){2})?$/)[0].replace(/:/g, "");\r
+\r
+ // Make the timestamp 6 characters by default\r
+ if(timestamp.length == 4) { timestamp += "00"; };\r
+\r
+ // Remove it from the string to assist the date parser, then trim\r
+ aa = aa.replace(/(\d){2}:(\d){2}(:(\d){2})?$/, "").replace(/\s\s*$/, '');\r
+\r
+ // If you want the parser to favour the parsing of European dd/mm/yyyy dates then leave this set to "true"\r
+ // If you want the parser to favour the parsing of American mm/dd/yyyy dates then set to "false"\r
+ var favourDMY = true;\r
+\r
+ // If you have a regular expression you wish to add, add the Object to the end of the array\r
+ var dateTest = [\r
+ { regExp:/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/, d:3, m:1, y:5 }, // mdy\r
+ { regExp:/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/, d:1, m:3, y:5 }, // dmy\r
+ { regExp:/^(\d\d\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/, d:5, m:3, y:1 } // ymd\r
+ ];\r
+\r
+ var start,y,m,d;\r
+ var cnt = 0;\r
+ var numFormats = dateTest.length;\r
+ while(cnt < numFormats) {\r
+ start = (cnt + (favourDMY ? numFormats + 1 : numFormats)) % numFormats;\r
+ if(aa.match(dateTest[start].regExp)) {\r
+ res = aa.match(dateTest[start].regExp);\r
+ y = res[dateTest[start].y];\r
+ m = res[dateTest[start].m];\r
+ d = res[dateTest[start].d];\r
+ if(m.length == 1) m = "0" + String(m);\r
+ if(d.length == 1) d = "0" + String(d);\r
+ if(y.length != 4) y = (parseInt(y) < 50) ? "20" + String(y) : "19" + String(y);\r
+\r
+ return y+String(m)+d+String(timestamp);\r
+ };\r
+ cnt++;\r
+ };\r
+ return -1;\r
+};\r
+\r
+/*\r
+ sortAlphaNumeric\r
+ -----------------------\r
+\r
+ This function sorts alphaNumeric values e.g. 1, e, 1a, -23c, 54z\r
+ \r
+ Notice how the prepareData function actually returns an Array i.e. you are not limited\r
+ in the type of data you return to the tableSort script.\r
+*/\r
+function sortAlphaNumericPrepareData(tdNode, innerText){\r
+ var aa = innerText.toLowerCase().replace(" ", "");\r
+ var reg = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)([a-z]+)/;\r
+\r
+ if(reg.test(aa)) {\r
+ var aaP = aa.match(reg);\r
+ return [aaP[1], aaP[8]];\r
+ };\r
+\r
+ // Return an array\r
+ return isNaN(aa) ? ["",aa] : [aa,""];\r
+}\r
+\r
+function sortAlphaNumeric(a, b){\r
+ // Get the previously prepared array\r
+ var aa = a[fdTableSort.pos];\r
+ var bb = b[fdTableSort.pos];\r
+\r
+ // If they are equal then return 0\r
+ if(aa[0] == bb[0] && aa[1] == bb[1]) { return 0; };\r
+\r
+ // Check numeric parts if not equal\r
+ if(aa[0] != bb[0]) {\r
+ if(aa[0] != "" && bb[0] != "") { return aa[0] - bb[0]; };\r
+ if(aa[0] == "" && bb[0] != "") { return -1; };\r
+ return 1;\r
+ };\r
+ \r
+ // Check alpha parts if numeric parts equal\r
+ if(aa[1] == bb[1]) return 0;\r
+ if(aa[1] < bb[1]) return -1;\r
+ return 1;\r
+}\r
+\r
+/*\r
+ sortDutchCurrencyValues\r
+ -----------------------\r
+\r
+ This function sorts Dutch currency values (of the type 100.000,00)\r
+ The function is "safe" i.e. non-currency data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortDutchCurrencyValues = fdTableSort.sortNumeric;\r
+\r
+function sortDutchCurrencyValuesPrepareData(tdNode, innerText) {\r
+ innerText = parseInt(innerText.replace(/[^0-9\.,]+/g, "").replace(/\./g,"").replace(",","."));\r
+ return isNaN(innerText) ? "" : innerText;\r
+}\r
+\r
+/*\r
+ sortByTwelveHourTimestamp\r
+ -------------------------\r
+\r
+ This custom sort function sorts 12 hour timestamps of an hour/minute nature.\r
+ The hour/minute dividor can be a full-stop or a colon and it correctly calculates that 12.30am is before 1am etc\r
+ The am/pm part can be written in lower or uppercase and can optionally contain full-stops e.g.\r
+\r
+ am, a.m, a.m., AM, A.M etc\r
+\r
+ Additionally, the values "12 midnight" and "12 noon" are also handled correctly.\r
+\r
+ The question remains... does "12p.m." mean "midnight" or "12 noon"? I've decided here that it's 12 noon.\r
+\r
+ The function is "safe" i.e. non-timestamp data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortByTwelveHourTimestamp = fdTableSort.sortNumeric;\r
+\r
+function sortByTwelveHourTimestampPrepareData(tdNode, innerText) {\r
+ tmp = innerText\r
+ innerText = innerText.replace(":",".");\r
+\r
+ // Check for the special cases of "12 noon" or "12 midnight"\r
+ if(innerText.search(/12([\s]*)?noon/i) != -1) return "12.00";\r
+ if(innerText.search(/12([\s]*)?midnight/i) != -1) return "24.00";\r
+\r
+ var regExpPM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(p[\.]?m)/i;\r
+ var regExpAM = /^([0-9]{1,2}).([0-9]{2})([\s]*)?(a[\.]?m)/i;\r
+\r
+ if(innerText.search(regExpPM) != -1) {\r
+ var bits = innerText.match(regExpPM);\r
+ if(parseInt(bits[1]) < 12) { bits[1] = parseInt(bits[1]) + 12; }\r
+ } else if(innerText.search(regExpAM) != -1) {\r
+ var bits = innerText.match(regExpAM);\r
+ if(bits[1] == "12") { bits[1] = "00"; }\r
+ } else return "";\r
+\r
+ if(bits[2].length < 2) { bits[2] = "0" + String(bits[2]); }\r
+\r
+ innerText = bits[1] + "." + String(bits[2]);\r
+\r
+ return isNaN(innerText) ? "" : innerText;\r
+}\r
+/*\r
+ sortEnglishLonghandDateFormat\r
+ -----------------------------\r
+\r
+ This custom sort function sorts dates of the format:\r
+\r
+ "12th April, 2006" or "12 April 2006" or "12-4-2006" or "12 April" or "12 4" or "12 Apr 2006" etc\r
+\r
+ The function expects dates to be in the format day/month/year. Should no year be stipulated,\r
+ the function treats the year as being the current year.\r
+\r
+ The function is "safe" i.e. non-date data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortEnglishLonghandDateFormat = fdTableSort.sortNumeric;\r
+\r
+function sortEnglishLonghandDateFormatPrepareData(tdNode, innerText) {\r
+ var months = ['january','february','march','april','may','june','july','august','september','october','november','december'];\r
+\r
+ var aa = innerText.toLowerCase();\r
+\r
+ // Replace the longhand months with an integer equivalent\r
+ for(var i = 0; i < 12; i++) {\r
+ aa = aa.replace(months[i], i+1).replace(months[i].substring(0,3), i+1);\r
+ }\r
+\r
+ // If there are still alpha characters then return -1\r
+ if(aa.search(/a-z/) != -1) return -1;\r
+\r
+ // Replace multiple spaces and anything that is not numeric\r
+ aa = aa.replace(/\s+/g, " ").replace(/[^\d\s]/g, "");\r
+\r
+ // If were left with nothing then return -1\r
+ if(aa.replace(" ", "") == "") return -1;\r
+\r
+ // Split on the (now) single spaces\r
+ aa = aa.split(" ");\r
+\r
+ // If something has gone terribly wrong then return -1\r
+ if(aa.length < 2) return -1;\r
+\r
+ // If no year stipulated, then add this year as default\r
+ if(aa.length == 2) {\r
+ aa[2] = String(new Date().getFullYear());\r
+ }\r
+\r
+ // Equalise the day and month\r
+ if(aa[0].length < 2) aa[0] = "0" + String(aa[0]);\r
+ if(aa[1].length < 2) aa[1] = "0" + String(aa[1]);\r
+\r
+ // Deal with Y2K issues\r
+ if(aa[2].length != 4) {\r
+ aa[2] = (parseInt(aa[2]) < 50) ? '20' + aa[2] : '19' + aa[2];\r
+ }\r
+\r
+ // YMD (can be used as integer during comparison)\r
+ return aa[2] + String(aa[1]) + aa[0];\r
+}\r
+/*\r
+ sortIPAddress\r
+ -------------\r
+\r
+ This custom sort function correctly sorts IP addresses i.e. it checks all of the address parts and not just the first.\r
+\r
+ The function is "safe" i.e. non-IP address data (like the word "Unknown") can be passed in and is sorted properly.\r
+*/\r
+var sortIPAddress = fdTableSort.sortNumeric;\r
+\r
+function sortIPAddressPrepareData(tdNode, innerText) {\r
+ // Get the innerText of the TR nodes\r
+ var aa = innerText;\r
+\r
+ // Remove spaces\r
+ aa = aa.replace(" ","");\r
+\r
+ // If not an IP address then return -1\r
+ if(aa.search(/^([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})$/) == -1) return -1;\r
+\r
+ // Split on the "."\r
+ aa = aa.split(".");\r
+\r
+ // If we don't have 4 parts then return -1\r
+ if(aa.length != 4) return -1;\r
+\r
+ var retVal = "";\r
+\r
+ // Make all the parts an equal length and create a master integer\r
+ for(var i = 0; i < 4; i++) {\r
+ retVal += (String(aa[i]).length < 3) ? "0000".substr(0, 3 - String(aa[i]).length) + String(aa[i]) : aa[i];\r
+ }\r
+\r
+ return retVal;\r
+}\r
+/*\r
+ sortScientificNotation\r
+ ----------------------\r
+\r
+ This custom sort function sorts numbers stipulated in scientific notation\r
+\r
+ The function is "safe" i.e. data like the word "Unknown" can be passed in and is sorted properly.\r
+\r
+ N.B. The only way I can think to really sort scientific notation is to convert\r
+ it to a floating point number and then perform the sort on that. If you can think of\r
+ an easier/better way then please let me know.\r
+*/\r
+var sortScientificNotation = fdTableSort.sortNumeric;\r
+\r
+function sortScientificNotationPrepareData(tdNode, innerText) {\r
+ var aa = innerText;\r
+\r
+ var floatRegExp = /((\-|\+)?(\s+)?[0-9]+\.([0-9]+)?|(\-|\+)?(\s+)?(\.)?[0-9]+)/g;\r
+\r
+ aa = aa.match(floatRegExp);\r
+\r
+ if(!aa || aa.length != 2) return "";\r
+\r
+ var f1 = parseFloat(aa[0].replace(" ",""))*Math.pow(10,parseFloat(aa[1].replace(" ","")));\r
+ return isNaN(f1) ? "" : f1;\r
+}\r
+\r
+/*\r
+ sortImage\r
+ ---------\r
+\r
+ This is the function called in order to sort the data previously prepared by the function\r
+ "sortImagePrepareData". It does a basic case sensitive comparison on the data using the\r
+ tableSort's in-built sortText method.\r
+*/\r
+var sortImage = fdTableSort.sortText;\r
+\r
+/*\r
+ This is the function used to prepare i.e. parse data, to be used during the sort\r
+ of the images within the last table.\r
+\r
+ In this case, we are checking to see if the TD node has any child nodes that are\r
+ images and, if an image exists, return it's "src" attribute.\r
+ If no image exists, then we return an empty string.\r
+\r
+ The "prepareData" functions are passed the actual TD node and also the TD node inner text\r
+ which means you are free to check for child nodes etc and are not just limited to\r
+ sorting on the TD node's inner text.\r
+\r
+ The prepareData functions are not required (only your bespoke sort function is required)\r
+ and only called by the script should they exist.\r
+*/\r
+function sortImagePrepareData(td, innerText) {\r
+ var img = td.getElementsByTagName('img');\r
+ return img.length ? img[0].src: "";\r
+}\r
+\r
+/*\r
+ sortFileSize\r
+ ------------\r
+\r
+ 1 Byte = 8 Bit\r
+ 1 Kilobyte = 1024 Bytes\r
+ 1 Megabyte = 1048576 Bytes\r
+ 1 Gigabyte = 1073741824 Bytes\r
+*/\r
+var sortFileSize = fdTableSort.sortNumeric;\r
+\r
+function sortFileSizePrepareData(td, innerText) {\r
+ var regExp = /(kb|mb|gb)/i;\r
+\r
+ var type = innerText.search(regExp) != -1 ? innerText.match(regExp)[0] : "";\r
+\r
+ switch (type.toLowerCase()) {\r
+ case "kb" :\r
+ mult = 1024;\r
+ break;\r
+ case "mb" :\r
+ mult = 1048576;\r
+ break;\r
+ case "gb" :\r
+ mult = 1073741824;\r
+ break;\r
+ default :\r
+ mult = 1;\r
+ };\r
+\r
+ innerText = parseFloat(innerText.replace(/[^0-9\.\-]/g,''));\r
+\r
+ return isNaN(innerText) ? "" : innerText * mult;\r
+};\r
--- /dev/null
+/*\r
+ paginate table object v2.0 by frequency-decoder.com\r
+\r
+ Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)\r
+\r
+ Please credit frequency decoder in any derivative work - thanks\r
+\r
+ You are free:\r
+\r
+ * to copy, distribute, display, and perform the work\r
+ * to make derivative works\r
+ * to make commercial use of the work\r
+\r
+ Under the following conditions:\r
+\r
+ by Attribution.\r
+ --------------\r
+ You must attribute the work in the manner specified by the author or licensor.\r
+\r
+ sa\r
+ --\r
+ Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.\r
+\r
+ * For any reuse or distribution, you must make clear to others the license terms of this work.\r
+ * Any of these conditions can be waived if you get permission from the copyright holder.\r
+*/\r
+\r
+var tablePaginater = (function() {\r
+ /*\r
+\r
+ Localise the button titles here...\r
+\r
+ %p is replaced with the appropriate page number\r
+ %t is replaced with the total number of pages\r
+ \r
+ */\r
+ var tableInfo = {},\r
+ uniqueID = 0,\r
+ text = ["First Page","Previous Page (Page %p)","Next Page (Page %p)","Last Page (Page %t)","Page %p of %t"];\r
+ \r
+ var addClass = function(e,c) {\r
+ if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) return;\r
+ e.className += ( e.className ? " " : "" ) + c;\r
+ }; \r
+ \r
+ /*@cc_on\r
+ /*@if (@_win32)\r
+ var removeClass = function(e,c) {\r
+ e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');\r
+ };\r
+ @else @*/\r
+ var removeClass = function(e,c) { \r
+ e.className = !c ? "" : (e.className || "").replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
+ };\r
+ /*@end\r
+ @*/ \r
+ \r
+ var addEvent = function(obj, type, fn) {\r
+ if( obj.attachEvent ) {\r
+ obj["e"+type+fn] = fn;\r
+ obj[type+fn] = function(){obj["e"+type+fn]( window.event );};\r
+ obj.attachEvent( "on"+type, obj[type+fn] );\r
+ } else {\r
+ obj.addEventListener( type, fn, true );\r
+ };\r
+ };\r
+ var removeEvent = function(obj, type, fn) {\r
+ try {\r
+ if( obj.detachEvent ) {\r
+ obj.detachEvent( "on"+type, obj[type+fn] );\r
+ obj[type+fn] = null;\r
+ } else {\r
+ obj.removeEventListener( type, fn, true );\r
+ };\r
+ } catch(err) {};\r
+ };\r
+ var stopEvent = function(e) {\r
+ e = e || window.event;\r
+ if(e.stopPropagation) {\r
+ e.stopPropagation();\r
+ e.preventDefault();\r
+ };\r
+ \r
+ /*@cc_on@*/\r
+ /*@if(@_win32)\r
+ e.cancelBubble = true;\r
+ e.returnValue = false;\r
+ /*@end@*/\r
+ return false;\r
+ }; \r
+ \r
+ var init = function(tableId) {\r
+ var tables = tableId && typeof(tableId) == "string" ? [document.getElementById(tableId)] : document.getElementsByTagName('table'),\r
+ hook, maxPages, visibleRows, numPages, cp, cb, rowList;\r
+ \r
+ for(var t = 0, tbl; tbl = tables[t]; t++) {\r
+ if(tbl.className.search(/paginate-([0-9]+)/) == -1) { continue; };\r
+\r
+ if(!tbl.id) { tbl.id = "fdUniqueTableId_" + uniqueID++; };\r
+\r
+ maxPages = tbl.className.search(/max-pages-([0-9]+)/) == -1 ? null : Number(tbl.className.match(/max-pages-([0-9]+)/)[1]);\r
+ if(maxPages % 2 == 0 && maxPages > 1) { maxPages--; };\r
+ \r
+ hook = tbl.getElementsByTagName('tbody');\r
+ hook = (hook.length) ? hook[0] : tbl;\r
+\r
+ visibleRows = calculateVisibleRows(hook);\r
+ \r
+ if(maxPages > (visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]))) {\r
+ maxPages = null;\r
+ };\r
+ \r
+ numPages = Math.ceil(visibleRows / Number(tbl.className.match(/paginate-([0-9]+)/)[1]));\r
+ \r
+ if(numPages < 2 && !(tbl.id in tableInfo)) {\r
+ continue;\r
+ };\r
+ \r
+ cp = (tbl.id in tableInfo) ? Math.min(tableInfo[tbl.id].currentPage, numPages) : 1;\r
+ \r
+ tableInfo[tbl.id] = {\r
+ rowsPerPage:Number(tbl.className.match(/paginate-([0-9]+)/)[1]),\r
+ currentPage:cp,\r
+ totalRows:hook.getElementsByTagName('tr').length,\r
+ hook:hook,\r
+ maxPages:maxPages,\r
+ numPages:numPages,\r
+ rowStyle:tbl.className.search(/rowstyle-([\S]+)/) != -1 ? tbl.className.match(/rowstyle-([\S]+)/)[1] : false,\r
+ callbacks:parseCallback(/^paginationcallback-/i, /paginationcallback-([\S-]+)/ig, tbl.className)\r
+ };\r
+ \r
+ showPage(tbl.id);\r
+ hook = null;\r
+ };\r
+ };\r
+ \r
+ var parseCallback = function(head, regExp, cname) {\r
+ var cbs = [],\r
+ matchs = cname.match(regExp),\r
+ parts, obj, func;\r
+ \r
+ if(!matchs) { return []; };\r
+ \r
+ for(var i = 0, mtch; mtch = matchs[i]; i++) { \r
+ mtch = mtch.replace(head, "").replace(/-/g, ".");\r
+ \r
+ try {\r
+ if(mtch.indexOf(".") != -1) {\r
+ parts = mtch.split('.');\r
+ obj = window;\r
+ for (var x = 0, part; part = obj[parts[x]]; x++) {\r
+ if(part instanceof Function) {\r
+ (function() {\r
+ var method = part;\r
+ func = function (data) { method.apply(obj, [data]) };\r
+ })();\r
+ } else {\r
+ obj = part;\r
+ };\r
+ };\r
+ } else {\r
+ func = window[mtch];\r
+ };\r
+ \r
+ if(!(func instanceof Function)) continue;\r
+ cbs[cbs.length] = func; \r
+ } catch(err) {};\r
+ };\r
+ \r
+ return cbs; \r
+ };\r
+ \r
+ var callback = function(tblId, opts) { \r
+ if(!(tblId in tableInfo) || !(tableInfo[tblId]["callbacks"].length)) return; \r
+ for(var i = 0, func; func = tableInfo[tblId]["callbacks"][i]; i++) {\r
+ func(opts || {});\r
+ };\r
+ };\r
+ \r
+ var calculateVisibleRows = function(hook) {\r
+ var trs = hook.rows,\r
+ cnt = 0,\r
+ reg = /(^|\s)invisibleRow(\s|$)/;\r
+ \r
+ for(var i = 0, tr; tr = trs[i]; i++) {\r
+ if(tr.parentNode != hook || tr.getElementsByTagName("th").length || (tr.parentNode && tr.parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) continue;\r
+ if(tr.className.search(reg) == -1) { cnt++; };\r
+ };\r
+ \r
+ return cnt;\r
+ };\r
+ \r
+ var createButton = function(details, ul, pseudo) {\r
+ var li = document.createElement("li"),\r
+ but = document.createElement(pseudo ? "div" : "a"),\r
+ span = document.createElement("span");\r
+\r
+ if(!pseudo) { \r
+ but.href = "#"; \r
+ but.title = details.title; \r
+ };\r
+ \r
+ but.className = details.className;\r
+\r
+ ul.appendChild(li);\r
+ li.appendChild(but);\r
+ but.appendChild(span);\r
+ span.appendChild(document.createTextNode(details.text));\r
+\r
+ if(!pseudo) { \r
+ li.onclick = but.onclick = buttonClick; \r
+ if(details.id) { but.id = details.id; };\r
+ }; \r
+ \r
+ li = but = span = null;\r
+ };\r
+ var removePagination = function(tableId) {\r
+ var wrapT = document.getElementById(tableId + "-fdtablePaginaterWrapTop"),\r
+ wrapB = document.getElementById(tableId + "-fdtablePaginaterWrapBottom");\r
+ if(wrapT) { wrapT.parentNode.removeChild(wrapT); };\r
+ if(wrapB) { wrapB.parentNode.removeChild(wrapB); };\r
+ };\r
+ var buildPagination = function(tblId) {\r
+ if(!(tblId in tableInfo)) { return; };\r
+\r
+ removePagination(tblId);\r
+\r
+ var details = tableInfo[tblId];\r
+ \r
+ if(details.numPages < 2) return;\r
+ \r
+ function resolveText(txt, curr) {\r
+ curr = curr || details.currentPage;\r
+ return txt.replace("%p", curr).replace("%t", details.numPages);\r
+ };\r
+\r
+ if(details.maxPages) {\r
+ findex = Math.max(0, Math.floor(Number(details.currentPage - 1) - (Number(details.maxPages - 1) / 2)));\r
+ lindex = findex + Number(details.maxPages);\r
+ if(lindex > details.numPages) {\r
+ lindex = details.numPages;\r
+ findex = Math.max(0, details.numPages - Number(details.maxPages));\r
+ };\r
+ } else {\r
+ findex = 0;\r
+ lindex = details.numPages;\r
+ };\r
+ \r
+\r
+ var wrapT = document.createElement("div");\r
+ wrapT.className = "fdtablePaginaterWrap";\r
+ wrapT.id = tblId + "-fdtablePaginaterWrapTop";\r
+\r
+ var wrapB = document.createElement("div");\r
+ wrapB.className = "fdtablePaginaterWrap";\r
+ wrapB.id = tblId + "-fdtablePaginaterWrapBottom";\r
+\r
+ // Create list scaffold\r
+ var ulT = document.createElement("ul");\r
+ ulT.id = tblId + "-tablePaginater";\r
+\r
+ var ulB = document.createElement("ul");\r
+ ulB.id = tblId + "-tablePaginaterClone";\r
+ ulT.className = ulB.className = "fdtablePaginater";\r
+\r
+ // Add to the wrapper DIVs\r
+ wrapT.appendChild(ulT);\r
+ wrapB.appendChild(ulB);\r
+\r
+ // FIRST (only created if maxPages set)\r
+ if(details.maxPages) {\r
+ createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulT, !findex);\r
+ createButton({title:text[0], className:"first-page", text:"\u00ab"}, ulB, !findex);\r
+ };\r
+ \r
+ // PREVIOUS (only created if there are more than two pages)\r
+ if(details.numPages > 2) {\r
+ createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPage"}, ulT, details.currentPage == 1);\r
+ createButton({title:resolveText(text[1], details.currentPage-1), className:"previous-page", text:"\u2039", id:tblId+"-previousPageC"}, ulB, details.currentPage == 1);\r
+ };\r
+ \r
+ // NUMBERED\r
+ for(var i = findex; i < lindex; i++) {\r
+ createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPage" : ""}, ulT);\r
+ createButton({title:resolveText(text[4], i+1), className:i != (details.currentPage-1) ? "page-"+(i+1) : "currentPage page-"+(i+1), text:(i+1), id:i == (details.currentPage-1) ? tblId + "-currentPageC" : ""}, ulB);\r
+ };\r
+\r
+ // NEXT (only created if there are more than two pages)\r
+ if(details.numPages > 2) {\r
+ createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPage"}, ulT, details.currentPage == details.numPages);\r
+ createButton({title:resolveText(text[2], details.currentPage + 1), className:"next-page", text:"\u203a", id:tblId+"-nextPageC"}, ulB, details.currentPage == details.numPages);\r
+ };\r
+ \r
+ // LAST (only created if maxPages set)\r
+ if(details.maxPages) {\r
+ createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulT, lindex == details.numPages);\r
+ createButton({title:resolveText(text[3], details.numPages), className:"last-page", text:"\u00bb"}, ulB, lindex == details.numPages);\r
+ };\r
+ \r
+ // DOM inject wrapper DIVs (FireFox 2.x Bug: this has to be done here if you use display:table)\r
+ if(document.getElementById(tblId+"-paginationListWrapTop")) {\r
+ document.getElementById(tblId+"-paginationListWrapTop").appendChild(wrapT);\r
+ } else {\r
+ document.getElementById(tblId).parentNode.insertBefore(wrapT, document.getElementById(tblId));\r
+ };\r
+\r
+ if(document.getElementById(tblId+"-paginationListWrapBottom")) {\r
+ document.getElementById(tblId+"-paginationListWrapBottom").appendChild(wrapB);\r
+ } else {\r
+ document.getElementById(tblId).parentNode.insertBefore(wrapB, document.getElementById(tblId).nextSibling);\r
+ };\r
+ };\r
+ \r
+ // The tableSort script uses this function to redraw.\r
+ var tableSortRedraw = function(tableid, identical) {\r
+ if(!tableid || !(tableid in fdTableSort.tableCache) || !(tableid in tableInfo)) { return; };\r
+ \r
+ var dataObj = fdTableSort.tableCache[tableid],\r
+ data = dataObj.data,\r
+ len1 = data.length,\r
+ len2 = len1 ? data[0].length - 1 : 0,\r
+ hook = dataObj.hook,\r
+ colStyle = dataObj.colStyle,\r
+ rowStyle = dataObj.rowStyle,\r
+ colOrder = dataObj.colOrder, \r
+ page = tableInfo[tableid].currentPage - 1,\r
+ d1 = tableInfo[tableid].rowsPerPage * page,\r
+ d2 = Math.min(tableInfo[tableid].totalRows, d1 + tableInfo[tableid].rowsPerPage), \r
+ cnt = 0,\r
+ rs = 0,\r
+ reg = /(^|\s)invisibleRow(\s|$)/, \r
+ tr, tds, cell, pos;\r
+ \r
+ for(var i = 0; i < len1; i++) {\r
+ tr = data[i][len2];\r
+ \r
+ if(colStyle) {\r
+ tds = tr.cells;\r
+ for(thPos in colOrder) {\r
+ if(!colOrder[thPos]) removeClass(tds[thPos], colStyle);\r
+ else addClass(tds[thPos], colStyle);\r
+ };\r
+ };\r
+ \r
+ if(tr.className.search(reg) != -1) { continue; };\r
+ \r
+ if(!identical) {\r
+ cnt++;\r
+\r
+ if(cnt > d1 && cnt <= d2) {\r
+ if(rowStyle) {\r
+ if(rs++ & 1) addClass(tr, rowStyle);\r
+ else removeClass(tr, rowStyle);\r
+ };\r
+ tr.style.display = "";\r
+ } else {\r
+ tr.style.display = "none";\r
+ };\r
+\r
+ // Netscape 8.1.2 requires the removeChild call or it freaks out, so add the line if you want to support this browser\r
+ // hook.removeChild(tr);\r
+ hook.appendChild(tr);\r
+ };\r
+ };\r
+\r
+ tr = tds = hook = null;\r
+ };\r
+ \r
+ var showPage = function(tblId, pageNum) {\r
+ if(!(tblId in tableInfo)) { return; };\r
+\r
+ var page = Math.max(0, !pageNum ? tableInfo[tblId].currentPage - 1 : pageNum - 1),\r
+ d1 = tableInfo[tblId].rowsPerPage * page,\r
+ d2 = Math.min(tableInfo[tblId].totalRows, d1 + tableInfo[tblId].rowsPerPage),\r
+ trs = tableInfo[tblId].hook.rows,\r
+ cnt = 0,\r
+ rc = 0,\r
+ len = trs.length,\r
+ rs = tableInfo[tblId].rowStyle,\r
+ reg = /(^|\s)invisibleRow(\s|$)/,\r
+ row = [];\r
+ \r
+ for(var i = 0; i < len; i++) {\r
+ if(trs[i].className.search(reg) != -1 || trs[i].getElementsByTagName("th").length || (trs[i].parentNode && trs[i].parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) { continue; };\r
+ \r
+ cnt++;\r
+ \r
+ if(cnt > d1 && cnt <= d2) {\r
+ if(rs) {\r
+ if(rc++ & 1) {\r
+ addClass(trs[i], rs);\r
+ } else {\r
+ removeClass(trs[i], rs);\r
+ }\r
+ };\r
+ trs[i].style.display = "";\r
+ row[row.length] = trs[i];\r
+ } else {\r
+ trs[i].style.display = "none";\r
+ };\r
+ };\r
+\r
+ buildPagination(tblId);\r
+ callback(tblId, {"totalRows":len, "currentPage":(page+1), "rowsPerPage":tableInfo[tblId].rowsPerPage, "visibleRows":row});\r
+ };\r
+ \r
+ var buttonClick = function(e) {\r
+ e = e || window.event;\r
+\r
+ var a = this.tagName.toLowerCase() == "a" ? this : this.getElementsByTagName("a")[0];\r
+\r
+ if(a.className.search("currentPage") != -1) return false;\r
+\r
+ var ul = this;\r
+ while(ul.tagName.toLowerCase() != "ul") ul = ul.parentNode;\r
+\r
+ var tblId = ul.id.replace("-tablePaginaterClone","").replace("-tablePaginater", "");\r
+\r
+ tableInfo[tblId].lastPage = tableInfo[tblId].currentPage;\r
+ \r
+ var showPrevNext = 0;\r
+ \r
+ if(a.className.search("previous-page") != -1) {\r
+ tableInfo[tblId].currentPage = tableInfo[tblId].currentPage > 1 ? tableInfo[tblId].currentPage - 1 : tableInfo[tblId].numPages;\r
+ showPrevNext = 1;\r
+ } else if(a.className.search("next-page") != -1) {\r
+ tableInfo[tblId].currentPage = tableInfo[tblId].currentPage < tableInfo[tblId].numPages ? tableInfo[tblId].currentPage + 1 : 1;\r
+ showPrevNext = 2;\r
+ } else if(a.className.search("first-page") != -1) {\r
+ tableInfo[tblId].currentPage = 1;\r
+ } else if(a.className.search("last-page") != -1) {\r
+ tableInfo[tblId].currentPage = tableInfo[tblId].numPages;\r
+ } else {\r
+ tableInfo[tblId].currentPage = parseInt(a.className.match(/page-([0-9]+)/)[1]) || 1;\r
+ };\r
+\r
+ showPage(tblId);\r
+\r
+ // Focus on the appropriate button (previous, next or the current page)\r
+ // I'm hoping screen readers are savvy enough to indicate the focus event to the user\r
+ if(showPrevNext == 1) {\r
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-previousPageC" : tblId + "-previousPage");\r
+ } else if(showPrevNext == 2) {\r
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-nextPageC" : tblId + "-nextPage");\r
+ } else {\r
+ var elem = document.getElementById(ul.id.search("-tablePaginaterClone") != -1 ? tblId + "-currentPageC" : tblId + "-currentPage");\r
+ };\r
+ \r
+ if(elem && elem.tagName.toLowerCase() == "a") { elem.focus(); }; \r
+ \r
+ return stopEvent(e);\r
+ };\r
+ \r
+ var onUnLoad = function(e) {\r
+ var tbl, lis, pagination, uls;\r
+ for(tblId in tableInfo) {\r
+ uls = [tblId + "-tablePaginater", tblId + "-tablePaginaterClone"];\r
+ for(var z = 0; z < 2; z++) {\r
+ pagination = document.getElementById(uls[z]);\r
+ if(!pagination) { continue; };\r
+ lis = pagination.getElementsByTagName("li");\r
+ for(var i = 0, li; li = lis[i]; i++) {\r
+ li.onclick = null;\r
+ if(li.getElementsByTagName("a").length) { li.getElementsByTagName("a")[0].onclick = null; };\r
+ };\r
+ };\r
+ };\r
+ };\r
+ \r
+ addEvent(window, "load", init);\r
+ addEvent(window, "unload", onUnLoad); \r
+ \r
+ return { \r
+ init: function(tableId) { init(tableId); }, \r
+ redraw: function(tableid, identical) { tableSortRedraw(tableid, identical); },\r
+ tableIsPaginated: function(tableId) { return (tableId in tableInfo); },\r
+ changeTranslations: function(translations) { text = translations; }\r
+ }; \r
+})();
\ No newline at end of file
--- /dev/null
+/*\r
+ TableSort revisited v5.0 by frequency-decoder.com\r
+\r
+ Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/)\r
+\r
+ Please credit frequency decoder in any derivative work - thanks\r
+\r
+ You are free:\r
+\r
+ * to copy, distribute, display, and perform the work\r
+ * to make derivative works\r
+ * to make commercial use of the work\r
+\r
+ Under the following conditions:\r
+\r
+ by Attribution.\r
+ --------------\r
+ You must attribute the work in the manner specified by the author or licensor.\r
+\r
+ sa\r
+ --\r
+ Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.\r
+\r
+ * For any reuse or distribution, you must make clear to others the license terms of this work.\r
+ * Any of these conditions can be waived if you get permission from the copyright holder.\r
+*/\r
+\r
+(function() {\r
+fdTableSort = {\r
+ regExp_Currency: /^[£$€¥¤]/,\r
+ regExp_Number: /^(\-)?[0-9]+(\.[0-9]*)?$/,\r
+ pos: -1,\r
+ uniqueHash: 1,\r
+ thNode: null,\r
+ tableId: null,\r
+ tableCache: {},\r
+ tmpCache: {},\r
+ sortActiveClass: "sort-active",\r
+ /*@cc_on\r
+ /*@if (@_win32)\r
+ colspan: "colSpan",\r
+ rowspan: "rowSpan",\r
+ @else @*/\r
+ colspan: "colspan",\r
+ rowspan: "rowspan",\r
+ /*@end\r
+ @*/\r
+ \r
+ addEvent: function(obj, type, fn, tmp) {\r
+ tmp || (tmp = true);\r
+ if( obj.attachEvent ) {\r
+ obj["e"+type+fn] = fn;\r
+ obj[type+fn] = function(){obj["e"+type+fn]( window.event );};\r
+ obj.attachEvent( "on"+type, obj[type+fn] );\r
+ } else {\r
+ obj.addEventListener( type, fn, true );\r
+ };\r
+ },\r
+ removeEvent: function(obj, type, fn, tmp) {\r
+ tmp || (tmp = true);\r
+ try {\r
+ if( obj.detachEvent ) {\r
+ obj.detachEvent( "on"+type, obj[type+fn] );\r
+ obj[type+fn] = null;\r
+ } else {\r
+ obj.removeEventListener( type, fn, true );\r
+ };\r
+ } catch(err) {};\r
+ },\r
+ stopEvent: function(e) {\r
+ e = e || window.event;\r
+\r
+ if(e.stopPropagation) {\r
+ e.stopPropagation();\r
+ e.preventDefault();\r
+ };\r
+ \r
+ /*@cc_on@*/\r
+ /*@if(@_win32)\r
+ e.cancelBubble = true;\r
+ e.returnValue = false;\r
+ /*@end@*/\r
+ return false;\r
+ },\r
+ parseClassName: function(head, tbl) {\r
+ var colMatch = tbl.className.match(new RegExp(head + "((-[\\d]+([r]){0,1})+)"));\r
+ return colMatch && colMatch.length ? colMatch[0].replace(head, "").split("-") : [];\r
+ },\r
+ disableSelection: function(element) {\r
+ element.onselectstart = function() {\r
+ return false;\r
+ };\r
+ element.unselectable = "on";\r
+ element.style.MozUserSelect = "none";\r
+ },\r
+ removeTableCache: function(tableId) {\r
+ if(!(tableId in fdTableSort.tableCache)) return;\r
+\r
+ fdTableSort.tableCache[tableId] = null;\r
+ delete fdTableSort.tableCache[tableId];\r
+\r
+ var tbl = document.getElementById(tableId);\r
+ if(!tbl) return;\r
+ var ths = tbl.getElementsByTagName("th");\r
+ var a;\r
+ for(var i = 0, th; th = ths[i]; i++) {\r
+ a = th.getElementsByTagName("a");\r
+ if(a.length) a[0].onkeydown = a[0].onclick = null;\r
+ th.onclick = th.onselectstart = th = a = null;\r
+ };\r
+ },\r
+ removeTmpCache: function(tableId) {\r
+ if(!(tableId in fdTableSort.tmpCache)) return;\r
+ var headers = fdTableSort.tmpCache[tableId].headers;\r
+ var a;\r
+ for(var i = 0, row; row = headers[i]; i++) {\r
+ for(var j = 0, th; th = row[j]; j++) {\r
+ a = th.getElementsByTagName("a");\r
+ if(a.length) a[0].onkeydown = a[0].onclick = null;\r
+ th.onclick = th.onselectstart = th = a = null;\r
+ };\r
+ };\r
+ fdTableSort.tmpCache[tableId] = null;\r
+ delete fdTableSort.tmpCache[tableId];\r
+ },\r
+ initEvt: function(e) {\r
+ fdTableSort.init(false);\r
+ },\r
+ init: function(tableId) {\r
+ if (!document.getElementsByTagName || !document.createElement || !document.getElementById) return;\r
+\r
+ var tables = tableId && document.getElementById(tableId) ? [document.getElementById(tableId)] : document.getElementsByTagName("table");\r
+ var c, ii, len, colMatch, showOnly, match, showArrow, columnNumSortObj, obj, workArr, headers, thtext, aclone, multi, colCnt, cel, allRowArr, rowArr, sortableTable, celCount, colspan, rowspan, rowLength;\r
+\r
+ var a = document.createElement("a");\r
+ a.href = "#";\r
+ a.className = "fdTableSortTrigger";\r
+\r
+ var span = document.createElement("span");\r
+\r
+ for(var k = 0, tbl; tbl = tables[k]; k++) {\r
+\r
+ if(tbl.id) {\r
+ fdTableSort.removeTableCache(tbl.id);\r
+ fdTableSort.removeTmpCache(tbl.id);\r
+ };\r
+\r
+ allRowArr = tbl.getElementsByTagName('thead').length ? tbl.getElementsByTagName('thead')[0].getElementsByTagName('tr') : tbl.getElementsByTagName('tr');\r
+ rowArr = [];\r
+ sortableTable = false;\r
+\r
+ for(var i = 0, tr; tr = allRowArr[i]; i++) {\r
+ if(tr.getElementsByTagName('td').length || !tr.getElementsByTagName('th').length) { continue; };\r
+ rowArr[rowArr.length] = tr.getElementsByTagName('th');\r
+ for(var j = 0, th; th = rowArr[rowArr.length - 1][j]; j++) {\r
+ if(th.className.search(/sortable/) != -1) { sortableTable = true; };\r
+ };\r
+ };\r
+\r
+ if(!sortableTable) continue;\r
+\r
+ if(!tbl.id) { tbl.id = "fd-table-" + fdTableSort.uniqueHash++; };\r
+\r
+ showArrow = tbl.className.search("no-arrow") == -1;\r
+ showOnly = tbl.className.search("sortable-onload-show") != -1;\r
+\r
+ columnNumSortObj = {};\r
+ colMatch = fdTableSort.parseClassName(showOnly ? "sortable-onload-show" : "sortable-onload", tbl);\r
+ for(match = 1; match < colMatch.length; match++) {\r
+ columnNumSortObj[parseInt(colMatch[match], 10)] = { "reverse":colMatch[match].search("r") != -1 };\r
+ };\r
+\r
+ rowLength = rowArr[0].length;\r
+\r
+ for(c = 0;c < rowArr[0].length;c++){\r
+ if(rowArr[0][c].getAttribute(fdTableSort.colspan) && rowArr[0][c].getAttribute(fdTableSort.colspan) > 1){\r
+ rowLength = rowLength + (rowArr[0][c].getAttribute(fdTableSort.colspan) - 1);\r
+ };\r
+ };\r
+\r
+ workArr = new Array(rowArr.length);\r
+ for(c = rowArr.length;c--;){ workArr[c]= new Array(rowLength); };\r
+\r
+ for(c = 0;c < workArr.length;c++){\r
+ celCount = 0;\r
+ for(i = 0;i < rowLength;i++){\r
+ if(!workArr[c][i]){\r
+ cel = rowArr[c][celCount];\r
+ colspan = (cel.getAttribute(fdTableSort.colspan) > 1) ? cel.getAttribute(fdTableSort.colspan):1;\r
+ rowspan = (cel.getAttribute(fdTableSort.rowspan) > 1) ? cel.getAttribute(fdTableSort.rowspan):1;\r
+ for(var t = 0;((t < colspan)&&((i+t) < rowLength));t++){\r
+ for(var n = 0;((n < rowspan)&&((c+n) < workArr.length));n++) {\r
+ workArr[(c+n)][(i+t)] = cel;\r
+ };\r
+ };\r
+ if(++celCount == rowArr[c].length) break;\r
+ };\r
+ };\r
+ };\r
+\r
+ for(c = 0;c < workArr.length;c++) {\r
+ for(i = 0;i < workArr[c].length;i++){\r
+\r
+ if(workArr[c][i].className.search("fd-column-") == -1 && workArr[c][i].className.search("sortable") != -1) workArr[c][i].className = workArr[c][i].className + " fd-column-" + i;\r
+\r
+ if(workArr[c][i].className.match('sortable')) {\r
+ workArr[c][i].className = workArr[c][i].className.replace(/forwardSort|reverseSort/, "");\r
+\r
+ if(i in columnNumSortObj) {\r
+ columnNumSortObj[i]["thNode"] = workArr[c][i];\r
+ columnNumSortObj["active"] = true;\r
+ };\r
+\r
+ thtext = fdTableSort.getInnerText(workArr[c][i], true);\r
+ \r
+ for(var cn = workArr[c][i].childNodes.length; cn--;) {\r
+ // Skip image nodes and links created by the filter script.\r
+ if(workArr[c][i].childNodes[cn].nodeType == 1 && (workArr[c][i].childNodes[cn].className == "fdFilterTrigger" || /img/i.test(workArr[c][i].childNodes[cn].nodeName))) {\r
+ continue;\r
+ };\r
+ if(workArr[c][i].childNodes[cn].nodeType == 1 && /^a$/i.test(workArr[c][i].childNodes[cn].nodeName)) {\r
+ workArr[c][i].childNodes[cn].onclick = workArr[c][i].childNodes[cn].onkeydown = null;\r
+ };\r
+ workArr[c][i].removeChild(workArr[c][i].childNodes[cn]);\r
+ };\r
+\r
+ aclone = a.cloneNode(true);\r
+ //aclone.appendChild(document.createTextNode(thtext));\r
+ aclone.innerHTML = thtext;\r
+ aclone.title = "Sort on \u201c" + thtext.replace('<br />', '') + "\u201d";\r
+ aclone.onclick = aclone.onkeydown = workArr[c][i].onclick = fdTableSort.initWrapper;\r
+ workArr[c][i].appendChild(aclone);\r
+ if(showArrow) workArr[c][i].appendChild(span.cloneNode(false));\r
+ workArr[c][i].className = workArr[c][i].className.replace(/fd-identical|fd-not-identical/, "");\r
+ fdTableSort.disableSelection(workArr[c][i]);\r
+ aclone = null;\r
+ };\r
+ };\r
+ };\r
+\r
+ fdTableSort.tmpCache[tbl.id] = {cols:rowLength, headers:workArr};\r
+\r
+ workArr = null;\r
+ multi = 0;\r
+\r
+ if("active" in columnNumSortObj) {\r
+ fdTableSort.tableId = tbl.id;\r
+ fdTableSort.prepareTableData(document.getElementById(fdTableSort.tableId));\r
+\r
+ delete columnNumSortObj["active"];\r
+\r
+ for(col in columnNumSortObj) {\r
+ obj = columnNumSortObj[col];\r
+ if(!("thNode" in obj)) { continue; };\r
+ fdTableSort.multi = true;\r
+\r
+ len = obj.reverse ? 2 : 1;\r
+\r
+ for(ii = 0; ii < len; ii++) {\r
+ fdTableSort.thNode = obj.thNode;\r
+ if(!showOnly) {\r
+ fdTableSort.initSort(false, true);\r
+ } else {\r
+ fdTableSort.addThNode();\r
+ };\r
+ };\r
+\r
+ if(showOnly) {\r
+ fdTableSort.removeClass(obj.thNode, "(forwardSort|reverseSort)");\r
+ fdTableSort.addClass(obj.thNode, obj.reverse ? "reverseSort" : "forwardSort");\r
+ if(showArrow) {\r
+ span = fdTableSort.thNode.getElementsByTagName('span')[0];\r
+ if(span.firstChild) { span.removeChild(span.firstChild); };\r
+ span.appendChild(document.createTextNode(len == 1 ? " \u2193" : " \u2191"));\r
+ };\r
+ };\r
+ };\r
+ if(showOnly && (fdTableSort.tableCache[tbl.id].colStyle || fdTableSort.tableCache[tbl.id].rowStyle)) {\r
+ fdTableSort.redraw(tbl.id, false);\r
+ };\r
+ } else if(tbl.className.search(/onload-zebra/) != -1) {\r
+ fdTableSort.tableId = tbl.id;\r
+ fdTableSort.prepareTableData(tbl);\r
+ if(fdTableSort.tableCache[tbl.id].rowStyle) { fdTableSort.redraw(tbl.id, false); };\r
+ };\r
+ };\r
+\r
+ fdTableSort.thNode = aclone = a = span = columnNumSortObj = thNode = tbl = allRowArr = rowArr = null;\r
+ },\r
+ initWrapper: function(e) {\r
+ e = e || window.event;\r
+ var kc = e.type == "keydown" ? e.keyCode != null ? e.keyCode : e.charCode : -1;\r
+ if(fdTableSort.thNode == null && (e.type == "click" || kc == 13)) {\r
+ var targ = this;\r
+ while(targ.tagName.toLowerCase() != "th") { targ = targ.parentNode; };\r
+ fdTableSort.thNode = targ;\r
+ while(targ.tagName.toLowerCase() != "table") { targ = targ.parentNode; };\r
+ fdTableSort.tableId = targ.id;\r
+ fdTableSort.multi = e.shiftKey;\r
+ fdTableSort.addSortActiveClass();\r
+ setTimeout(fdTableSort.initSort,5,false);\r
+ return fdTableSort.stopEvent(e);\r
+ };\r
+ return kc != -1 ? true : fdTableSort.stopEvent(e);\r
+ },\r
+ jsWrapper: function(tableid, colNums) {\r
+ if(!(tableid in fdTableSort.tmpCache)) { return false; };\r
+ if(!(tableid in fdTableSort.tableCache)) { fdTableSort.prepareTableData(document.getElementById(tableid)); };\r
+ if(!(colNums instanceof Array)) { colNums = [colNums]; };\r
+\r
+ fdTableSort.tableId = tableid;\r
+ var len = colNums.length, colNum;\r
+\r
+ if(fdTableSort.tableCache[tableid].thList.length == colNums.length) {\r
+ var identical = true;\r
+ var th;\r
+ for(var i = 0; i < len; i++) {\r
+ colNum = colNums[i];\r
+ th = fdTableSort.tmpCache[tableid].headers[0][colNum];\r
+ if(th != fdTableSort.tableCache[tableid].thList[i]) {\r
+ identical = false;\r
+ break;\r
+ };\r
+ };\r
+ if(identical) {\r
+ fdTableSort.thNode = th;\r
+ fdTableSort.initSort(true);\r
+ return;\r
+ };\r
+ };\r
+\r
+ fdTableSort.addSortActiveClass();\r
+\r
+ for(var i = 0; i < len; i++) {\r
+ fdTableSort.multi = i;\r
+ colNum = colNums[i];\r
+ fdTableSort.thNode = fdTableSort.tmpCache[tableid].headers[0][colNum];\r
+ fdTableSort.initSort(true);\r
+ };\r
+ },\r
+ addSortActiveClass: function() {\r
+ if(fdTableSort.thNode == null) { return; };\r
+ fdTableSort.addClass(fdTableSort.thNode, fdTableSort.sortActiveClass);\r
+ fdTableSort.addClass(document.getElementsByTagName('body')[0], fdTableSort.sortActiveClass);\r
+ },\r
+ removeSortActiveClass: function() {\r
+ if(fdTableSort.thNode == null) return;\r
+ fdTableSort.removeClass(fdTableSort.thNode, fdTableSort.sortActiveClass);\r
+ fdTableSort.removeClass(document.getElementsByTagName('body')[0], fdTableSort.sortActiveClass);\r
+ },\r
+ doCallback: function(init) {\r
+ if(!fdTableSort.tableId || !(fdTableSort.tableId in fdTableSort.tableCache)) { return; };\r
+ fdTableSort.callback(fdTableSort.tableId, init ? fdTableSort.tableCache[fdTableSort.tableId].initiatedCallback : fdTableSort.tableCache[fdTableSort.tableId].completeCallback);\r
+ },\r
+ addClass: function(e,c) {\r
+ if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) { return; };\r
+ e.className += ( e.className ? " " : "" ) + c;\r
+ },\r
+ /*@cc_on\r
+ /*@if (@_win32)\r
+ removeClass: function(e,c) {\r
+ e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s*((?:[\S\s]*\S)?)\s*$/, '$1');\r
+ },\r
+ @else @*/\r
+ removeClass: function(e,c) {\r
+ e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, '');\r
+ },\r
+ /*@end\r
+ @*/\r
+ callback: function(tblId, cb) {\r
+ var func, parts;\r
+ try {\r
+ if(cb.indexOf(".") != -1) { \r
+ parts = cb.split('.');\r
+ obj = window;\r
+ for (var x = 0, part; part = obj[parts[x]]; x++) {\r
+ if(part instanceof Function) {\r
+ (function() {\r
+ var method = part;\r
+ func = function (data) { method.apply(obj, [data]) };\r
+ })();\r
+ } else {\r
+ obj = part;\r
+ };\r
+ };\r
+ } else if(cb + tblId in window) {\r
+ func = window[cb + tblId];\r
+ } else if(cb in window) {\r
+ func = window[cb];\r
+ } else {\r
+ func = null;\r
+ };\r
+ } catch(err) {};\r
+ \r
+ if(!(func instanceof Function)) return;\r
+ func(tblId, fdTableSort.tableCache[tblId].thList); \r
+ },\r
+ prepareTableData: function(table) {\r
+ var data = [];\r
+\r
+ var start = table.getElementsByTagName('tbody');\r
+ start = start.length ? start[0] : table;\r
+\r
+ var trs = start.rows;\r
+ var ths = table.getElementsByTagName('th');\r
+\r
+ var numberOfRows = trs.length;\r
+ var numberOfCols = fdTableSort.tmpCache[table.id].cols;\r
+\r
+ var data = [];\r
+ var identical = new Array(numberOfCols);\r
+ var identVal = new Array(numberOfCols);\r
+\r
+ for(var tmp = 0; tmp < numberOfCols; tmp++) identical[tmp] = true;\r
+\r
+ var tr, td, th, txt, tds, col, row;\r
+\r
+ var re = new RegExp(/fd-column-([0-9]+)/);\r
+ var rowCnt = 0;\r
+\r
+ var sortableColumnNumbers = [];\r
+\r
+ for(var tmp = 0, th; th = ths[tmp]; tmp++) {\r
+ if(th.className.search(re) == -1) continue;\r
+ sortableColumnNumbers[sortableColumnNumbers.length] = th;\r
+ };\r
+\r
+ for(row = 0; row < numberOfRows; row++) {\r
+\r
+ tr = trs[row];\r
+ if(tr.parentNode != start || tr.getElementsByTagName("th").length || (tr.parentNode && tr.parentNode.tagName.toLowerCase().search(/thead|tfoot/) != -1)) continue;\r
+ data[rowCnt] = [];\r
+ tds = tr.cells;\r
+\r
+ for(var tmp = 0, th; th = sortableColumnNumbers[tmp]; tmp++) {\r
+ col = th.className.match(re)[1];\r
+\r
+ td = tds[col];\r
+ txt = fdTableSort.getInnerText(td) + " ";\r
+ txt = txt.replace(/^\s+/,'').replace(/\s+$/,'');\r
+\r
+ if(th.className.search(/sortable-date/) != -1) {\r
+ txt = fdTableSort.dateFormat(txt, th.className.search(/sortable-date-dmy/) != -1);\r
+ } else if(th.className.search(/sortable-numeric|sortable-currency/) != -1) {\r
+ txt = parseFloat(txt.replace(/[^0-9\.\-]/g,''));\r
+ if(isNaN(txt)) txt = "";\r
+ } else if(th.className.search(/sortable-text/) != -1) {\r
+ txt = txt.toLowerCase();\r
+ } else if (th.className.search(/sortable-keep/) != -1) {\r
+ txt = rowCnt;\r
+ } else if(th.className.search(/sortable-([a-zA-Z\_]+)/) != -1) {\r
+ if((th.className.match(/sortable-([a-zA-Z\_]+)/)[1] + "PrepareData") in window) {\r
+ txt = window[th.className.match(/sortable-([a-zA-Z\_]+)/)[1] + "PrepareData"](td, txt);\r
+ };\r
+ } else if(txt != "") {\r
+ fdTableSort.removeClass(th, "sortable");\r
+ if(fdTableSort.dateFormat(txt) != 0) {\r
+ fdTableSort.addClass(th, "sortable-date");\r
+ txt = fdTableSort.dateFormat(txt);\r
+ } else if(txt.search(fdTableSort.regExp_Number) != -1 || txt.search(fdTableSort.regExp_Currency) != -1) {\r
+ fdTableSort.addClass(th, "sortable-numeric");\r
+ txt = parseFloat(txt.replace(/[^0-9\.\-]/g,''));\r
+ if(isNaN(txt)) txt = "";\r
+ } else {\r
+ fdTableSort.addClass(th, "sortable-text");\r
+ txt = txt.toLowerCase();\r
+ };\r
+ };\r
+\r
+ if(rowCnt > 0 && identical[col] && identVal[col] != txt) { identical[col] = false; };\r
+\r
+ identVal[col] = txt;\r
+ data[rowCnt][col] = txt;\r
+ };\r
+ data[rowCnt][numberOfCols] = tr;\r
+ rowCnt++;\r
+ };\r
+\r
+ var colStyle = table.className.search(/colstyle-([\S]+)/) != -1 ? table.className.match(/colstyle-([\S]+)/)[1] : false;\r
+ var rowStyle = table.className.search(/rowstyle-([\S]+)/) != -1 ? table.className.match(/rowstyle-([\S]+)/)[1] : false;\r
+ var iCBack = table.className.search(/sortinitiatedcallback-([\S-]+)/) == -1 ? "sortInitiatedCallback" : table.className.match(/sortinitiatedcallback-([\S]+)/)[1];\r
+ var cCBack = table.className.search(/sortcompletecallback-([\S-]+)/) == -1 ? "sortCompleteCallback" : table.className.match(/sortcompletecallback-([\S]+)/)[1];\r
+ iCBack = iCBack.replace("-", ".");\r
+ cCBack = cCBack.replace("-", ".");\r
+ fdTableSort.tableCache[table.id] = { hook:start, initiatedCallback:iCBack, completeCallback:cCBack, thList:[], colOrder:{}, data:data, identical:identical, colStyle:colStyle, rowStyle:rowStyle, noArrow:table.className.search(/no-arrow/) != -1 };\r
+ sortableColumnNumbers = data = tr = td = th = trs = identical = identVal = null;\r
+ },\r
+ onUnload: function() {\r
+ for(tbl in fdTableSort.tableCache) { fdTableSort.removeTableCache(tbl); };\r
+ for(tbl in fdTableSort.tmpCache) { fdTableSort.removeTmpCache(tbl); };\r
+ fdTableSort.removeEvent(window, "load", fdTableSort.initEvt);\r
+ fdTableSort.removeEvent(window, "unload", fdTableSort.onUnload);\r
+ fdTableSort.tmpCache = fdTableSort.tableCache = null;\r
+ },\r
+ addThNode: function() {\r
+ var dataObj = fdTableSort.tableCache[fdTableSort.tableId];\r
+ var pos = fdTableSort.thNode.className.match(/fd-column-([0-9]+)/)[1];\r
+ var alt = false;\r
+\r
+ if(!fdTableSort.multi) {\r
+ if(dataObj.colStyle) {\r
+ var len = dataObj.thList.length;\r
+ for(var i = 0; i < len; i++) {\r
+ dataObj.colOrder[dataObj.thList[i].className.match(/fd-column-([0-9]+)/)[1]] = false;\r
+ };\r
+ };\r
+ if(dataObj.thList.length && dataObj.thList[0] == fdTableSort.thNode) alt = true;\r
+ dataObj.thList = [];\r
+ };\r
+\r
+ var found = false;\r
+ var l = dataObj.thList.length;\r
+\r
+ for(var i = 0, n; n = dataObj.thList[i]; i++) {\r
+ if(n == fdTableSort.thNode) {\r
+ found = true;\r
+ break;\r
+ };\r
+ };\r
+\r
+ if(!found) {\r
+ dataObj.thList.push(fdTableSort.thNode);\r
+ if(dataObj.colStyle) { dataObj.colOrder[pos] = true; };\r
+ };\r
+\r
+ var ths = document.getElementById(fdTableSort.tableId).getElementsByTagName("th");\r
+ for(var i = 0, th; th = ths[i]; i++) {\r
+ found = false;\r
+ for(var z = 0, n; n = dataObj.thList[z]; z++) {\r
+ if(n == th) {\r
+ found = true;\r
+ break;\r
+ };\r
+ };\r
+ if(!found) {\r
+ fdTableSort.removeClass(th, "(forwardSort|reverseSort)");\r
+ if(!dataObj.noArrow) {\r
+ span = th.getElementsByTagName('span');\r
+ if(span.length) {\r
+ span = span[0];\r
+ while(span.firstChild) span.removeChild(span.firstChild);\r
+ };\r
+ };\r
+ };\r
+ };\r
+\r
+ if(dataObj.thList.length > 1) {\r
+ classToAdd = fdTableSort.thNode.className.search(/forwardSort/) != -1 ? "reverseSort" : "forwardSort";\r
+ fdTableSort.removeClass(fdTableSort.thNode, "(forwardSort|reverseSort)");\r
+ fdTableSort.addClass(fdTableSort.thNode, classToAdd);\r
+ dataObj.pos = -1\r
+ } else if(alt) { dataObj.pos = fdTableSort.thNode };\r
+ },\r
+ initSort: function(noCallback, ident) {\r
+ var thNode = fdTableSort.thNode;\r
+ var tableElem = document.getElementById(fdTableSort.tableId);\r
+\r
+ if(!(fdTableSort.tableId in fdTableSort.tableCache)) { fdTableSort.prepareTableData(document.getElementById(fdTableSort.tableId)); };\r
+\r
+ fdTableSort.addThNode();\r
+\r
+ if(!noCallback) { fdTableSort.doCallback(true); };\r
+\r
+ fdTableSort.pos = thNode.className.match(/fd-column-([0-9]+)/)[1];\r
+ var dataObj = fdTableSort.tableCache[tableElem.id];\r
+ var lastPos = dataObj.pos && dataObj.pos.className ? dataObj.pos.className.match(/fd-column-([0-9]+)/)[1] : -1;\r
+ var len1 = dataObj.data.length;\r
+ var len2 = dataObj.data.length > 0 ? dataObj.data[0].length - 1 : 0;\r
+ var identical = dataObj.identical[fdTableSort.pos];\r
+ var classToAdd = "forwardSort";\r
+\r
+ if(dataObj.thList.length > 1) {\r
+ var js = "var sortWrapper = function(a,b) {\n";\r
+ var l = dataObj.thList.length;\r
+ var cnt = 0;\r
+ var e,d,th,p,f;\r
+\r
+ for(var i=0; i < l; i++) {\r
+ th = dataObj.thList[i];\r
+ p = th.className.match(/fd-column-([0-9]+)/)[1];\r
+ if(dataObj.identical[p]) { continue; };\r
+ cnt++;\r
+\r
+ if(th.className.match(/sortable-(numeric|currency|date|keep)/)) {\r
+ f = "fdTableSort.sortNumeric";\r
+ } else if(th.className.match('sortable-text')) {\r
+ f = "fdTableSort.sortText";\r
+ } else if(th.className.search(/sortable-([a-zA-Z\_]+)/) != -1 && th.className.match(/sortable-([a-zA-Z\_]+)/)[1] in window) {\r
+ f = "window['" + th.className.match(/sortable-([a-zA-Z\_]+)/)[1] + "']";\r
+ } else f = "fdTableSort.sortText";\r
+\r
+ e = "e" + i;\r
+ d = th.className.search('forwardSort') != -1 ? "a,b" : "b,a";\r
+ js += "fdTableSort.pos = " + p + ";\n";\r
+ js += "var " + e + " = "+f+"(" + d +");\n";\r
+ js += "if(" + e + ") return " + e + ";\n";\r
+ js += "else { \n";\r
+ };\r
+\r
+ js += "return 0;\n";\r
+\r
+ for(var i=0; i < cnt; i++) {\r
+ js += "};\n";\r
+ };\r
+\r
+ if(cnt) js += "return 0;\n";\r
+ js += "};\n";\r
+\r
+ eval(js);\r
+ dataObj.data.sort(sortWrapper);\r
+ identical = false;\r
+ } else if((lastPos == fdTableSort.pos && !identical) || (thNode.className.search(/sortable-keep/) != -1 && lastPos == -1)) {\r
+ dataObj.data.reverse();\r
+ classToAdd = thNode.className.search(/reverseSort/) != -1 ? "forwardSort" : "reverseSort";\r
+ if(thNode.className.search(/sortable-keep/) != -1 && lastPos == -1) fdTableSort.tableCache[tableElem.id].pos = thNode;\r
+ } else {\r
+ fdTableSort.tableCache[tableElem.id].pos = thNode;\r
+ classToAdd = thNode.className.search(/forwardSort/) != -1 ? "reverseSort" : "forwardSort";\r
+ if(!identical) {\r
+ if(thNode.className.match(/sortable-(numeric|currency|date|keep)/)) {\r
+ dataObj.data.sort(fdTableSort.sortNumeric);\r
+ } else if(thNode.className.match('sortable-text')) {\r
+ dataObj.data.sort(fdTableSort.sortText);\r
+ } else if(thNode.className.search(/sortable-([a-zA-Z\_]+)/) != -1 && thNode.className.match(/sortable-([a-zA-Z\_]+)/)[1] in window) {\r
+ dataObj.data.sort(window[thNode.className.match(/sortable-([a-zA-Z\_]+)/)[1]]);\r
+ };\r
+\r
+ if(thNode.className.search(/(^|\s)favour-reverse($|\s)/) != -1) {\r
+ classToAdd = classToAdd == "forwardSort" ? "reverseSort" : "forwardSort";\r
+ dataObj.data.reverse();\r
+ };\r
+ };\r
+ };\r
+ if(ident) { identical = false; };\r
+ if(dataObj.thList.length == 1) {\r
+ fdTableSort.removeClass(thNode, "(forwardSort|reverseSort)");\r
+ fdTableSort.addClass(thNode, classToAdd);\r
+ };\r
+ if(!dataObj.noArrow) {\r
+ var span = fdTableSort.thNode.getElementsByTagName('span')[0];\r
+ if(span.firstChild) span.removeChild(span.firstChild);\r
+ span.appendChild(document.createTextNode(fdTableSort.thNode.className.search(/forwardSort/) != -1 ? " \u2193" : " \u2191"));\r
+ };\r
+ if(!dataObj.rowStyle && !dataObj.colStyle && identical) {\r
+ fdTableSort.removeSortActiveClass();\r
+ if(!noCallback) { fdTableSort.doCallback(false); };\r
+ fdTableSort.thNode = null;\r
+ return;\r
+ };\r
+ if("tablePaginater" in window && tablePaginater.tableIsPaginated(fdTableSort.tableId)) {\r
+ tablePaginater.redraw(fdTableSort.tableId, identical);\r
+ } else {\r
+ fdTableSort.redraw(fdTableSort.tableId, identical);\r
+ };\r
+ fdTableSort.removeSortActiveClass();\r
+ if(!noCallback) { fdTableSort.doCallback(false); };\r
+ fdTableSort.thNode = null;\r
+ },\r
+ redraw: function(tableid, identical) {\r
+ if(!tableid || !(tableid in fdTableSort.tableCache)) { return; };\r
+ var dataObj = fdTableSort.tableCache[tableid];\r
+ var data = dataObj.data;\r
+ var len1 = data.length;\r
+ var len2 = len1 ? data[0].length - 1 : 0;\r
+ var hook = dataObj.hook;\r
+ var colStyle = dataObj.colStyle;\r
+ var rowStyle = dataObj.rowStyle;\r
+ var colOrder = dataObj.colOrder;\r
+ var highLight = 0;\r
+ var reg = /(^|\s)invisibleRow(\s|$)/;\r
+ var tr, tds;\r
+\r
+ for(var i = 0; i < len1; i++) {\r
+ tr = data[i][len2];\r
+ if(colStyle) {\r
+ tds = tr.cells;\r
+ for(thPos in colOrder) {\r
+ if(!colOrder[thPos]) fdTableSort.removeClass(tds[thPos], colStyle);\r
+ else fdTableSort.addClass(tds[thPos], colStyle);\r
+ };\r
+ };\r
+ if(!identical) {\r
+ if(rowStyle && tr.className.search(reg) == -1) {\r
+ if(highLight++ & 1) fdTableSort.addClass(tr, rowStyle);\r
+ else fdTableSort.removeClass(tr, rowStyle);\r
+ };\r
+\r
+ // Netscape 8.1.2 requires the removeChild call or it freaks out, so add the line if you want to support this browser\r
+ // hook.removeChild(tr);\r
+ hook.appendChild(tr);\r
+ };\r
+ };\r
+ tr = tds = hook = null;\r
+ },\r
+ getInnerText: function(el, allowBrTags) {\r
+ if (typeof el == "string" || typeof el == "undefined") return el;\r
+ if(el.innerText) return el.innerText;\r
+ var txt = '', i;\r
+ for(i = el.firstChild; i; i = i.nextSibling) {\r
+ if(allowBrTags && i.nodeName && i.nodeName == "BR") txt += "<br />";\r
+ else if(i.nodeType == 3) txt += i.nodeValue;\r
+ else if(i.nodeType == 1) txt += fdTableSort.getInnerText(i);\r
+ };\r
+ return txt;\r
+ },\r
+ dateFormat: function(dateIn, favourDMY) {\r
+ var dateTest = [\r
+ { regExp:/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/, d:3, m:1, y:5 }, // mdy\r
+ { regExp:/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/, d:1, m:3, y:5 }, // dmy\r
+ { regExp:/^(\d\d\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/, d:5, m:3, y:1 } // ymd\r
+ ];\r
+ var start, cnt = 0, numFormats = dateTest.length;\r
+ while(cnt < numFormats) {\r
+ start = (cnt + (favourDMY ? numFormats + 1 : numFormats)) % numFormats;\r
+ if(dateIn.match(dateTest[start].regExp)) {\r
+ res = dateIn.match(dateTest[start].regExp);\r
+ y = res[dateTest[start].y];\r
+ m = res[dateTest[start].m];\r
+ d = res[dateTest[start].d];\r
+ if(m.length == 1) m = "0" + String(m);\r
+ if(d.length == 1) d = "0" + String(d);\r
+ if(y.length != 4) y = (parseInt(y) < 50) ? "20" + String(y) : "19" + String(y);\r
+\r
+ return y+String(m)+d;\r
+ };\r
+ cnt++;\r
+ };\r
+ return 0;\r
+ },\r
+ sortNumeric:function(a,b) {\r
+ var aa = a[fdTableSort.pos];\r
+ var bb = b[fdTableSort.pos];\r
+ if(aa == bb) return 0;\r
+ if(aa === "" && !isNaN(bb)) return -1;\r
+ if(bb === "" && !isNaN(aa)) return 1;\r
+ return aa - bb;\r
+ },\r
+ sortText:function(a,b) {\r
+ var aa = a[fdTableSort.pos];\r
+ var bb = b[fdTableSort.pos];\r
+ if(aa == bb) return 0;\r
+ if(aa < bb) return -1;\r
+ return 1;\r
+ }\r
+};\r
+})();\r
+fdTableSort.addEvent(window, "load", fdTableSort.initEvt);\r
+fdTableSort.addEvent(window, "unload", fdTableSort.onUnload);\r