diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4040c6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.gem +.bundle +Gemfile.lock +pkg/* diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..267b9da --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source "http://rubygems.org" + +# Specify your gem's dependencies in datatables.gemspec +gemspec diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..d8342ad --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2004-2011 Caseproof, LLC + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..1fa4830 --- /dev/null +++ b/README.rdoc @@ -0,0 +1,12 @@ += Datatables + +Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model. Datatables provides a simple helper that can be utilized in the view to automatically display a dynamic view on top of a model. Datatables handles the entire front end and backend support to do this. + += Installation += Example += Why use this plugin? += Support + +Bug report? Faulty/incomplete documentation? Feature request? Please post an issue on 'http://github.com/Caseproof/metafy/issues'. If its urgent, please contact me from my website at 'http://blairwilliams.com/contact' + +Copyright (c) 2004-2011 Caseproof, LLC, released under the MIT license \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..14cfe0b --- /dev/null +++ b/Rakefile @@ -0,0 +1,2 @@ +require 'bundler' +Bundler::GemHelper.install_tasks diff --git a/app/helpers/datatable_helper.rb b/app/helpers/datatable_helper.rb new file mode 100644 index 0000000..9df27a7 --- /dev/null +++ b/app/helpers/datatable_helper.rb @@ -0,0 +1,29 @@ +module DatatableHelper + def datatable(modelname,columns,options={},jsoptions={}) + if modelname.kind_of? Array + @modelname = modelname[0].to_s + @scope = modelname[1].to_s + @id = modelname[2] + else + @modelname = modelname.to_s + end + + @columns = columns + @jsoptions = jsoptions + @pptions = options + + @col_str = "" + @columns.each_pair do |key,col| + @col_str += "," unless @columns.keys.first == key + @col_str += key.to_s + if !col[:column].nil? + real_column_name = col[:column].gsub( /[\.#|]/, ":" ) + @col_str += ":#{real_column_name}" + logger.debug real_column_name + logger.debug @col_str + end + end + + render :partial => '/datatable/datatable' + end +end \ No newline at end of file diff --git a/app/views/datatable/_datatable.html.erb b/app/views/datatable/_datatable.html.erb new file mode 100644 index 0000000..503eee8 --- /dev/null +++ b/app/views/datatable/_datatable.html.erb @@ -0,0 +1,163 @@ +<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%> +
+ Clear Selections + <% unless @pptions[:selectable_actions].nil? -%> + <% @pptions[:selectable_actions].each do |sa| %> +  <%= sa %> + <% end -%> + <% end -%> +
+<% end -%> + + + + <% @columns.each_pair do |key,col| -%> + + <% end -%> + + + + + + + + + + <% @columns.each_pair do |key,col| -%> + + <% end -%> + + +
<%= col[:label] || key.to_s.humanize %>
<%= image_tag "upload_indicator.gif", :title => "progress", :class => "progress" %>
+ +<%= javascript_tag :defer => 'defer' do -%> + var asInitVals = new Array(); + +<% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%> + var gaiSelected = []; + + function rd_toggle_buttons() { + if( gaiSelected.length > 0 ) + { + jQuery("#rd_buttons a").removeClass('rd_disabled'); + jQuery("#rd_buttons a").addClass('rd_enabled'); + } + else + { + jQuery("#rd_buttons a").removeClass('rd_enabled'); + jQuery("#rd_buttons a").addClass('rd_disabled'); + } + } +<% end -%> + + function rd_bulk_edit_users() { + if( jQuery('#rd_bulk_edit_users').hasClass('rd_enabled') ) + { + jQuery.prettyPhoto.open('/admin/projects/<%= @id %>/edit_users/' + gaiSelected + '?iframe=true&width=90%&height=90%'); + } + } + + jQuery(document).ready(function() { + var oTable = jQuery('#rdatatable').dataTable( { + + /* Custom Options */ + <% @jsoptions.each_pair do |k,v| -%> + "<%= k %>": <%= v %>, + <% end -%> + + /* Visible / Hidden columns & Formatting */ + "aoColumnDefs": [ + <% @columns.each_pair do |name,attrs| -%> + <% if attrs[:type] == 'link' -%> + /* <%= name.to_s %> */ { + "fnRender": function ( oObj ) { + return '".replace( /<%= attrs[:replace] %>/i, oObj.aData[<%= @columns.keys.index( attrs[:replace].to_sym ) %>] ) + '">' + oObj.aData[<%= @columns.keys.index( name.to_sym ) %>] + ''; + }, + "aTargets": [ <%= @columns.keys.index( name ) %> ] + }<%= "," unless @columns.keys.last == name %> + <% elsif attrs[:type] == 'hidden' -%> + /* <%= name.to_s %> */ { "bVisible": false, "aTargets": [ <%= @columns.keys.index( name ) %> ] }<%= "," unless @columns.keys.last == name %> + <% else -%> + /* <%= name.to_s %> */ { "aTargets": [ <%= @columns.keys.index( name ) %> ] }<%= "," unless @columns.keys.last == name %> + <% end -%> + <% end -%> + ], + + <% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%> + "fnRowCallback": function( nRow, aData, iDisplayIndex ) { + if ( jQuery.inArray(aData[0], gaiSelected) != -1 ) { + jQuery(nRow).addClass('row_selected'); + } + return nRow; + }, + <% end -%> + + /* Boilerplate Options */ + "sPaginationType": "full_numbers", + "aLengthMenu": [[10, 25, 50, 100, 500], [10, 25, 50, 100, 500]], + "bProcessing": true, + "bServerSide": true, + "sAjaxSource": '/rdtable/<%= @modelname %><%= "/#{@col_str}" %><%= @scope.nil? ? '' : "/#{@scope}" %><%= @id.nil? ? '' : "/#{@id}" %>' + } ); + + <% unless @pptions[:selectable].nil? or !@pptions[:selectable] -%> + jQuery('#rd_clear_selections').click( function () { + gaiSelected = []; + jQuery("#rdatatable tbody tr").removeClass('row_selected'); + rd_toggle_buttons(); + }); + + /* Click event handler */ + jQuery('#rdatatable tbody tr').live('click', function () { + var aData = oTable.fnGetData( this ); + var iId = aData[0]; + + if ( jQuery.inArray(iId, gaiSelected) == -1 ) + { + gaiSelected[gaiSelected.length++] = iId; + } + else + { + gaiSelected = jQuery.grep(gaiSelected, function(value) { + return value != iId; + } ); + } + + jQuery(this).toggleClass('row_selected'); + rd_toggle_buttons(); + } ); + <% end -%> + + jQuery("tfoot input").keyup( function () { + /* Filter on the column (the index) of this element */ + oTable.fnFilter( this.value, jQuery(this).attr('rel') ); + gaiSelected = []; // clear the selection on filter + rd_toggle_buttons(); + } ); + + /* + * Support functions to provide a little bit of 'user friendlyness' to the textboxes in + * the footer + */ + jQuery("tfoot input").each( function (i) { + asInitVals[i] = this.value; + } ); + + jQuery("tfoot input").focus( function () { + if ( this.className == "search_init" ) + { + this.className = ""; + this.value = ""; + } + } ); + + jQuery("tfoot input").blur( function (i) { + if ( this.value == "" ) + { + this.className = "search_init"; + this.value = asInitVals[jQuery("tfoot input").index(this)]; + } + } ); + + } ); +<% end -%> diff --git a/datatables.gemspec b/datatables.gemspec new file mode 100644 index 0000000..60146bf --- /dev/null +++ b/datatables.gemspec @@ -0,0 +1,47 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "datatables/version" + +Gem::Specification.new do |s| + s.name = "datatables" + s.version = Datatables::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["TODO: Write your name"] + s.email = ["TODO: Write your email address"] + s.homepage = "" + s.summary = %q{TODO: Write a gem summary} + s.description = %q{TODO: Write a gem description} + + s.rubyforge_project = "datatables" + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.require_paths = ["lib"] +end + +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) + +Gem::Specification.new do |s| + s.name = "datatables" + s.version = "0.0.1" + s.platform = Gem::Platform::RUBY + s.authors = ["Blair Williams","Brandon Toone"] + s.email = ["blair@caseproof.com","btoone@gmail.com"] + s.homepage = "http://blairwilliams.com/ruby-on-rails/datatables" + s.summary = %q{Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model} + s.description = %q{Datatables is a Rails 3 plugin that enables the easy creation of dynamic datatable views on top of any ActiveRecord model. Datatables provides a simple helper that can be utilized in the view to automatically display a dynamic view on top of a model. Datatables handles the entire front end and backend support to do this. } + + s.add_dependency('rails','>= 3.0.3') + s.add_dependency('jquery-rails') + + s.license = 'MIT' + + s.rubyforge_project = "datatables" + + s.files = `git ls-files`.split("\n") + #s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + #s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + #s.require_paths = ["app","config","lib"] +end diff --git a/lib/datatables.rb b/lib/datatables.rb new file mode 100644 index 0000000..dfb71a2 --- /dev/null +++ b/lib/datatables.rb @@ -0,0 +1,4 @@ +module Datatables + require 'datatables/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3 + require 'datatables/activerecord_methods' if defined?(Rails) && Rails::VERSION::MAJOR == 3 +end diff --git a/lib/datatables/activerecord_methods.rb b/lib/datatables/activerecord_methods.rb new file mode 100644 index 0000000..be43911 --- /dev/null +++ b/lib/datatables/activerecord_methods.rb @@ -0,0 +1,130 @@ +# Adds the datatable method in ActiveRecord::Base, which sets up the backend for the datatable javascript +# +class << ActiveRecord::Base + def datatable( params ) + curr_model = self + table_name = curr_model.table_name + + if curr_model.metafied? + metas = curr_model.metafied_attrs || [] + else + metas = [] + end + + sql_opts = { :select => [], :limit => "", :order => "", :joins => [], :conditions => "" } + columns = [] + full_columns = [] + + dscope = params[:scope] || nil + dcols = params[:columns].split(',') + did = params[:id] + + dcols.each do |col| + col = col.split(':') + if col.length > 1 # association (already assumed we're joined within a scope) + col_fmt = "`#{col[1].to_s}`.`#{col[2].to_s}`" + elsif metas.include? col.first.to_sym + col_fmt = "`m_#{col.first.to_s}`.`meta_value`" + else + col_fmt = "`#{table_name.to_s}`.`#{col.first.to_s}`" + end + + columns.push col.first.to_s + full_columns.push col_fmt + sql_opts[:select].push "#{col_fmt} as #{col.first.to_s}" + end + + # Paging + if params['iDisplayStart'] and params['iDisplayLength'] != '-1' + sql_opts[:limit] = "#{params['iDisplayStart']},#{params['iDisplayLength']}" + end + + # Ordering + if params['iSortCol_0'] + orders = [] + i = 0 + while i < params['iSortingCols'].to_i do + if params['bSortable_' + params['iSortCol_' + i.to_s]] == "true" + # Make sure the order works for metafied columns and normal columns + col = full_columns[ params['iSortCol_' + i.to_s].to_i ] + orders.push( "#{col} #{params['sSortDir_' + i.to_s]}" ) + end + i += 1 + end + sql_opts[:order] = orders.join(", ") unless orders.empty? + end + + # Searching + search_str = "" + searches = [] + if params['sSearch'] and !params['sSearch'].empty? + full_columns.each_with_index do |col,i| + searches.push( "#{col} LIKE '%#{params['sSearch']}%'" ) + end + search_str = searches.join(' OR ') unless searches.empty? + end + + # Filtering + filter_str = "" + filters = [] + full_columns.each_with_index do |col,i| + if params['bSearchable_' + i.to_s] == "true" and !params['sSearch_' + i.to_s].empty? + filters.push( "#{col} LIKE '%#{params['sSearch_' + i.to_s]}%'" ) + end + end + filter_str = filters.join(' AND ') unless filters.empty? + + # Pull Searching & Filtering into where + if !searches.empty? and !filters.empty? + sql_opts[:conditions] = "(#{search_str}) AND #{filter_str}" + elsif !searches.empty? + sql_opts[:conditions] = search_str + elsif !filters.empty? + sql_opts[:conditions] = filter_str + end + + # Query + if dscope.nil? + # Scope model + records = curr_model.select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins]) + # Records Found + filtered_total = curr_model.count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] ) + # Total Found + total = curr_model.count( :select => "*" ) + elsif params[:id].nil? + # Scope model + records = curr_model.send( dscope.to_s ).select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins]) + # Records Found + filtered_total = curr_model.send( dscope.to_s ).count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] ) + # Total Found + total = curr_model.send( dscope.to_s ).count( :select => "*" ) + else + # Scope model + records = curr_model.send( dscope.to_s, params[:id] ).select( sql_opts[:select] ).limit( sql_opts[:limit] ).order( sql_opts[:order] ).where( sql_opts[:conditions] ).joins(sql_opts[:joins]) + # Records Found + filtered_total = curr_model.send( dscope.to_s, params[:id] ).count( :select => "*", :conditions => sql_opts[:conditions], :joins => sql_opts[:joins] ) + # Total Found + total = curr_model.send( dscope.to_s, params[:id] ).count( :select => "*" ) + end + + # Build Output Data Structure + output = { "sEcho" => params['sEcho'], + "iTotalRecords" => total, + "iTotalDisplayRecords" => filtered_total, + "aaData" => [] } + + records.each do |a_row| + row = [] + columns.each_with_index do |col,i| + if col == "version" # Special output formatting for version column + row.push( a_row[ col ]=="0" ? '-' : a_row[ col ] ) + elsif col != ' ' # General Output + row.push( a_row[ col ]) + end + end + output['aaData'].push(row) + end + + output + end +end \ No newline at end of file diff --git a/lib/datatables/engine.rb b/lib/datatables/engine.rb new file mode 100644 index 0000000..491e343 --- /dev/null +++ b/lib/datatables/engine.rb @@ -0,0 +1,9 @@ +require 'rails' +require 'active_record/base' +require 'datatables' + +module Datatables + class Engine < Rails::Engine + config.autoload_paths += %W(#{config.root}) + end +end diff --git a/public/javascripts/jquery.dataTables.min.js b/public/javascripts/jquery.dataTables.min.js new file mode 100644 index 0000000..cd65875 --- /dev/null +++ b/public/javascripts/jquery.dataTables.min.js @@ -0,0 +1,142 @@ +/* + * File: jquery.dataTables.min.js + * Version: 1.7.5 + * Author: Allan Jardine (www.sprymedia.co.uk) + * Info: www.datatables.net + * + * Copyright 2008-2010 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, as supplied with this software. + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + */ +(function(j,qa,p){j.fn.dataTableSettings=[];var D=j.fn.dataTableSettings;j.fn.dataTableExt={};var n=j.fn.dataTableExt;n.sVersion="1.7.5";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active", +sPageButtonStaticDisabled:"paginate_button",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled", +sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled", +sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",sPageFirst:"first ui-corner-tl ui-corner-bl", +sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripOdd:"odd",sStripEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",sSortableAsc:"ui-state-default", +sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner", +sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,m,r){var s,w,y;if(g.bJUI){s=p.createElement("a");w=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;w.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev;s.appendChild(y)}else{s=p.createElement("div");w=p.createElement("div")}s.className= +g.oClasses.sPagePrevDisabled;w.className=g.oClasses.sPageNextDisabled;s.title=g.oLanguage.oPaginate.sPrevious;w.title=g.oLanguage.oPaginate.sNext;m.appendChild(s);m.appendChild(w);j(s).click(function(){g.oApi._fnPageChange(g,"previous")&&r(g)});j(w).click(function(){g.oApi._fnPageChange(g,"next")&&r(g)});j(s).bind("selectstart",function(){return false});j(w).bind("selectstart",function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){m.setAttribute("id",g.sTableId+"_paginate"); +s.setAttribute("id",g.sTableId+"_previous");w.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var m=g.aanFeatures.p,r=0,s=m.length;r=w-s){s=w-r+1;x=w}else{s=y-Math.ceil(r/2)+1;x=s+r-1}for(r=s;r<= +x;r++)F+=y!=r?''+r+"":''+r+"";x=g.aanFeatures.p;var z,U=function(){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;m(g);return false},C=function(){return false};r=0;for(s=x.length;rm?1:0},"string-desc":function(g,m){g=g.toLowerCase();m=m.toLowerCase();return gm?-1:0},"html-asc":function(g,m){g=g.replace(/<.*?>/g,"").toLowerCase();m=m.replace(/<.*?>/g,"").toLowerCase();return gm?1:0},"html-desc":function(g,m){g=g.replace(/<.*?>/g,"").toLowerCase();m=m.replace(/<.*?>/g,"").toLowerCase();return gm?-1:0},"date-asc":function(g,m){g=Date.parse(g);m=Date.parse(m);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(m)|| +m==="")m=Date.parse("01/01/1970 00:00:00");return g-m},"date-desc":function(g,m){g=Date.parse(g);m=Date.parse(m);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(m)||m==="")m=Date.parse("01/01/1970 00:00:00");return m-g},"numeric-asc":function(g,m){return(g=="-"||g===""?0:g*1)-(m=="-"||m===""?0:m*1)},"numeric-desc":function(g,m){return(m=="-"||m===""?0:m*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(g.length===0)return"numeric";var m,r=false;m=g.charAt(0);if("0123456789-".indexOf(m)== +-1)return null;for(var s=1;s")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var m=function(x,v){for(;x.length=parseInt(w,10)};n._oExternConfig={iNextUnique:0};j.fn.dataTable=function(g){function m(){this.fnRecordsTotal=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1? +this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance=this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...", +sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.iNextId=0;this.asDataSearch= +[];this.oPreviousSearch={sSearch:"",bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripClasses=[];this.asDestoryStrips=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType="two_button"; +this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.bAjaxDataGet=true;this.fnServerData=function(a,b,c){j.ajax({url:a,data:b,success:c,dataType:"json",cache:false,error:function(d,f){f=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})};this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b= +a+"";a=b.split("");var c="";b=b.length;for(var d=0;d=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;E(a)}if(!(!a.bDestroying&&a.oFeatures.bServerSide&&!sa(a))){a.oFeatures.bServerSide||a.iDraw++;if(a.aiDisplay.length!==0){var i=a._iDisplayStart,h=a._iDisplayEnd;if(a.oFeatures.bServerSide){i=0;h=a.aoData.length}for(i= +i;itr",a.nTHead)[0],V(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay); +typeof a.fnFooterCallback=="function"&&a.fnFooterCallback.call(a.oInstance,j(">tr",a.nTFoot)[0],V(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);f=p.createDocumentFragment();b=p.createDocumentFragment();if(a.nTBody){e=a.nTBody.parentNode;b.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered){c=a.nTBody.childNodes;for(b=c.length-1;b>=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b=0;b--)a.aoDrawCallback[b].fn.call(a.oInstance,a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){K(a,false);typeof a._bInitComplete=="undefined"&&w(a)}}}function W(a){if(a.oFeatures.bSort)O(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)P(a,a.oPreviousSearch);else{E(a);C(a)}}function sa(a){if(a.bAjaxDataGet){K(a,true);var b=a.aoColumns.length,c=[],d;a.iDraw++;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns", +value:ca(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:-1});if(a.oFeatures.bFilter!==false){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(d=0;d")c=c.parentNode; +else if(i=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=va(a);e=1}else if(i=="f"&&a.oFeatures.bFilter){f=wa(a);e=1}else if(i=="r"&&a.oFeatures.bProcessing){f=xa(a);e=1}else if(i=="t"){f=ya(a);e=1}else if(i=="i"&&a.oFeatures.bInfo){f=za(a);e=1}else if(i=="p"&&a.oFeatures.bPaginate){f=Aa(a);e=1}else if(n.aoFeatures.length!==0){h=n.aoFeatures;q=0;for(k=h.length;qcaption",a.nTable);i=0;for(k=d.length;ij(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()0&&a.nTable.removeChild(i[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}i=a.nTHead.cloneNode(true);a.nTable.insertBefore(i,a.nTable.childNodes[0]);if(a.nTFoot!==null){k=a.nTFoot.cloneNode(true);a.nTable.insertBefore(k,a.nTable.childNodes[1])}var J=fa(i);f=0;for(e=J.length;ff-a.oScroll.iBarWidth)a.nTable.style.width=u(f)}else a.nTable.style.width= +u(f);f=j(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");i=i.getElementsByTagName("tr");L(function(B,I){l=B.style;l.paddingTop="0";l.paddingBottom="0";l.borderTopWidth="0";l.borderBottomWidth="0";l.height=0;t=j(B).width();I.style.width=u(t);G.push(t)},i,e);j(i).height(0);if(a.nTFoot!==null){h=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");L(function(B,I){l=B.style;l.paddingTop="0";l.paddingBottom="0";l.borderTopWidth="0";l.borderBottomWidth="0";t=j(B).width();I.style.width= +u(t);G.push(t)},h,k);j(h).height(0)}L(function(B){B.innerHTML="";B.style.width=u(G.shift())},i);a.nTFoot!==null&&L(function(B){B.innerHTML="";B.style.width=u(G.shift())},h);if(j(a.nTable).outerWidth()d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight';var c=j("input",b);c.val(a.oPreviousSearch.sSearch.replace('"',"""));c.keyup(function(){for(var d=a.aanFeatures.f,f=0,e=d.length;f=0;d--){f=ja(a.aoData[a.aiDisplay[d]]._aData[c],a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Ca(a,b,c,d,f){var e=ia(b,d,f);if(typeof c=="undefined"||c===null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!== +0){a.aiDisplay.splice(0,a.aiDisplay.length);ha(a,1);for(c=0;c/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");return a}function O(a,b){var c,d,f,e,i,h,k=[],l=[],q=n.oSort,t=a.aoData,G=a.aoColumns;if(!a.oFeatures.bServerSide&&(a.aaSorting.length!==0||a.aaSortingFixed!==null)){k=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(f=0;f=i)for(b=0;b=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength=0){b=parseInt((a.fnRecordsDisplay()-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else H(a,0,"Unknown paging action: "+b);return c!=a._iDisplayStart}function za(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Fa,sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b} +function Fa(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),i=a.fnFormatNumber(c),h=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_", +h)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",i).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c'+a.aLengthMenu[1][c]+""}else{c=0;for(d=a.aLengthMenu.length;c'+a.aLengthMenu[c]+""}b+="";var f=p.createElement("div"); +a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length");f.className=a.oClasses.sLength;f.innerHTML=a.oLanguage.sLengthMenu.replace("_MENU_",b);j('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);j("select",f).change(function(){var e=j(this).val(),i=a.aanFeatures.l;c=0;for(d=i.length;ca.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Ga(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=p.createElement("div");c.style.width=a;b.appendChild(c);a=c.offsetWidth; +b.removeChild(c);return a}function $(a){var b=0,c,d=0,f=a.aoColumns.length,e,i=j("th",a.nTHead);for(e=0;etd",b);e.each(function(h){this.style.width="";h=ga(a,h);if(h!==null&&a.aoColumns[h].sWidthOrig!=="")this.style.width=a.aoColumns[h].sWidthOrig});for(e=0;etd",b);if(f.length===0)f=j("thead tr:eq(0)>th",b);for(e=c=0;e +0)a.aoColumns[e].sWidth=u(d);c++}a.nTable.style.width=u(j(b).outerWidth());b.parentNode.removeChild(b)}}function Ia(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){j(b).width();b.style.width=u(j(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!=="")b.style.width=u(j(b).outerWidth())}function Ha(a,b,c){if(typeof c=="undefined"||c){c=Ja(a,b);b=M(a,b);if(c<0)return null;return a.aoData[c].nTr.getElementsByTagName("td")[b]}var d=-1,f,e;c=-1;var i=p.createElement("div");i.style.visibility="hidden"; +i.style.position="absolute";p.body.appendChild(i);f=0;for(e=a.aoData.length;fd){d=i.offsetWidth;c=f}}p.body.removeChild(i);if(c>=0){b=M(a,b);if(a=a.aoData[c].nTr.getElementsByTagName("td")[b])return a}return null}function Ja(a,b){for(var c=-1,d=-1,f=0;fc){c=e.length;d=f}}return d}function u(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b= +a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+"px"}function Oa(a,b){if(a.length!=b.length)return 1;for(var c=0;cb&&a[d]--;c!=-1&&a.splice(c,1)}function ua(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d4096){a=p.cookie.split(";");for(var h=0,k=a.length;h=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){E(d);C(d)}return f};this.fnClearTable=function(a){var b=A(this[n.iApiIndex]);da(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=A(this[n.iApiIndex]);this.fnClose(a);var f= +p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c;e.colSpan=S(d);e.innerHTML=b;b=j("tr",d.nTBody);j.inArray(a,b)!=-1&&j(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=A(this[n.iApiIndex]),c=0;ctr",d.nTHead)[0];i=j(">tr",d.nTFoot)[0];q=[];h=[];for(f=0;f=S(d)){l.appendChild(q[a]);l=j(">tr",d.nTHead);f=1;for(e=l.length;ftr",d.nTFoot);f=1;for(e=l.length;ftr",d.nTHead);f=1;for(e=l.length;ftr",d.nTFoot);f=1;for(e=l.length;ftd:eq("+k+")",d.aoData[f].nTr)[0])}}d.aoColumns[a].bVisible=true}else{l.removeChild(q[a]);f=0;for(e=d.aoColumns[a].anThExtra.length;ftr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove();if(a.nTable!=a.nTHead.parentNode){j(">thead",a.nTable).remove();a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){j(">tfoot",a.nTable).remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);j(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];T(a);j(R(a)).removeClass(a.asStripClasses.join(" "));if(a.bJUI){j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc, +n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" "));j("th span",a.nTHead).remove()}else j("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));b.appendChild(a.nTable);d=0;for(f=a.aoData.length;dtr:even",c).addClass(a.asDestoryStrips[0]);j(">tr:odd",c).addClass(a.asDestoryStrips[1]);d=0;for(f=D.length;dt<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!=="")e.oScroll.iBarWidth=Ma();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;La(e,g);e.aoDrawCallback.push({fn:na,sName:"state_save"})}if(typeof g.aaData!="undefined")h= +true;if(typeof g!="undefined"&&typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;j.getJSON(e.oLanguage.sUrl,null,function(q){y(e,q,true)});i=true}else y(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"){e.asStripClasses.push(e.oClasses.sStripOdd);e.asStripClasses.push(e.oClasses.sStripEven)}c=false;d=j("tbody>tr",this);a=0;for(b=e.asStripClasses.length;a< +b;a++)if(d.filter(":lt(2)").hasClass(e.asStripClasses[a])){c=true;break}if(c){e.asDestoryStrips=["",""];if(j(d[0]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[0]+=e.oClasses.sStripOdd+" ";if(j(d[0]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[0]+=e.oClasses.sStripEven;if(j(d[1]).hasClass(e.oClasses.sStripOdd))e.asDestoryStrips[1]+=e.oClasses.sStripOdd+" ";if(j(d[1]).hasClass(e.oClasses.sStripEven))e.asDestoryStrips[1]+=e.oClasses.sStripEven;d.removeClass(e.asStripClasses.join(" "))}a=this.getElementsByTagName("thead"); +c=a.length===0?[]:fa(a[0]);var k;if(typeof g.aoColumns=="undefined"){k=[];a=0;for(b=c.length;a=0;a--){var l=g.aoColumnDefs[a].aTargets;j.isArray(l)||H(e,1,"aTargets must be an array of targets, not a "+typeof l); +c=0;for(d=l.length;c=0){for(;e.aoColumns.length<=l[c];)F(e);x(e,l[c],g.aoColumnDefs[a])}else if(typeof l[c]=="number"&&l[c]<0)x(e,e.aoColumns.length+l[c],g.aoColumnDefs[a]);else if(typeof l[c]=="string"){b=0;for(f=e.aoColumns.length;b=e.aoColumns.length)e.aaSorting[a][0]= +0;k=e.aoColumns[e.aaSorting[a][0]];if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c0)e.nTFoot=this.getElementsByTagName("tfoot")[0];if(h)for(a=0;a c4 + ee > d5 + Level 2: + dd > d1 + ee > e2 + */ +tr.odd.gradeA td.sorting_1 { + background-color: #c4ffc4; +} + +tr.odd.gradeA td.sorting_2 { + background-color: #d1ffd1; +} + +tr.odd.gradeA td.sorting_3 { + background-color: #d1ffd1; +} + +tr.even.gradeA td.sorting_1 { + background-color: #d5ffd5; +} + +tr.even.gradeA td.sorting_2 { + background-color: #e2ffe2; +} + +tr.even.gradeA td.sorting_3 { + background-color: #e2ffe2; +} + +tr.odd.gradeC td.sorting_1 { + background-color: #c4c4ff; +} + +tr.odd.gradeC td.sorting_2 { + background-color: #d1d1ff; +} + +tr.odd.gradeC td.sorting_3 { + background-color: #d1d1ff; +} + +tr.even.gradeC td.sorting_1 { + background-color: #d5d5ff; +} + +tr.even.gradeC td.sorting_2 { + background-color: #e2e2ff; +} + +tr.even.gradeC td.sorting_3 { + background-color: #e2e2ff; +} + +tr.odd.gradeX td.sorting_1 { + background-color: #ffc4c4; +} + +tr.odd.gradeX td.sorting_2 { + background-color: #ffd1d1; +} + +tr.odd.gradeX td.sorting_3 { + background-color: #ffd1d1; +} + +tr.even.gradeX td.sorting_1 { + background-color: #ffd5d5; +} + +tr.even.gradeX td.sorting_2 { + background-color: #ffe2e2; +} + +tr.even.gradeX td.sorting_3 { + background-color: #ffe2e2; +} + +tr.odd.gradeU td.sorting_1 { + background-color: #c4c4c4; +} + +tr.odd.gradeU td.sorting_2 { + background-color: #d1d1d1; +} + +tr.odd.gradeU td.sorting_3 { + background-color: #d1d1d1; +} + +tr.even.gradeU td.sorting_1 { + background-color: #d5d5d5; +} + +tr.even.gradeU td.sorting_2 { + background-color: #e2e2e2; +} + +tr.even.gradeU td.sorting_3 { + background-color: #e2e2e2; +} + + +/* + * Row highlighting rdatatable + */ +.ex_highlight #rdatatable tbody tr.even:hover, #rdatatable tbody tr.even td.highlighted { + background-color: #ECFFB3; +} + +.ex_highlight #rdatatable tbody tr.odd:hover, #rdatatable tbody tr.odd td.highlighted { + background-color: #E6FF99; +} + +.ex_highlight_row #rdatatable tr.even:hover { + background-color: #ECFFB3; +} + +.ex_highlight_row #rdatatable tr.even:hover td.sorting_1 { + background-color: #DDFF75; +} + +.ex_highlight_row #rdatatable tr.even:hover td.sorting_2 { + background-color: #E7FF9E; +} + +.ex_highlight_row #rdatatable tr.even:hover td.sorting_3 { + background-color: #E2FF89; +} + +.ex_highlight_row #rdatatable tr.odd:hover { + background-color: #E6FF99; +} + +.ex_highlight_row #rdatatable tr.odd:hover td.sorting_1 { + background-color: #D6FF5C; +} + +.ex_highlight_row #rdatatable tr.odd:hover td.sorting_2 { + background-color: #E0FF84; +} + +.ex_highlight_row #rdatatable tr.odd:hover td.sorting_3 { + background-color: #DBFF70; +} + + +/* + * KeyTable + */ +table.KeyTable td { + border: 3px solid transparent; +} + +table.KeyTable td.focus { + border: 3px solid #3366FF; +} + +table.display tr.gradeA { + background-color: #eeffee; +} + +table.display tr.gradeC { + background-color: #ddddff; +} + +table.display tr.gradeX { + background-color: #ffdddd; +} + +table.display tr.gradeU { + background-color: #ddd; +} + +div.box { + height: 100px; + padding: 10px; + overflow: auto; + border: 1px solid #8080FF; + background-color: #E5E5FF; +}