Skip to content

Commit

Permalink
Add truncation plugin to apply to html+text desc blocks [ref #6685]
Browse files Browse the repository at this point in the history
  • Loading branch information
mheppler committed Feb 26, 2021
1 parent 54a47cf commit 698c9b7
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/main/webapp/dataverse_template.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
<script defer="defer" src="#{resource['js/dv_rebind_bootstrap_ui.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/owl.carousel.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/jquery.matchHeight.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/jquery.sharrre.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/jquery.sharrre.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/jquery.truncate.js']}?version=#{systemConfig.getVersion()}"></script>
<script defer="defer" src="#{resource['js/clipboard.min.js']}?version=#{systemConfig.getVersion()}"></script>
<ui:fragment rendered="#{systemConfig.isShibPassiveLoginEnabled()}">
<script defer="defer" src="#{resource['js/shib/isPassive.js']}"></script>
Expand Down
26 changes: 25 additions & 1 deletion src/main/webapp/resources/css/structure.css
Original file line number Diff line number Diff line change
Expand Up @@ -627,13 +627,37 @@ div.edit-field div.ui-message {margin:6px 0;}
.metadata-container table.metadata {border-collapse:separate;margin:0 4px;width:100%;}
.metadata-container table.metadata th {width:25%;vertical-align:top;padding:6px 12px;}
.metadata-container table.metadata td {padding:6px 12px;vertical-align:top;}
@media(max-width:767px){

/* TO-DO FIX max-width:1199px FOR SUMMARY BLOCK ONLY, NOT OTHER PAGES */
@media(max-width:1199px){
.metadata-container table.metadata th, .metadata-container table.metadata td {display:block;width:100%;}
.metadata-container table.metadata th {padding-bottom:0;}
.metadata-container table.metadata td {padding-left:30px;}
}
.panel-body.metadata-container {padding:15px 0;}
.metadata-logo {max-width:180px;max-height:40px;}
.metadata-container .truncate-more-link, .metadata-container .collapse-less-link {color: #337AB7; cursor: pointer; cursor: hand;}

/* HTML METADATA OVERWRITE */
.metadata-container table.metadata td > div {
/* https://stackoverflow.com/a/24158056 */
/*-moz-white-space: pre-wrap;
white-space: pre-wrap;
hyphens: auto;
-ms-word-break: break-all;
-ms-word-wrap: break-all;
-webkit-word-break: break-word;
-webkit-word-wrap: break-word;
word-break: break-word;
word-wrap: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;*/
}
.metadata-container pre {
white-space: pre-wrap !important;
}

/* Primefaces vs Bootstrap selectOneMenu fix */
div.ui-selectonemenu.form-control {padding:0px;}
Expand Down
64 changes: 61 additions & 3 deletions src/main/webapp/resources/js/dv_rebind_bootstrap_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ function bind_bsui_components(){
// Hide open tooltips + popovers
$('.bootstrap-button-tooltip, [data-toggle="tooltip"]').tooltip("hide");
$("[data-toggle='popover']").popover("hide");

// Truncate content
contentTruncate();

// Truncate checksums
checksumTruncate();

// Tooltips + popovers
bind_tooltip_popover();

// Disabled pagination links
disabledLinks();

// Truncate checksums
checksumTruncate();

// Sharrre
sharrre();

Expand Down Expand Up @@ -157,7 +160,62 @@ function sharrre(){
}
});
}

/*
* Truncate any metadata content
*/
function contentTruncate(){

// jquery.truncate.js
// HTML-safe truncation
// https://github.com/pathable/truncate

// WHAT ARE WE TRUNCATING
// TO-DO IS THERE A MORE SCALABLE SELECTOR METHOD THAN THIS? ADD TRUNCATE CLASS TO OBJECTS? e.g. span.checksum-truncate
$('#dsDescription td div').each(function () {

// GET THE DESC TEXT AND HTML
var truncateThis = $(this).html();

// TO-DO TRUNCATE BTN LABEL TEXT FROM BUNDLE
var readMoreBtn = '... <button class="btn btn-link truncate-more-link" style="color:teal !important;margin:0;padding:0;" type="button" data-toggle="tooltip" data-original-title="Click to read the full description." aria-expanded="false" aria-controls="#dsDescription">Read More [+]</button>';
var readLessBtn = '<button class="btn btn-link collapse-less-link" style="margin:0;padding:0;" type="button" data-toggle="tooltip" data-original-title="Click to collapse the description." aria-expanded="true" aria-controls="#dsDescription">Read Less [-]</button>';

if ($(this).hasClass('thisWasTruncated')) {
// DO NOTHING
}
else {

// TO-DO PUT THE ORIGINAL FULL DESCRIPTION SOMEWHERE
// $('#dsDescription td div').attr({'data-html':'true', 'data-original-text':truncateThis});

var thisWasTruncated = jQuery.truncate(truncateThis, {
length: 500,
words: true,
keepFirstWord: true,
ellipsis: readMoreBtn,
finishBlock: true
});

// ... add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!!
$(this).toggleClass('thisWasTruncated').html(thisWasTruncated).find('img').attr('class', 'img-responsive');

// Return full description on Read More link click ++ add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!!
$(document).on('click', 'button.truncate-more-link', function() {
$(this).tooltip('hide').parent('div').toggleClass('thisWasTruncated').html(truncateThis).append(readLessBtn).find('img').attr('class', 'img-responsive');
$('button.collapse-less-link').tooltip();
});
// ... add responsive img class ++ link target ... DO THIS ANYWAY SOMEWHERE ELSE!!
$(document).on('click', 'button.collapse-less-link', function() {
$(this).tooltip('hide').parent('div').toggleClass('thisWasTruncated').html(thisWasTruncated).find('img').attr('class', 'img-responsive');
$('button.truncate-more-link').tooltip();
});

}

});
}

/*
* Truncate file checksums
*/
Expand Down
103 changes: 103 additions & 0 deletions src/main/webapp/resources/js/jquery.truncate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
(function($) {

// Matches trailing non-space characters.
var chop = /(\s*\S+|\s)$/;

// Matches the first word in the string.
var start = /^(\S*)/;

// Return a truncated html string. Delegates to $.fn.truncate.
$.truncate = function(html, options) {
return $('<div></div>').append(html).truncate(options).html();
};

// Truncate the contents of an element in place.
$.fn.truncate = function(options) {
if ($.isNumeric(options)) options = {length: options};
var o = $.extend({}, $.truncate.defaults, options);

return this.each(function() {
var self = $(this);

if (o.noBreaks) self.find('br').replaceWith(' ');

var text = self.text();
var excess = text.length - o.length;

if (o.stripTags) self.text(text);

// Chop off any partial words if appropriate.
if (o.words && excess > 0) {
var truncated = text.slice(0, o.length).replace(chop, '').length;

if (o.keepFirstWord && truncated === 0) {
excess = text.length - start.exec(text)[0].length - 1;
} else {
excess = text.length - truncated - 1;
}
}

if (excess < 0 || !excess && !o.truncated) return;

// Iterate over each child node in reverse, removing excess text.
$.each(self.contents().get().reverse(), function(i, el) {
var $el = $(el);
var text = $el.text();
var length = text.length;

// If the text is longer than the excess, remove the node and continue.
if (length <= excess) {
o.truncated = true;
excess -= length;
$el.remove();
return;
}

// Remove the excess text and append the ellipsis.
if (el.nodeType === 3) {
// should we finish the block anyway?
if (o.finishBlock) {
$(el.splitText(length)).replaceWith(o.ellipsis);
} else {
$(el.splitText(length - excess - 1)).replaceWith(o.ellipsis);
}
return false;
}

// Recursively truncate child nodes.
$el.truncate($.extend(o, {length: length - excess}));
return false;
});
});
};

$.truncate.defaults = {

// Strip all html elements, leaving only plain text.
stripTags: false,

// Only truncate at word boundaries.
words: false,

// When 'words' is active, keeps the first word in the string
// even if it's longer than a target length.
keepFirstWord: false,

// Replace instances of <br> with a single space.
noBreaks: false,

// if true always truncate the content at the end of the block.
finishBlock: false,

// The maximum length of the truncated html.
length: Infinity,

// The character to use as the ellipsis. The word joiner (U+2060) can be
// used to prevent a hanging ellipsis, but displays incorrectly in Chrome
// on Windows 7.
// http://code.google.com/p/chromium/issues/detail?id=68323
ellipsis: '\u2026' // '\u2060\u2026'

};

})(jQuery);

0 comments on commit 698c9b7

Please sign in to comment.