Commit 5d4a5fcd by Miles Steele

add slickgrid assets

parent 6ff568ce
/*
IMPORTANT:
In order to preserve the uniform grid appearance, all cell styles need to have padding, margin and border sizes.
No built-in (selected, editable, highlight, flashing, invalid, loading, :focus) or user-specified CSS
classes should alter those!
*/
.slick-header.ui-state-default, .slick-headerrow.ui-state-default {
width: 100%;
overflow: hidden;
border-left: 0px;
}
.slick-header-columns, .slick-headerrow-columns {
position: relative;
white-space: nowrap;
cursor: default;
overflow: hidden;
}
.slick-header-column.ui-state-default {
position: relative;
display: inline-block;
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
height: 16px;
line-height: 16px;
margin: 0;
padding: 4px;
border-right: 1px solid silver;
border-left: 0px;
border-top: 0px;
border-bottom: 0px;
float: left;
}
.slick-headerrow-column.ui-state-default {
padding: 4px;
}
.slick-header-column-sorted {
font-style: italic;
}
.slick-sort-indicator {
display: inline-block;
width: 8px;
height: 5px;
margin-left: 4px;
margin-top: 6px;
float: left;
}
.slick-sort-indicator-desc {
background: url(images/sort-desc.gif);
}
.slick-sort-indicator-asc {
background: url(images/sort-asc.gif);
}
.slick-resizable-handle {
position: absolute;
font-size: 0.1px;
display: block;
cursor: col-resize;
width: 4px;
right: 0px;
top: 0;
height: 100%;
}
.slick-sortable-placeholder {
background: silver;
}
.grid-canvas {
position: relative;
outline: 0;
}
.slick-row.ui-widget-content, .slick-row.ui-state-active {
position: absolute;
border: 0px;
width: 100%;
}
.slick-cell, .slick-headerrow-column {
position: absolute;
border: 1px solid transparent;
border-right: 1px dotted silver;
border-bottom-color: silver;
overflow: hidden;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
vertical-align: middle;
z-index: 1;
padding: 1px 2px 2px 1px;
margin: 0;
white-space: nowrap;
cursor: default;
}
.slick-group {
}
.slick-group-toggle {
display: inline-block;
}
.slick-cell.highlighted {
background: lightskyblue;
background: rgba(0, 0, 255, 0.2);
-webkit-transition: all 0.5s;
-moz-transition: all 0.5s;
-o-transition: all 0.5s;
transition: all 0.5s;
}
.slick-cell.flashing {
border: 1px solid red !important;
}
.slick-cell.editable {
z-index: 11;
overflow: visible;
background: white;
border-color: black;
border-style: solid;
}
.slick-cell:focus {
outline: none;
}
.slick-reorder-proxy {
display: inline-block;
background: blue;
opacity: 0.15;
filter: alpha(opacity = 15);
cursor: move;
}
.slick-reorder-guide {
display: inline-block;
height: 2px;
background: blue;
opacity: 0.7;
filter: alpha(opacity = 70);
}
.slick-selection {
z-index: 10;
position: absolute;
border: 2px dashed black;
}
/*!
* jquery.event.drop - v 2.2
* Copyright (c) 2010 Three Dub Media - http://threedubmedia.com
* Open Source MIT License - http://threedubmedia.com/code/license
*/
// Created: 2008-06-04
// Updated: 2012-05-21
// REQUIRES: jquery 1.7.x, event.drag 2.2
;(function($){ // secure $ jQuery alias
// Events: drop, dropstart, dropend
// add the jquery instance method
$.fn.drop = function( str, arg, opts ){
// figure out the event type
var type = typeof str == "string" ? str : "",
// figure out the event handler...
fn = $.isFunction( str ) ? str : $.isFunction( arg ) ? arg : null;
// fix the event type
if ( type.indexOf("drop") !== 0 )
type = "drop"+ type;
// were options passed
opts = ( str == fn ? arg : opts ) || {};
// trigger or bind event handler
return fn ? this.bind( type, opts, fn ) : this.trigger( type );
};
// DROP MANAGEMENT UTILITY
// returns filtered drop target elements, caches their positions
$.drop = function( opts ){
opts = opts || {};
// safely set new options...
drop.multi = opts.multi === true ? Infinity :
opts.multi === false ? 1 : !isNaN( opts.multi ) ? opts.multi : drop.multi;
drop.delay = opts.delay || drop.delay;
drop.tolerance = $.isFunction( opts.tolerance ) ? opts.tolerance :
opts.tolerance === null ? null : drop.tolerance;
drop.mode = opts.mode || drop.mode || 'intersect';
};
// local refs (increase compression)
var $event = $.event,
$special = $event.special,
// configure the drop special event
drop = $.event.special.drop = {
// these are the default settings
multi: 1, // allow multiple drop winners per dragged element
delay: 20, // async timeout delay
mode: 'overlap', // drop tolerance mode
// internal cache
targets: [],
// the key name for stored drop data
datakey: "dropdata",
// prevent bubbling for better performance
noBubble: true,
// count bound related events
add: function( obj ){
// read the interaction data
var data = $.data( this, drop.datakey );
// count another realted event
data.related += 1;
},
// forget unbound related events
remove: function(){
$.data( this, drop.datakey ).related -= 1;
},
// configure the interactions
setup: function(){
// check for related events
if ( $.data( this, drop.datakey ) )
return;
// initialize the drop element data
var data = {
related: 0,
active: [],
anyactive: 0,
winner: 0,
location: {}
};
// store the drop data on the element
$.data( this, drop.datakey, data );
// store the drop target in internal cache
drop.targets.push( this );
},
// destroy the configure interaction
teardown: function(){
var data = $.data( this, drop.datakey ) || {};
// check for related events
if ( data.related )
return;
// remove the stored data
$.removeData( this, drop.datakey );
// reference the targeted element
var element = this;
// remove from the internal cache
drop.targets = $.grep( drop.targets, function( target ){
return ( target !== element );
});
},
// shared event handler
handler: function( event, dd ){
// local vars
var results, $targets;
// make sure the right data is available
if ( !dd )
return;
// handle various events
switch ( event.type ){
// draginit, from $.event.special.drag
case 'mousedown': // DROPINIT >>
case 'touchstart': // DROPINIT >>
// collect and assign the drop targets
$targets = $( drop.targets );
if ( typeof dd.drop == "string" )
$targets = $targets.filter( dd.drop );
// reset drop data winner properties
$targets.each(function(){
var data = $.data( this, drop.datakey );
data.active = [];
data.anyactive = 0;
data.winner = 0;
});
// set available target elements
dd.droppable = $targets;
// activate drop targets for the initial element being dragged
$special.drag.hijack( event, "dropinit", dd );
break;
// drag, from $.event.special.drag
case 'mousemove': // TOLERATE >>
case 'touchmove': // TOLERATE >>
drop.event = event; // store the mousemove event
if ( !drop.timer )
// monitor drop targets
drop.tolerate( dd );
break;
// dragend, from $.event.special.drag
case 'mouseup': // DROP >> DROPEND >>
case 'touchend': // DROP >> DROPEND >>
drop.timer = clearTimeout( drop.timer ); // delete timer
if ( dd.propagates ){
$special.drag.hijack( event, "drop", dd );
$special.drag.hijack( event, "dropend", dd );
}
break;
}
},
// returns the location positions of an element
locate: function( elem, index ){
var data = $.data( elem, drop.datakey ),
$elem = $( elem ),
posi = $elem.offset() || {},
height = $elem.outerHeight(),
width = $elem.outerWidth(),
location = {
elem: elem,
width: width,
height: height,
top: posi.top,
left: posi.left,
right: posi.left + width,
bottom: posi.top + height
};
// drag elements might not have dropdata
if ( data ){
data.location = location;
data.index = index;
data.elem = elem;
}
return location;
},
// test the location positions of an element against another OR an X,Y coord
contains: function( target, test ){ // target { location } contains test [x,y] or { location }
return ( ( test[0] || test.left ) >= target.left && ( test[0] || test.right ) <= target.right
&& ( test[1] || test.top ) >= target.top && ( test[1] || test.bottom ) <= target.bottom );
},
// stored tolerance modes
modes: { // fn scope: "$.event.special.drop" object
// target with mouse wins, else target with most overlap wins
'intersect': function( event, proxy, target ){
return this.contains( target, [ event.pageX, event.pageY ] ) ? // check cursor
1e9 : this.modes.overlap.apply( this, arguments ); // check overlap
},
// target with most overlap wins
'overlap': function( event, proxy, target ){
// calculate the area of overlap...
return Math.max( 0, Math.min( target.bottom, proxy.bottom ) - Math.max( target.top, proxy.top ) )
* Math.max( 0, Math.min( target.right, proxy.right ) - Math.max( target.left, proxy.left ) );
},
// proxy is completely contained within target bounds
'fit': function( event, proxy, target ){
return this.contains( target, proxy ) ? 1 : 0;
},
// center of the proxy is contained within target bounds
'middle': function( event, proxy, target ){
return this.contains( target, [ proxy.left + proxy.width * .5, proxy.top + proxy.height * .5 ] ) ? 1 : 0;
}
},
// sort drop target cache by by winner (dsc), then index (asc)
sort: function( a, b ){
return ( b.winner - a.winner ) || ( a.index - b.index );
},
// async, recursive tolerance execution
tolerate: function( dd ){
// declare local refs
var i, drp, drg, data, arr, len, elem,
// interaction iteration variables
x = 0, ia, end = dd.interactions.length,
// determine the mouse coords
xy = [ drop.event.pageX, drop.event.pageY ],
// custom or stored tolerance fn
tolerance = drop.tolerance || drop.modes[ drop.mode ];
// go through each passed interaction...
do if ( ia = dd.interactions[x] ){
// check valid interaction
if ( !ia )
return;
// initialize or clear the drop data
ia.drop = [];
// holds the drop elements
arr = [];
len = ia.droppable.length;
// determine the proxy location, if needed
if ( tolerance )
drg = drop.locate( ia.proxy );
// reset the loop
i = 0;
// loop each stored drop target
do if ( elem = ia.droppable[i] ){
data = $.data( elem, drop.datakey );
drp = data.location;
if ( !drp ) continue;
// find a winner: tolerance function is defined, call it
data.winner = tolerance ? tolerance.call( drop, drop.event, drg, drp )
// mouse position is always the fallback
: drop.contains( drp, xy ) ? 1 : 0;
arr.push( data );
} while ( ++i < len ); // loop
// sort the drop targets
arr.sort( drop.sort );
// reset the loop
i = 0;
// loop through all of the targets again
do if ( data = arr[ i ] ){
// winners...
if ( data.winner && ia.drop.length < drop.multi ){
// new winner... dropstart
if ( !data.active[x] && !data.anyactive ){
// check to make sure that this is not prevented
if ( $special.drag.hijack( drop.event, "dropstart", dd, x, data.elem )[0] !== false ){
data.active[x] = 1;
data.anyactive += 1;
}
// if false, it is not a winner
else
data.winner = 0;
}
// if it is still a winner
if ( data.winner )
ia.drop.push( data.elem );
}
// losers...
else if ( data.active[x] && data.anyactive == 1 ){
// former winner... dropend
$special.drag.hijack( drop.event, "dropend", dd, x, data.elem );
data.active[x] = 0;
data.anyactive -= 1;
}
} while ( ++i < len ); // loop
} while ( ++x < end ) // loop
// check if the mouse is still moving or is idle
if ( drop.last && xy[0] == drop.last.pageX && xy[1] == drop.last.pageY )
delete drop.timer; // idle, don't recurse
else // recurse
drop.timer = setTimeout(function(){
drop.tolerate( dd );
}, drop.delay );
// remember event, to compare idleness
drop.last = drop.event;
}
};
// share the same special event configuration with related events...
$special.dropinit = $special.dropstart = $special.dropend = drop;
})(jQuery); // confine scope
\ No newline at end of file
/***
* Contains basic SlickGrid formatters.
*
* NOTE: These are merely examples. You will most likely need to implement something more
* robust/extensible/localizable/etc. for your use!
*
* @module Formatters
* @namespace Slick
*/
(function ($) {
// register namespace
$.extend(true, window, {
"Slick": {
"Formatters": {
"PercentComplete": PercentCompleteFormatter,
"PercentCompleteBar": PercentCompleteBarFormatter,
"YesNo": YesNoFormatter,
"Checkmark": CheckmarkFormatter
}
}
});
function PercentCompleteFormatter(row, cell, value, columnDef, dataContext) {
if (value == null || value === "") {
return "-";
} else if (value < 50) {
return "<span style='color:red;font-weight:bold;'>" + value + "%</span>";
} else {
return "<span style='color:green'>" + value + "%</span>";
}
}
function PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext) {
if (value == null || value === "") {
return "";
}
var color;
if (value < 30) {
color = "red";
} else if (value < 70) {
color = "silver";
} else {
color = "green";
}
return "<span class='percent-complete-bar' style='background:" + color + ";width:" + value + "%'></span>";
}
function YesNoFormatter(row, cell, value, columnDef, dataContext) {
return value ? "Yes" : "No";
}
function CheckmarkFormatter(row, cell, value, columnDef, dataContext) {
return value ? "<img src='../images/tick.png'>" : "";
}
})(jQuery);
This source diff could not be displayed because it is too large. You can view the blob instead.
(function ($) {
$.extend(true, window, {
Slick: {
Data: {
GroupItemMetadataProvider: GroupItemMetadataProvider
}
}
});
/***
* Provides item metadata for group (Slick.Group) and totals (Slick.Totals) rows produced by the DataView.
* This metadata overrides the default behavior and formatting of those rows so that they appear and function
* correctly when processed by the grid.
*
* This class also acts as a grid plugin providing event handlers to expand & collapse groups.
* If "grid.registerPlugin(...)" is not called, expand & collapse will not work.
*
* @class GroupItemMetadataProvider
* @module Data
* @namespace Slick.Data
* @constructor
* @param options
*/
function GroupItemMetadataProvider(options) {
var _grid;
var _defaults = {
groupCssClass: "slick-group",
groupTitleCssClass: "slick-group-title",
totalsCssClass: "slick-group-totals",
groupFocusable: true,
totalsFocusable: false,
toggleCssClass: "slick-group-toggle",
toggleExpandedCssClass: "expanded",
toggleCollapsedCssClass: "collapsed",
enableExpandCollapse: true
};
options = $.extend(true, {}, _defaults, options);
function defaultGroupCellFormatter(row, cell, value, columnDef, item) {
if (!options.enableExpandCollapse) {
return item.title;
}
var indentation = item.level * 15 + "px";
return "<span class='" + options.toggleCssClass + " " +
(item.collapsed ? options.toggleCollapsedCssClass : options.toggleExpandedCssClass) +
"' style='margin-left:" + indentation +"'>" +
"</span>" +
"<span class='" + options.groupTitleCssClass + "' level='" + item.level + "'>" +
item.title +
"</span>";
}
function defaultTotalsCellFormatter(row, cell, value, columnDef, item) {
return (columnDef.groupTotalsFormatter && columnDef.groupTotalsFormatter(item, columnDef)) || "";
}
function init(grid) {
_grid = grid;
_grid.onClick.subscribe(handleGridClick);
_grid.onKeyDown.subscribe(handleGridKeyDown);
}
function destroy() {
if (_grid) {
_grid.onClick.unsubscribe(handleGridClick);
_grid.onKeyDown.unsubscribe(handleGridKeyDown);
}
}
function handleGridClick(e, args) {
var item = this.getDataItem(args.row);
if (item && item instanceof Slick.Group && $(e.target).hasClass(options.toggleCssClass)) {
if (item.collapsed) {
this.getData().expandGroup(item.groupingKey);
} else {
this.getData().collapseGroup(item.groupingKey);
}
e.stopImmediatePropagation();
e.preventDefault();
}
}
// TODO: add -/+ handling
function handleGridKeyDown(e, args) {
if (options.enableExpandCollapse && (e.which == $.ui.keyCode.SPACE)) {
var activeCell = this.getActiveCell();
if (activeCell) {
var item = this.getDataItem(activeCell.row);
if (item && item instanceof Slick.Group) {
if (item.collapsed) {
this.getData().expandGroup(item.groupingKey);
} else {
this.getData().collapseGroup(item.groupingKey);
}
e.stopImmediatePropagation();
e.preventDefault();
}
}
}
}
function getGroupRowMetadata(item) {
return {
selectable: false,
focusable: options.groupFocusable,
cssClasses: options.groupCssClass,
columns: {
0: {
colspan: "*",
formatter: defaultGroupCellFormatter,
editor: null
}
}
};
}
function getTotalsRowMetadata(item) {
return {
selectable: false,
focusable: options.totalsFocusable,
cssClasses: options.totalsCssClass,
formatter: defaultTotalsCellFormatter,
editor: null
};
}
return {
"init": init,
"destroy": destroy,
"getGroupRowMetadata": getGroupRowMetadata,
"getTotalsRowMetadata": getTotalsRowMetadata
};
}
})(jQuery);
(function ($) {
/***
* A sample AJAX data store implementation.
* Right now, it's hooked up to load all Apple-related Digg stories, but can
* easily be extended to support and JSONP-compatible backend that accepts paging parameters.
*/
function RemoteModel() {
// private
var PAGESIZE = 50;
var data = {length: 0};
var searchstr = "apple";
var sortcol = null;
var sortdir = 1;
var h_request = null;
var req = null; // ajax request
// events
var onDataLoading = new Slick.Event();
var onDataLoaded = new Slick.Event();
function init() {
}
function isDataLoaded(from, to) {
for (var i = from; i <= to; i++) {
if (data[i] == undefined || data[i] == null) {
return false;
}
}
return true;
}
function clear() {
for (var key in data) {
delete data[key];
}
data.length = 0;
}
function ensureData(from, to) {
if (req) {
req.abort();
for (var i = req.fromPage; i <= req.toPage; i++)
data[i * PAGESIZE] = undefined;
}
if (from < 0) {
from = 0;
}
var fromPage = Math.floor(from / PAGESIZE);
var toPage = Math.floor(to / PAGESIZE);
while (data[fromPage * PAGESIZE] !== undefined && fromPage < toPage)
fromPage++;
while (data[toPage * PAGESIZE] !== undefined && fromPage < toPage)
toPage--;
if (fromPage > toPage || ((fromPage == toPage) && data[fromPage * PAGESIZE] !== undefined)) {
// TODO: look-ahead
return;
}
var url = "http://services.digg.com/search/stories?query=" + searchstr + "&offset=" + (fromPage * PAGESIZE) + "&count=" + (((toPage - fromPage) * PAGESIZE) + PAGESIZE) + "&appkey=http://slickgrid.googlecode.com&type=javascript";
switch (sortcol) {
case "diggs":
url += ("&sort=" + ((sortdir > 0) ? "digg_count-asc" : "digg_count-desc"));
break;
}
if (h_request != null) {
clearTimeout(h_request);
}
h_request = setTimeout(function () {
for (var i = fromPage; i <= toPage; i++)
data[i * PAGESIZE] = null; // null indicates a 'requested but not available yet'
onDataLoading.notify({from: from, to: to});
req = $.jsonp({
url: url,
callbackParameter: "callback",
cache: true, // Digg doesn't accept the autogenerated cachebuster param
success: onSuccess,
error: function () {
onError(fromPage, toPage)
}
});
req.fromPage = fromPage;
req.toPage = toPage;
}, 50);
}
function onError(fromPage, toPage) {
alert("error loading pages " + fromPage + " to " + toPage);
}
function onSuccess(resp) {
var from = this.fromPage * PAGESIZE, to = from + resp.count;
data.length = parseInt(resp.total);
for (var i = 0; i < resp.stories.length; i++) {
data[from + i] = resp.stories[i];
data[from + i].index = from + i;
}
req = null;
onDataLoaded.notify({from: from, to: to});
}
function reloadData(from, to) {
for (var i = from; i <= to; i++)
delete data[i];
ensureData(from, to);
}
function setSort(column, dir) {
sortcol = column;
sortdir = dir;
clear();
}
function setSearch(str) {
searchstr = str;
clear();
}
init();
return {
// properties
"data": data,
// methods
"clear": clear,
"isDataLoaded": isDataLoaded,
"ensureData": ensureData,
"reloadData": reloadData,
"setSort": setSort,
"setSearch": setSearch,
// events
"onDataLoading": onDataLoading,
"onDataLoaded": onDataLoaded
};
}
// Slick.Data.RemoteModel
$.extend(true, window, { Slick: { Data: { RemoteModel: RemoteModel }}});
})(jQuery);
\ No newline at end of file
......@@ -73,7 +73,28 @@ setup_section_data_download = (section) ->
location.href = url
else
$.getJSON url, (data) ->
section.find('.dumped-data-display').text JSON.stringify(data)
display = section.find('.dumped-data-display')
display.text JSON.stringify(data)
log data
# setup SlickGrid
options = enableCellNavigation: true, enableColumnReorder: false
# columns = [{id: feature, name: feature} for feature in data.queried_features]
log options
# log columns
# new Slick.Grid(display, data.students, columns, options)
data = [{'label1': 'val1,1', 'label2': 'val2,1'}, {'label1': 'val1,2', 'label2': 'val2,2'}]
columns = [{id: 'label1', name: 'Label One', width: 80, minWidth: 80}, {id: 'label2', name: 'Label Two'}]
log 'columns', columns
log 'data', data
grid = new Slick.Grid(display, data, columns, options)
grid.autosizeColumns()
grade_config_btn = section.find("input[name='dump-gradeconf']'")
grade_config_btn.click (e) ->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment