Skip to content

Instantly share code, notes, and snippets.

@e0da
Created April 13, 2012 17:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save e0da/2378789 to your computer and use it in GitHub Desktop.
Save e0da/2378789 to your computer and use it in GitHub Desktop.
The Gevirtz School Currently Funded Page
/*!
* The Gevirtz School Currently Funded Page v1.1.2
* http://education.ucsb.edu/Faculty-Research/Research-Office/currentlyfunded.htm
*
* Copyright (c) 2011, Justin Force
* Licensed under the BSD 3-Clause License
*/
/*jslint browser: true, indent: 2 */
/*global jQuery, muster */
(function ($) {
'use strict';
// XXX hack to work around Prototype's reckless manipulation of the Array prototype
if (Array.prototype._reverse) {
Array.prototype.reverse = Array.prototype._reverse;
}
// <a href=...first=first&last=last>last, first</a>
function bioLink(last, first) {
var link = $('<a>').attr('href', [
'http://education.ucsb.edu/Faculty-Research/Faculty-Listing/bio.php?',
'first=' + first,
'&last=' + last
].join(''));
link.text(last + ', ' + first);
return link;
}
function dollars(amount) {
var i,
parts = [];
// reverse the string, split it into chunks of 3 digis, join the chunks
// with commas, then reverse it again. Prepend a $ and return it.
amount = Array.prototype.reverse.call(amount.split('')).join('');
for (i = 0; i < amount.length; i += 3) {
parts.push(amount.slice(i, i + 3));
}
amount = Array.prototype.reverse.call(parts.join(',').split('')).join('');
return '$' + amount;
}
muster('ggsedb').query({
select: '*',
from: 'grants_and_contracts,grants_and_contracts_lookup,profile',
where: [
'grant_closed is null',
" and (grant_type = 'Grant' or grant_type = 'Income/MOU' or grant_type = 'Award')",
' and grants_and_contracts_id = grants_and_contracts.id and profile_id = profile.id'
].join('')
}, function () {
this.serializeBy('id').toTable(
// Column definitions: [format, label]
[
/*
* PI / Co-PI
*
* If there's only one value,
* "Lastname, Firstname"
* If there are multiples,
* "Lastone, Firstone / Lasttwo, Firsttwo / ... / Lastn, Firstn"
*/
[
'PI / Co-PI',
function () {
var i, len, names;
if (typeof this.last_name === 'string') {
return bioLink(this.last_name, this.first_name);
} else if (this.last_name instanceof Array) {
names = $('<div>'); // wrap it for appending
for (i = 0, len = this.last_name.length; i < len; i += 1) {
names.append(bioLink(this.last_name[i], this.first_name[i]));
if (i < len - 1) {
names.append(' / ');
}
}
return names.html(); // unwrap it
}
}
],
/*
* Contract or Grant
*
* Show the title as an h3, then show all of the other attributes in the
* same cell in a definition list (dl). After the table is rendered,
* we'll use the callback to pull the definition list into a cell in its
* own row below the normal row. So a single row will become
*
* ---------------------------------------------------------------
* | PI / Co-PI | Grant or Contract |
* ---------------------------------------------------------------
* | Baca, Michele / Force, Justin | Leaning to Yell at People |
* ---------------------------------------------------------------
* | Year Begin: |
* | 2009 |
* | Year End: |
* | 2012 |
* | Amount: |
* | $1,210,000 |
* | Sponsor: |
* | Spite Itself |
* | Abstract: |
* | A bunch of shapes and colors that make you feel superior. |
* ---------------------------------------------------------------
*/
[
'Contract or Grant',
function () {
var html, dl;
html = $('<div>'); // wrap it for appending
html.append($('<h3>' + this.title + '</h3>'));
dl = $('<dl>');
html.append(dl);
if (this.year_begin) {
dl.append('<dt class=yearBegin>Year Begin:</dt><dd>' + this.year_begin + '</dd>');
}
if (this.year_end) {
dl.append('<dt class=yearEnd>Year End:</dt><dd>' + this.year_end + '</dd>');
}
if (this.award_amount) {
dl.append('<dt class=amount>Amount:</dt><dd class=amount>' + dollars(this.award_amount) + '</dd>');
}
if (this.source) {
dl.append('<dt class=sponsor>Sponsor:</dt><dd class=sponsor>' + this.source + '</dd>');
}
if (this.abstract) {
dl.append('<dt class=abstract>Abstract:</dt><dd class=abstract>' + this.abstract + '</dd>');
}
return html.html(); // unwrap it
}
]
],
// Target container for table (<div id="currentlyFunded"></div>)
'#currentlyFunded',
/*
* toTable callback
*
* Post processing on the table. Since it's not entirely tabular, we need
* to pop out the definition list and put it on a new row, hide the row, and
* set the rows up to be opened and closed when the title is clicked.
*
* We also want to click the first header (th) once to sort by PI / Co-PI
*/
function () {
var table = $(this),
titles = table.find('h3'),
link = $('<a href=#>Expand / Collapse All</a>'),
rows = table.find('tbody tr');
rows.each(function () {
var row = $(this),
tr = $('<tr>'),
td = $('<td colspan=2>'),
h3 = row.find('h3'),
dl = row.find('dl');
tr.append(td.append(dl));
row.after(tr);
h3.data('open', function (animate) {
if (animate === undefined || animate === true) {
dl.slideDown();
} else {
dl.show();
}
});
h3.data('close', function (animate) {
if (animate === undefined || animate === true) {
dl.slideUp();
} else {
dl.hide();
}
});
h3.click(function () {
if (dl.is(':visible')) {
h3.data('close').call();
} else {
h3.data('open').call();
}
});
dl.hide();
// When a the table is sorted, the supplementary rows that we just
// added will not be considered. We need to put them back where they
// belong after a sort is performed.
$(window).bind('muster_sorted', function () {
row.after(tr);
});
});
// "Expand/collapse all" link before the table
link.toggle(function (event) {
event.preventDefault();
titles.each(function () {
$(this).data('open').call(this, false);
});
}, function (event) {
event.preventDefault();
titles.each(function () {
$(this).data('close').call(this, false);
});
});
table.before(link);
// Click first header to sort by PI / Co-PI
table.find('th:first').click();
}
);
});
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment