Commit 6490a268 authored by Kjetil Thuen's avatar Kjetil Thuen

Merge remote-tracking branch 'listinfo/master' into ListEntryInfoPlugin

parents d884d442 1fb06916
.*.swp
*_template.js
tags
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ListEntryInfo Plugin Demo</title>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/3.2.0/css/font-awesome.min.css" rel="stylesheet">
<link href="studylist.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/headjs/0.99/head.min.js"></script>
<script>
head.js("studylist.js");
</script>
</head>
<body>
<div class="container">
<div class="hero-unit">
<h1>Data fra Skolenesstar</h1>
Finn interresante studier i listen under.
</div>
<p>
franchise bridge cyber- nodality beef noodles tank-traps into systema city
uplink papier-mache soul-delay savant Tokyo courier uplink. vinyl car construct
urban dead camera drugs bicycle rain physical dead narrative neural concrete
-ware bridge. fluidity knife RAF alcohol -space otaku drugs San Francisco
military-grade wristwatch carbon warehouse warehouse ablative woman artisanal.
j-pop Chiba San Francisco cyber- cartel sunglasses film pistol sub-orbital
corrupted bridge rebar post- refrigerator drugs numinous. advert concrete
footage ablative futurity receding systemic table kanji sentient denim dolphin
augmented reality geodesic into pre-.
</p>
<p>
drugs garage neural knife singularity 3D-printed military-grade post-
Tokyo crypto- A.I. girl hacker sprawl chrome faded. saturation point
3D-printed vinyl knife claymore mine euro-pop military-grade soul-delay
cyber- euro-pop assault silent nodal point chrome physical stimulate.
garage render-farm numinous market vinyl sunglasses sentient beef noodles
table skyscraper BASE jump refrigerator augmented reality human Chiba
tank-traps. office wristwatch systemic pen tattoo marketing Tokyo DIY
-ware systema range-rover carbon urban grenade neon fluidity. digital
monofilament Legba beef noodles fetishism physical math- sentient modem
euro-pop man shrine rifle katana nodality futurity.
</p>
<p>
geodesic Chiba stimulate bomb nano- wonton soup pen paranoid spook hacker
courier hotdog wonton soup network assassin papier-mache. hacker decay
fetishism claymore mine plastic meta- film systemic film bomb otaku
3D-printed rifle assault claymore mine j-pop. knife katana rebar gang
apophenia savant weathered range-rover pre- neural artisanal bicycle
crypto- carbon carbon fetishism. sub-orbital engine shanty town tattoo
construct 8-bit plastic spook film denim shoes jeans engine refrigerator
dome shanty town. city denim refrigerator sensory A.I. realism A.I. film
dolphin cartel katana voodoo god narrative ablative beef noodles human.
</p>
<p>
narrative receding rain physical 8-bit refrigerator augmented reality
warehouse shoes lights franchise market cyber- rain dolphin -space.
vehicle tube systemic futurity urban wonton soup digital advert hacker
RAF long-chain hydrocarbons dome boat knife jeans tube. realism tattoo
market receding otaku human girl geodesic pen stimulate franchise lights
table warehouse girl corporation. lights augmented reality pre-
range-rover futurity long-chain hydrocarbons systemic warehouse Chiba
city sunglasses warehouse into warehouse drone soul-delay. hotdog knife
BASE jump motion semiotics corrupted denim post- stimulate bridge
cardboard fetishism vehicle voodoo god cardboard monofilament.
</p>
<div id="content"></div>
<p>
franchise bridge cyber- nodality beef noodles tank-traps into systema city
uplink papier-mache soul-delay savant Tokyo courier uplink. vinyl car construct
urban dead camera drugs bicycle rain physical dead narrative neural concrete
-ware bridge. fluidity knife RAF alcohol -space otaku drugs San Francisco
military-grade wristwatch carbon warehouse warehouse ablative woman artisanal.
j-pop Chiba San Francisco cyber- cartel sunglasses film pistol sub-orbital
corrupted bridge rebar post- refrigerator drugs numinous. advert concrete
footage ablative futurity receding systemic table kanji sentient denim dolphin
augmented reality geodesic into pre-.
</p>
<p>
drugs garage neural knife singularity 3D-printed military-grade post-
Tokyo crypto- A.I. girl hacker sprawl chrome faded. saturation point
3D-printed vinyl knife claymore mine euro-pop military-grade soul-delay
cyber- euro-pop assault silent nodal point chrome physical stimulate.
garage render-farm numinous market vinyl sunglasses sentient beef noodles
table skyscraper BASE jump refrigerator augmented reality human Chiba
tank-traps. office wristwatch systemic pen tattoo marketing Tokyo DIY
-ware systema range-rover carbon urban grenade neon fluidity. digital
monofilament Legba beef noodles fetishism physical math- sentient modem
euro-pop man shrine rifle katana nodality futurity.
</p>
<p>
geodesic Chiba stimulate bomb nano- wonton soup pen paranoid spook hacker
courier hotdog wonton soup network assassin papier-mache. hacker decay
fetishism claymore mine plastic meta- film systemic film bomb otaku
3D-printed rifle assault claymore mine j-pop. knife katana rebar gang
apophenia savant weathered range-rover pre- neural artisanal bicycle
crypto- carbon carbon fetishism. sub-orbital engine shanty town tattoo
construct 8-bit plastic spook film denim shoes jeans engine refrigerator
dome shanty town. city denim refrigerator sensory A.I. realism A.I. film
dolphin cartel katana voodoo god narrative ablative beef noodles human.
</p>
<p>
narrative receding rain physical 8-bit refrigerator augmented reality
warehouse shoes lights franchise market cyber- rain dolphin -space.
vehicle tube systemic futurity urban wonton soup digital advert hacker
RAF long-chain hydrocarbons dome boat knife jeans tube. realism tattoo
market receding otaku human girl geodesic pen stimulate franchise lights
table warehouse girl corporation. lights augmented reality pre-
range-rover futurity long-chain hydrocarbons systemic warehouse Chiba
city sunglasses warehouse into warehouse drone soul-delay. hotdog knife
BASE jump motion semiotics corrupted denim post- stimulate bridge
cardboard fetishism vehicle voodoo god cardboard monofilament.
</p>
</div>
</body>
</html>
/*jshint browser:true jquery:true */
(function ($) {
"use strict";
var settings = {};
var peekedList = null;
var horizontalCenter = Math.floor(window.innerWidth/2),
centerOfHeadline = 0,
focusedListElement = null,
targetTop = 0,
scrollListenersEnabled = false,
scrollInProgress = false,
handlersRegistered = false;
$.fn.listEntryInfo = function(options) {
settings = $.extend({
selectedClass: "listPeekSelected",
targetId: "listPeekTargetArea",
revealDivId: "listPeakRevealArea",
timeout: 100,
backgroundColor: "white",
extendedInfoFunc: function(id){ return "<strong>" + id + "</strong>";}
}, options );
peekedList = this;
targetTop = peekedList.position().top;
$('<div></div>').attr('id', settings.targetId).css({
width: '100%',
left: 0,
'min-height': '1em',
'z-index': '-2',
padding: '0px',
position: 'fixed',
top: targetTop
}).insertAfter(peekedList);
$('<div></div>').attr('id', settings.revealDivId).css({
position: 'fixed',
width: '70%',
left: '15%',
'z-index': 2,
display: 'none',
'max-height': '70%',
top: targetTop + $('#' + settings.targetId).height()
}).insertAfter(peekedList);
horizontalCenter = Math.floor(window.innerWidth/2);
centerOfHeadline = $('#' + settings.targetId).offset().top - $(window).scrollTop() + ($('#' + settings.targetId).height() / 2);
if (!handlersRegistered) {
registerEventHandlers();
}
resetGeometry();
return this;
};
var debounce = function (func, threshold, execAsap) {
var timeout;
return function debounced () {
var obj = this, args = arguments;
function delayed () {
if (!execAsap) {
func.apply(obj, args);
}
timeout = null;
}
if (timeout) {
clearTimeout(timeout);
} else if (execAsap) {
func.apply(obj, args);
}
timeout = setTimeout(delayed, threshold || timeout);
};
};
var showExpandedInfo = function() {
var listElem = peekedList.children("li." + settings.selectedClass),
details,
heightDiff,
marginDiff;
scrollListenersEnabled = false;
heightDiff = $('#' + settings.targetId).height() - listElem.height();
marginDiff = parseInt($('#' + settings.targetId).css('margin-top'), 0) + heightDiff;
if (heightDiff !== 0) {
$('#' + settings.targetId).animate({height: listElem.height(),'margin-top': marginDiff + 'px'}, 'fast');
}
var tarTop = $('#' + settings.targetId).position().top;
var listTop = listElem.offset().top;
var scrollVal = listTop - tarTop - marginDiff;
$('body').animate({scrollTop: scrollVal}, 'fast');
details = settings.extendedInfoFunc(listElem.attr('id'));
//listElem.find("div.abstract").html();
scrollInProgress = false;
if (details !== null) {
$('#' + settings.revealDivId).html(details);
$('#' + settings.revealDivId).slideDown('fast', function() {
scrollListenersEnabled = true;
});
}
};
var setSelectedElement = function (element, asap) {
if (!element) {
element = peekedList.children('li:first-child').get();
}
if (element) {
var listElem = $(element).closest('li');
if (listElem.is("LI") && listElem !== focusedListElement) {
$('#' + settings.revealDivId + ':visible').slideUp(settings.timeout);
peekedList.children('li').removeClass(settings.selectedClass);
listElem.addClass(settings.selectedClass);
focusedListElement = listElem;
if (asap) {
debounce(showExpandedInfo, 50, false)();
} else {
debounce(showExpandedInfo, 500, false)();
}
} else {
$('#' + settings.revealDivId).hide();
}
}
};
var findAndSelectElement = function() {
var newFocusedListElement = document.elementFromPoint(horizontalCenter, centerOfHeadline);
//TODO: Handle overshooting the list. Move target to bottom or top.
if (newFocusedListElement !== focusedListElement) {
setSelectedElement(newFocusedListElement);
}
};
var resetGeometry = function() {
var alreadyFocusedListElement,
bodyHeight = 0,
distanceFromListEndToBodyEnd = 0,
distanceFromTargetToViewportEnd = 0,
listHeight = 0,
viewPortHeight = 0;
alreadyFocusedListElement = peekedList.children("li." + settings.selectedClass);
if (alreadyFocusedListElement.length > 0) {
setSelectedElement(alreadyFocusedListElement[0]);
} else {
setSelectedElement();
}
listHeight = peekedList.outerHeight();
bodyHeight = $('body').outerHeight();
viewPortHeight = $(window).height();
distanceFromListEndToBodyEnd = bodyHeight - targetTop - listHeight;
distanceFromTargetToViewportEnd = viewPortHeight - targetTop - $('#' + settings.targetId).height();
if (distanceFromListEndToBodyEnd < distanceFromTargetToViewportEnd) {
peekedList.css("padding-bottom", "+=" + (distanceFromTargetToViewportEnd - distanceFromListEndToBodyEnd));
}
};
var registerEventHandlers = function() {
$(window).bind('scrollstart', function(){
if (scrollListenersEnabled) {
scrollInProgress = true;
$('#' + settings.revealDivId + ':visible').slideUp(settings.timeout);
}
});
$(window).bind('touchmove', function(){
//IOS specific touch event
if (scrollListenersEnabled) {
scrollInProgress = true;
$('#' + settings.revealDivId + ':visible').hide();
} else {
// console.log("scroll registered, but listener disabled");
}
});
$(window).bind('scrollstop', function(e){
if (scrollInProgress) {
findAndSelectElement();
}
});
peekedList.children("li").click(function() {
setSelectedElement($(this).get(), true);
});
$(window).resize(function() {
debounce(resetGeometry, 500, false)();
});
handlersRegistered = true;
};
}(jQuery));
/*
* James Padolsey's scrollstart and scrollstop event implementation
* Lifted from http://james.padolsey.com/javascript/special-scroll-events-for-jquery/
*/
inScroll = false;
(function(){
"use strict";
var special = $.event.special,
uid1 = 'D' + (+new Date()),
uid2 = 'D' + (+new Date() + 1);
special.scrollstart = {
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
} else {
inScroll = true;
evt.type = 'scrollstart';
$(this).trigger(evt.type, _args);
}
timer = setTimeout( function(){
timer = null;
}, special.scrollstop.latency);
};
if (!inScroll) {
$(this).bind('scroll', handler).data(uid1, handler);
}
},
teardown: function(){
$(this).unbind( 'scroll', $(this).data(uid1) );
}
};
special.scrollstop = {
latency: 100,
setup: function() {
var timer,
handler = function(evt) {
var _self = this,
_args = arguments;
if (timer) {
clearTimeout(timer);
}
if(inScroll) {
timer = setTimeout( function(){
inScroll = false;
timer = null;
evt.type = 'scrollstop';
$(this).trigger(evt.type, _args);
}, special.scrollstop.latency);
}
};
$(this).bind('scroll', handler).data(uid2, handler);
},
teardown: function() {
$(this).unbind( 'scroll', $(this).data(uid2) );
}
};
}());
body {
background-color: #f5f3ec;
color: #5f5a49;
}
.hero-unit {
color: #eee;
background-color: rgba(0,0,0,0.8);
}
ul#studies_list {
width: 80%;
margin: auto;
}
ul#studies_list li {
color: #5f5a49;
overflow: hidden;
border-bottom: 1px solid #5f5a49;
}
#studies_list li div.study_title {
margin: 0px;
padding: 0.5em;
z-index: 3;
}
ul#studies_list li.selected {
color: #eee;
}
#target {
background-color: rgba(0,0,0,0.8);
}
#expander {
background-color: rgba(0,0,0,0.8);
}
#expander button {
margin: 0 0 1em 1em ;
}
div.metadata div.abstract {
max-height: 6em;
margin-bottom: 0.5em;
overflow: hidden;
color: white;
padding: 0em 1em 1em 1em;
}
<ul class="nav nav-list" id="studies_list">
{{#each studies}}
<li id="{{id}}">
<div class="study_title">{{name}}</div>
</li>
{{/each}}
</ul>
head.js("http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js")
.js("http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.0/handlebars.min.js")
.js("http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js")
.js("listEntryInfo.js")
//Precompiled handlebars templates. Compile using handlebars util before deploying
.js("studymetadata_template.js")
.js("studylist_template.js", function() {
var jsondata = {};
var build_list = function() {
var template = Handlebars.templates.studylist;
var listhtml = template(jsondata);
$('#content').html(listhtml);
$('#studies_list').listEntryInfo({
selectedClass: "selected",
targetId: "target",
revealDivId: "expander",
extendedInfoFunc: get_metadata
});
};
var load_data = function() {
$.ajax({
url: "https://nesstar-dev.nsd.uib.no/nesstardrop/study/list",
datatype: "json",
context: document.body
}).done(function(data) {
jsondata = data;
build_list();
}).error(function(jqXHR, exception) {
alert("Loading data failed:\n" + exception);
});
};
var get_metadata = function (id) {
var studyMetadata = jsondata.studies.filter(function(v) {
return v.id === id; // filter out appropriate one
});
var studyMetadataTemplate = Handlebars.templates.studymetadata;
var metadatahtml = studyMetadataTemplate(studyMetadata.length > 0 ? studyMetadata[0] : {});
return metadatahtml;
};
head.ready(function() {
load_data();
});
});
<div class="metadata" id="studymetadata">
<div class="abstract">{{abstractText}}</div>
<div class="buttons">
<button class="btn btn-info"><i class="icon-info-sign"></i> Mer metadata</button>
<button class="btn btn-success"><i class="icon-ok-sign"></i> Velg studie</button>
</div>
</div>
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