Skip to content

Commit

Permalink
Merge branch 'feature-2204-related-ui'
Browse files Browse the repository at this point in the history
  • Loading branch information
aron committed May 1, 2012
2 parents 4d7f0bf + 11927ee commit 93b4377
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 46 deletions.
42 changes: 42 additions & 0 deletions ckan/public/css/style.css
Expand Up @@ -1405,6 +1405,18 @@ body.editresources .error-explanation {
margin-bottom: 0;
}

.popover-title {
margin-bottom: 0;
}

.popover-inner {
background: #aaa;
}

.popover.right .arrow {
border-right-color: #aaa;
}

/* Chosen Form Styles */

.chzn-container-single {
Expand All @@ -1420,10 +1432,27 @@ body.editresources .error-explanation {
color: #808080;
}

.related-help {
opacity: 0.3;
position: relative;
top: 2px;
cursor: pointer;
}

.thumbnails li {
z-index: 0;
position: relative;
background-color: #fff;
}

.thumbnails li:nth-of-type(5n) {
clear: left;
}

.thumbnails li.expanded-description {
z-index: 1;
}

.thumbnail .heading {
font-weight: bold;
}
Expand All @@ -1444,6 +1473,19 @@ body.editresources .error-explanation {
height: auto;
}

.thumbnail .close {
padding-bottom: 7px;
padding-top: 2px;
position: relative;
top: -1px;
right: -1px;
display: none;
}

.thumbnail:hover .close {
display: block;
}

.thumbnail .empty {
color: #ccc;
}
Expand Down
107 changes: 86 additions & 21 deletions ckan/public/scripts/application.js
Expand Up @@ -133,23 +133,39 @@ CKAN.Utils = CKAN.Utils || {};
jQuery.fn.truncate = function (max, suffix) {
return this.each(function () {
var element = jQuery(this),
cached = element.text(),
length = max || element.data('truncate') || 30,
text = cached.slice(0, length),
expand = jQuery('<a href="#" />').text(suffix || '»');
isTruncated = element.hasClass('truncated'),
cached, length, text, expand;

if (isTruncated) {
element.html(element.data('truncate:' + (max === 'expand' ? 'original' : 'truncated')));
return;
}

cached = element.text();
length = max || element.data('truncate') || 30;
text = cached.slice(0, length);
expand = jQuery('<a href="#" />').text(suffix || '»');

// Bail early if there is nothing to truncate.
if (cached.length < length) {
return;
}

// Try to truncate to nearest full word.
while ((/\S/).test(text[text.length - 1])) {
text = text.slice(0, text.length - 1);
}

element.html(jQuery.trim(text));

expand.appendTo(element.append(' '));
expand.click(function (event) {
event.preventDefault();
element.text(cached);
element.html(cached);
});

element.addClass('truncated');
element.data('truncate:original', cached);
element.data('truncate:truncated', element.html());
});
};

Expand Down Expand Up @@ -1141,13 +1157,30 @@ CKAN.Utils = function($, my) {


my.relatedSetup = function(form) {
$('[rel=popover]').popover();

function addAlert(msg) {
$('<div class="alert alert-error" />').html(msg).hide().prependTo(form).fadeIn();
}

function relatedRequest(action, method, data) {
return $.ajax({
type: method,
dataType: 'json',
contentType: 'application/json',
url: CKAN.SITE_URL + '/api/3/action/related_' + action,
data: data ? JSON.stringify(data) : undefined,
error: function(err, txt, w) {
// This needs to be far more informative.
addAlert('<strong>Error:</strong> Unable to ' + action + ' related item');
}
});
}

// Center thumbnails vertically.
$('.related-items').each(function () {
var item = $(this);
var relatedItems = $('.related-items');
relatedItems.find('li').each(function () {
var item = $(this), description = item.find('.description');

function vertiallyAlign() {
var img = $(this),
Expand All @@ -1161,7 +1194,47 @@ CKAN.Utils = function($, my) {
}

item.find('img').load(vertiallyAlign);
item.find('.description').truncate();
description.data('height', description.height()).truncate();
});

relatedItems.on('mouseenter mouseleave', '.description.truncated', function (event) {
var isEnter = event.type === 'mouseenter'
description = $(this)
timer = description.data('hover-intent');

function update() {
var parent = description.parents('li:first'),
difference = description.data('height') - description.height();

description.truncate(isEnter ? 'expand' : 'collapse');
parent.toggleClass('expanded-description', isEnter);

// Adjust the bottom margin of the item relative to it's current value
// to allow the description to expand without breaking the grid.
parent.css('margin-bottom', isEnter ? '-=' + difference + 'px' : '');
description.removeData('hover-intent');
}

if (!isEnter && timer) {
// User has moused out in the time set so cancel the action.
description.removeData('hover-intent');
return clearTimeout(timer);
} else if (!isEnter && !timer) {
update();
} else {
// Delay the hover action slightly to wait to see if the user mouses
// out again. This prevents unwanted actions.
description.data('hover-intent', setTimeout(update, 200));
}
});

// Add a handler for the delete buttons.
relatedItems.on('click', '[data-action=delete]', function (event) {
var id = $(this).data('relatedId');
relatedRequest('delete', 'POST', {id: id}).done(function () {
$('#related-item-' + id).remove();
});
event.preventDefault();
});

$(form).submit(function (event) {
Expand All @@ -1186,18 +1259,10 @@ CKAN.Utils = function($, my) {
return;
}

$.ajax({
type: this.method,
url: CKAN.SITE_URL + '/api/3/action/related_create',
data: JSON.stringify(data),
success: function (data) {
window.location.reload();
},
error: function(err, txt, w) {
// This needs to be far more informative.
addAlert('<strong>Error:</strong> Unable to add related item');
}
});
relatedRequest('create', this.method, data).done(function () {
// TODO: Insert item dynamically.
window.location.reload();
});
});
};

Expand Down
6 changes: 3 additions & 3 deletions ckan/templates/_util.html
Expand Up @@ -126,16 +126,16 @@


<py:def function="related_summary(related)">
<li class="span3">
<li id="related-item-${related.id}" class="span3">
<div class="thumbnail">
<button py:if="c.user and (c.userobj.id == related.owner_id or h.check_access('package_update',{'id':c.pkg.id}))" class="close" onclick="related_delete('${related.id}');">×</button>
<button py:if="c.user and (c.userobj.id == related.owner_id or h.check_access('package_update',{'id':c.pkg.id}))" class="close" data-action="delete" data-related-id="${related.id}">×</button>
<a href="${related.url}" class="image">
<img src="${related.image_url}" width="210" py:if="related.image_url" />
<img src="/images/photo-placeholder.png" width="210" py:if="not related.image_url" />
</a>
<div class="caption">
<h5 class="heading" title="${related.title}">${h.markdown_extract(related.title, extract_length=30)}</h5>
<div class="description" data-truncate="60" py:if="related.description">${h.markdown_extract(related.description, extract_length=1000)}</div>
<div class="description" data-truncate="55" py:if="related.description">${h.markdown_extract(related.description, extract_length=1000)}</div>
<i class="empty" py:if="not related.description">No description for this item</i>
<p class="read-more"><a href="${related.url}">View this related item</a></p>
</div>
Expand Down
2 changes: 1 addition & 1 deletion ckan/templates/layout_base.html
Expand Up @@ -27,7 +27,7 @@
<link rel="alternate" type="application/atom+xml" title="${g.site_title} - Recent Revision History" href="${h.url_for(controller='revision', action='list', format='atom', days=1)}" />
</py:otherwise>
</py:choose>
<link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css' />
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,700' rel='stylesheet' type='text/css' />

<link rel="stylesheet" href="${h.url_for_static('/scripts/vendor/jqueryui/1.8.14/css/jquery-ui.custom.css')}" type="text/css" media="screen, print" />
<link rel="stylesheet" href="${h.url_for_static('/css/bootstrap.min.css')}" type="text/css" media="screen, projection" />
Expand Down
23 changes: 2 additions & 21 deletions ckan/templates/package/related_list.html
Expand Up @@ -18,12 +18,12 @@
- Related</py:def>

<py:def function="page_heading" property="dc:title">
${c.pkg_dict['title']} - Related
${c.pkg_dict['title']} - Related
</py:def>

<div py:match="content">
${add_related(c.pkg)}
<h3>Related items <a class="btn btn-small btn-primary pull-right" data-toggle="modal" href=".modal-add-related" py:if="c.user"><i class="icon-plus-sign icon-white"></i> Add related item</a></h3>
<h3>Related items <i class="related-help icon-info-sign" rel="popover" data-content="These are applications, ideas and visualisations that are using this dataset." data-original-title="What are related items?"></i> <a class="btn btn-small btn-primary pull-right" data-toggle="modal" href=".modal-add-related" py:if="c.user"><i class="icon-plus-sign icon-white"></i> Add related item</a></h3>
<div>
<div py:if="not c.pkg.related" class="span8 no-related-items">
There are no related items here yet<span py:if="c.user">, why not <a data-toggle="modal" href=".modal-add-related">add one</a>?</span>
Expand All @@ -40,25 +40,6 @@ <h3>Related items <a class="btn btn-small btn-primary pull-right" data-toggle="m
</div>

<py:def function="optional_head">
<script type="text/javascript" py:if="c.user">
function related_delete(related_id) {
var data = { 'id' : related_id }
$.ajax({
type: "post",
url: CKAN.SITE_URL + '/api/3/action/related_delete',
data: JSON.stringify(data),
success: function (data) {
window.location.reload();
},
error: function(err, txt, w) {
// This needs to be far more informative.
var msg = '<strong>Error:</strong> Unable to delete related item';
$('<div class="alert alert-error" />').html(msg).hide().prependTo($('div#main')).fadeIn();
}
});

}
</script>
<py:if test="config.get('rdf_packages')">
<link rel="alternate" type="application/rdf+xml" title="RDF/XML" href="${config['rdf_packages'] + '/' + c.pkg.id + '.rdf' }" />
<link rel="alternate" type="application/turtle" title="RDF/Turtle" href="${config['rdf_packages'] + '/' + c.pkg.id + '.ttl' }" />
Expand Down

0 comments on commit 93b4377

Please sign in to comment.