I'm trying to implement a function that yields highlighted and summarized preview of the given text. Please see the following code snippet.
<div>
Search:
<input value='vestibulum' disabled/>
</div>
<div style='margin-top: 20px'>Output I want:</div>
<div style='border: 1px solid #000; padding: 10px'>
...diam lectus <mark>vestibulum</mark> risus, eu <mark>vestibulum</mark> turpis quam in lorem. Vivamus posuere nibh leo, sit amet pharetra velit convallis sed. Sed porta convallis justo ac auctor. <mark>Vestibulum</mark> ante ipsum primis in faucibus orci luctus...
</div>
<div style='margin-top: 20px'>Original Text:</div>
<div style='border: 1px solid #000; padding: 10px'>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean at lacus tempus, pharetra dui vel, egestas massa. Integer metus enim, varius sed quam sed, convallis volutpat lectus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur, tortor quis sagittis sollicitudin, diam lectus vestibulum risus, eu vestibulum turpis quam in lorem. Vivamus posuere nibh leo, sit amet pharetra velit convallis sed. Sed porta convallis justo ac auctor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nulla et luctus leo, eu dignissim nunc. Phasellus vel fringilla sapien. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aenean et dui ut ipsum pretium ullamcorper. Aenean hendrerit dolor et lorem auctor ullamcorper.
</p>
<p>
Donec aliquet, purus ut tempor efficitur, velit eros luctus turpis, in pretium elit augue vel eros. Morbi eget dui ullamcorper, semper magna sit amet, cursus nulla. Aenean augue dolor, varius eu orci a, efficitur auctor diam. Quisque tempor lacus dolor. Aliquam erat volutpat. Donec imperdiet pellentesque nunc, sed accumsan sem lacinia sed. In hac habitasse platea dictumst. Nam placerat odio et leo ultricies ultrices. Cras nulla lacus, maximus in risus ut, auctor auctor vestibulum.
</p>
</div>
The function I want to implement should look like this:
const getSummarizedPreview = (query, text, windowSize) => {
// query: The word that should be highlighted. It's just one word, not a phrase.
// text: Original Text.
// windowSize: The maximum length of text returned.
}
Note that the last word of the text is also vestibulum, but getSummarizedPreview smartly chose more relevant part of the text based on the frequency of the query.
I think this might be pretty complicated to implement, so any advice, pseudocode, or introduction to library that does the simliar thing would be appreciated.
Thank you.
You can use full text search of Elasticsearch. See quick intro here.
OR you can implement this feature by yourself:
Look in your original text i see it have multi paragraph ( tag). You can split it into an array, then loop all of this array elements.
In the loop, using regex like below to find count frequency of appearance of query word:
var temp = "This is a string.";
var count = (temp.match(/is/g) || []).length;
console.log(count);
Get element have max count.
Replace query word with highlighted query word, like: vestibulum with <mark>vestibulum</mark>
Return formatted string for display highlighted matched query word.
This is an interesting question and I am also looking for a better solution.
Related
I am attempting to implement readmore.js into my code but I am continuously running into readmore.js is not a function error. I've read over the documentation multiple times and I am unable to figure out what I am doing wrong. When implemented correctly should include a "READ MORE" button to expand the text in its entirety.
I've included the HTML script tag that is presented in the github
I've made sure I included a jquery cdn before the readmore.js
I've included a class name of article
I've attempted to wrap the .readmore in a function such as :
$(function () { $('.article').readmore({speed: 75, lessLink: 'Read less'});});
Here is a snippet of code that I am working with:
const data = [{ paragraph: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id aliquam nibh. Aenean a porttitor ipsum. Vestibulum ut sagittis dui, nec pharetra eros. Vivamus tempus fringilla dictum. Maecenas facilisis auctor magna, a accumsan nunc molestie dictum. In tempus rhoncus condimentum. Aenean interdum leo et velit pellentesque dapibus. Vivamus nunc orci, commodo sit amet dui a, lobortis finibus arcu. Maecenas metus mauris, tincidunt sit amet ex id, gravida commodo nunc. Donec consequat tristique lacinia. Pellentesque commodo eu tortor sit amet rutrum. Vivamus mollis eros ipsum, in vestibulum lorem tempor sit amet. Morbi egestas orci sem, posuere rutrum augue malesuada eget. Mauris ultricies egestas luctus. Praesent at dignissim nunc. Aliquam erat volutpat."},{
paragraph: "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam porttitor tincidunt fringilla. In ullamcorper vitae sapien eget ornare. Nulla quis lacus condimentum lacus tincidunt consectetur ut in ante. Suspendisse a eleifend est. Pellentesque eu ornare magna. Vestibulum ac mi sit amet arcu tristique volutpat in id nisl. Aenean interdum et odio gravida hendrerit. Pellentesque at diam lacus. Mauris elementum ultricies imperdiet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus metus ligula, molestie at laoreet id, convallis et felis. Nullam molestie, augue vel interdum semper, dui massa feugiat risus, non sodales est massa non arcu. Vivamus ut sodales metus."
}
]
let htmlOutput = ""
for (let i = 0; i < data.length; i++) {
htmlOutput += "<div>" + data[i].paragraph + "</div>"
}
$("#report").html(htmlOutput)
$('.article').readmore({
speed: 75,
lessLink: 'Read less'
});
<div id="report" class="article">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="/node_modules/readmore-js/readmore.min.js"></script>
My expected outcome is to be able to include the .readmore function and have a "read more" that will expand the text once clicked.
You will have to download the readmore.min.js file from the repo. The file is located here.
https://github.com/jedfoster/Readmore.js/blob/master/readmore.min.js
Then you can include it in your project by putting it in the same directory as your index.html file and add a script tag like this
<script src="readmore.min.js"></script>
hi this might have been solved but ill add my 2c.
from your code it seem that you are adding the text inside a nested div instead of the parent div with the article class.
try adding "id='report' class= 'article' " inside the for loop div and check if the plugin works
I have a table that has columns that can grow based on the content in them but I would like to restrict that growth by adding a "Read More" link after two lines of a row for a particular column. So lets say I have a td as given below:
<table>
<tr>
<td role="gridcell" style="padding-bottom: 50px;">
<p><span style="font-family:'Open Sans', Arial, sans-serif;font-size:14px;line-height:20px;text-align:justify;background-color:#ffffff;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi malesuada luctus porta. Sed eu magna quis sem bibendum tincidunt. Pellentesque rhoncus efficitur risus, eu pretium metus consequat quis. Phasellus eget porta augue. Fusce porta magna nisi, vel euismod ante ultrices in. Vestibulum faucibus, lectus sit amet ornare efficitur, est tellus egestas sem, nec consequat tellus lorem eget elit. Morbi venenatis convallis lorem, eu ornare eros blandit posuere.</span>
</p>
<p><span style="font-family:'Open Sans', Arial, sans-serif;font-size:14px;line-height:20px;text-align:justify;background-color:#ffffff;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi malesuada luctus porta. Sed eu magna quis sem bibendum tincidunt. Pellentesque rhoncus efficitur risus, eu pretium metus consequat quis. Phasellus eget porta augue. Fusce porta magna nisi, vel euismod ante ultrices in. Vestibulum faucibus, lectus sit amet ornare efficitur, est tellus egestas sem, nec consequat tellus lorem eget elit. Morbi venenatis convallis lorem, eu ornare eros blandit posuere.</span>
</p>
</td>
</tr>
</table>
I would like to wrap both the paragraphs and only show two lines from the above td and append a "Read More" button such that upon clicking that it shows the remaining content. Any suggestions?
Code:
listItems.each(function(i, listItems) {
var max_length = 150; // set the max content length before a read more link will be added
// check for content length
if ($(this).html().length > max_length) {
// split the content in two parts
var short_content = $(this).html().substr(0, max_length);
var long_content = $(this).html().substr(max_length);
// Alter the html to allow the read more functionality
$(this).html(short_content +
'<br/>Read More' +
'<span class="more_text" style="display:none;">' + long_content + '</span>');
$(this).find('a.read_more').click(function(event) { // find the a.read_more element within the new html and bind the following code to it
event.preventDefault(); // prevent the a from changing the url
$(this).hide(); // hide the read more button
$(this).parents().find('.more_text').show(); // show the .more_text span
});
}
}
Here is really simple solution, which takes only the text from the target cell, split it by words, than replace the original cell html with the first 10 word, than append link, which click handler will append the rest of the original text:
$(function() {
// Get the cell
var td = $("td.more");
// Get the text and split it into words
var words = td.text().trim().split(" ").filter(function(w) {
return (w.length > 0) && (w != "\n");
});
// Get the basic text first 10 words
var base = words.slice(0, 10)
// Get the rest
var rest = words.slice(10);
// Replace cell original text with first 10 words
td.html(base.join(" "));
// Append more link to the cell
$("<a>", {
html: " more..."
}).css("color", "blue").appendTo(td).click(function() {
// Remove the link
$(this).remove();
// Append the rest of the original text
td.append(" " + rest.join(" "));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="more" role="gridcell" style="padding-bottom: 50px;">
<p>
<span>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi malesuada luctus porta. Sed eu magna quis sem bibendum tincidunt. Pellentesque rhoncus efficitur risus, eu pretium metus consequat quis. Phasellus eget porta augue. Fusce porta magna nisi, vel euismod ante ultrices in. Vestibulum faucibus, lectus sit amet ornare efficitur, est tellus egestas sem, nec consequat tellus lorem eget elit. Morbi venenatis convallis lorem, eu ornare eros blandit posuere.
</span>
</p>
<p>
<span>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi malesuada luctus porta. Sed eu magna quis sem bibendum tincidunt. Pellentesque rhoncus efficitur risus, eu pretium metus consequat quis. Phasellus eget porta augue. Fusce porta magna nisi, vel euismod ante ultrices in. Vestibulum faucibus, lectus sit amet ornare efficitur, est tellus egestas sem, nec consequat tellus lorem eget elit. Morbi venenatis convallis lorem, eu ornare eros blandit posuere.
</span>
</p>
</td>
</tr>
</table>
I have a hover element in which when user hover over it will get text from a hidden element and when it hovers out it will reassign in its previous value.
My html is sort of like this.
<div id="product-name">Hover Here</div>
<br>
<div id="result-content">Lorem ipsum dolor sit amet.</div>
<div class="hidden">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla pellentesque mi leo, ut cursus tellus tempor nec. Sed facilisis augue neque, a ornare urna ornare in. Etiam consequat, dui sit amet pretium bibendum, ante ipsum ullamcorper libero, vel tempus erat urna sed purus. Quisque id ultricies elit, non posuere nunc. Etiam pulvinar magna tortor, at aliquet turpis interdum et. Duis imperdiet enim ante, sit amet pretium enim aliquet venenatis. Donec ac nibh nibh. Interdum et malesuada fames ac ante ipsum primis in faucibus. Morbi aliquam est adipiscing volutpat pulvinar. Curabitur leo augue, iaculis id lacus sed, dictum vestibulum nulla. Etiam sit amet tempus felis, ac aliquet erat. Nunc ullamcorper consequat mattis. In molestie, tortor ac venenatis dapibus, eros neque vulputate nulla, in tristique ante diam non turpis. Maecenas mattis in risus eu ornare. Cras a rutrum nulla. Proin sagittis justo vehicula augue porttitor vulputate.
</div>
and javascript is this:
var object = document.getElementById("product-name");
object.onmouseover=function(){
document.getElementById("result-content").innerHTML = document.getElementsByClassName("hidden")[0].innerHTML;
};
object.onmouseout=function(){
document.getElementById("result-content")[0].innerHTML = document.getElementById("result-content").innerHTML;
};
jsfiddle.net
But my mouseout event failed me here. Can anyone help me out here how can i resolve this. I can't use jQuery in this dom only javascript, but I wouldn't mind if anybody show me a better approach to resolve javascript mouseout/mouseover paradigm.
Fiddle Demo
You need to store initial contents of the block.
var object = document.getElementById("product-name");
var currentHtml = document.getElementById("result-content").innerHTML;
object.onmouseover=function(){
document.getElementById("result-content").innerHTML = document.getElementsByClassName("hidden")[0].innerHTML;
this.onmouseout=function(){
document.getElementById("result-content").innerHTML = currentHtml;
}
};
document.getElementById("result-content")[0].innerHTML = document.getElementById("result-content").innerHTML; will take you nowhere. You have to preserve the value somewhere.
If you fancy a bit different approach then try this.
document.querySelector("#product-name").addEventListener("mouseover", function(){
var txt = document.querySelector("#result-content").innerHTML;
document.querySelector("#result-content").innerHTML = document.querySelector(".hidden").innerHTML;
this.addEventListener("mouseout", function(){
document.querySelector("#result-content").innerHTML = txt;
});
});
jsfiddle Demo
document.querySelector is supported in most browser.
http://caniuse.com/queryselector
I think, in this case must save somewhere previous state, like:
var object = document.getElementById("product-name"),
previous_state = document.getElementById("result-content").innerHTML;
Might not be the best approach, but without major changes in code should look like this:
jsfiddle
try this one for mouse out
object.onmouseout=function(){
document.getElementById("result-content").innerHTML ='Lorem ipsum dolor sit amet.';
};
Does anyone know of a clean and easy way to truncate a section of text to two lines. This is what I am trying to truncate (p element):
<blockquote><p>“<?=$test_entry ?>”</p></blockquote><cite><?=$test_name ?></cite>
I have tried various solutions including clamp.js (which doesnt even work properly in the example supplied)
I have tried CSS3 solutions using text-overflow but these only truncate to one line.
All other javascript examples use string length which breaks if the text size changes, if special chars are encoded and under many other conditions.
I am happy to change the markup if necessary I just want to be able to truncate text to fit two lines within a div box and have it end with an elipses (...) or even better with (..."). I thought this would be straightforward but apparantly not.
Can anyone point me to an existing solution or give me a clue where to start with this. Any help much appreciated.
Here you can find an existing solution based on jQuery, which should be working cross browser, in this SO question.
This is a very simple solution to truncate the multiline paragraph and this will also add the ellipsis dots at the end of the last line.
p.truncate_text {
color:red;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce quis justo nibh. Phasellus ac ante enim. Mauris ullamcorper mauris nec laoreet lacinia. Sed interdum tincidunt tempor. Cras euismod, tellus id consequat varius, est lectus sagittis justo, sit amet egestas sem dolor sit amet arcu. In commodo nibh ac nisi tincidunt tincidunt. Nullam suscipit, mi nec posuere imperdiet, odio est pellentesque arcu, at varius massa ex nec urna.</p>
<p class="truncate_text">This paragraph will truncate into 3 lines Quisque ut purus nunc. Aenean vitae lectus maximus, fermentum justo quis, lobortis neque. Curabitur lacinia in massa in efficitur. Praesent et dolor et ex sodales volutpat vel lobortis ligula. Maecenas convallis luctus tempus. Vivamus non libero nisi. Donec facilisis, odio sed dictum consectetur, eros dolor pellentesque quam, ut ornare est ligula eu ligula. Etiam elementum nibh lectus, quis sodales massa malesuada vitae. Etiam finibus quam eget condimentum rutrum. Donec et velit ipsum. </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce quis justo nibh. Phasellus ac ante enim. Mauris ullamcorper mauris nec laoreet lacinia. Sed interdum tincidunt tempor. Cras euismod, tellus id consequat varius, est lectus sagittis justo, sit amet egestas sem dolor sit amet arcu. In commodo nibh ac nisi tincidunt tincidunt. Nullam suscipit, mi nec posuere imperdiet, odio est pellentesque arcu, at varius massa ex nec urna.</p>
Use the textarea element to limit text rows!
<textarea rows="2" readonly disabled>Try enameling the ricotta broccolis with aged champaign and rum, warmed. </textarea>
You could then use a pseudo element :after to add an ellipsis or a 'Read more'.
Don't forget the attributes 'readonly' and 'disabled'. Readonly prevents textarea from being interacted with by the user. Disabled prevents any forms in the page from submitting the values.
I have a div, which has content in it.
The content could be really long, or the content could be really small.
I don't want the content to stretch the page on page load if it is long, I want them to click a "more" link and it will slide down and reveal the rest of the content.
For example:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vulputate mi egestas ligula feugiat volutpat. Morbi eros felis, aliquam in varius id, sodales quis nunc. Nulla sagittis consectetur arcu, sed auctor odio placerat quis. Praesent vitae lacus neque. Curabitur ultricies tristique sollicitudin. Suspendisse malesuada nunc at augue interdum at facilisis ipsum gravida.
Below it is a bar or link that says "show the rest"
Up on click, this div lengthens and shows the rest of the content:
Nunc congue sapien sed sem tincidunt ut adipiscing neque lacinia. Praesent facilisis quam sed tellus sodales id tristique massa ullamcorper. Donec sem turpis, cursus in elementum id, tincidunt a libero. Etiam feugiat, sem quis dictum imperdiet, nisl ante pharetra erat, ut ornare nulla justo ac sapien.
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Suspendisse vulputate mi egestas
ligula feugiat volutpat. Morbi eros
felis, aliquam in varius id, sodales
quis nunc. Nulla sagittis consectetur
arcu, sed auctor odio placerat quis.
Praesent vitae lacus neque. Curabitur
ultricies tristique sollicitudin.
Suspendisse malesuada nunc at augue
interdum at facilisis ipsum gravida.
Nunc congue sapien sed sem tincidunt
ut adipiscing neque lacinia. Praesent
facilisis quam sed tellus sodales id
tristique massa ullamcorper. Donec sem
turpis, cursus in elementum id,
tincidunt a libero. Etiam feugiat, sem
quis dictum imperdiet, nisl ante
pharetra erat, ut ornare nulla justo
ac sapien.
I know itll be hard to control what will be cut off, blah blah but it isn't for that type of thing. The div does not contain text, it contains a list of features, for example X listing may have 4 features, Z listing may have 14 features, instead of the page stretching if the listing has 14 features listed vertically, we want it to only show a few and then they must click "show me more" for it to slide down and reveal the rest.
How would I go about doing this? Even a jsfiddle to demonstrate it?
Thank you :)
Try giving a fixed height to the div. You can use CSS for this. Then compare height of the list with the outer div. If it is greater show the bar with link show more. On click of this bar you can manage the height of outer div. Like this -
CSS
.parentDiv{
height:some fixed height px;
overflow: auto;
}
Jquery
var parentHeight = $('.parentDiv').height();
var listHeight = $('#List').outerHeight(true);
if(parentHeight < listHeight) {
$('#linkBar').show();
}
$('#linkBar').click(function(){
//$('.parentDiv').height(listHeight);
//OR you can use following code to animate the div
$('.parentDiv').animate({'height': listHeight}, 'slow')
});
Here's a working demo of my implementation (coincidentally similar to the answer given above; I was making this before any answers were given): http://jsfiddle.net/7fhrN/15/
It works for users without JavaScript and gives graceful degradation to your page. Try switching the JS library to something random on JsFiddle and click Run.
HTML:
<div class="stretchy">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vulputate mi egestas ligula feugiat volutpat. Morbi eros felis, aliquam in varius id, sodales quis nunc. Nulla sagittis consectetur arcu, sed auctor odio placerat quis. Praesent vitae lacus neque. Curabitur ultricies tristique sollicitudin. Suspendisse malesuada nunc at augue interdum at facilisis ipsum gravida.</div>
<div class="stretchy">Nunc congue sapien sed sem tincidunt ut adipiscing neque lacinia. Praesent facilisis quam sed tellus sodales id tristique massa ullamcorper. Donec sem turpis, cursus in elementum id, tincidunt a libero. Etiam feugiat, sem quis dictum imperdiet, nisl ante pharetra erat, ut ornare nulla justo ac sapien. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse vulputate mi egestas ligula feugiat volutpat. Morbi eros felis, aliquam in varius id, sodales quis nunc. Nulla sagittis consectetur arcu, sed auctor odio placerat quis. Praesent vitae lacus neque. Curabitur ultricies tristique sollicitudin. Suspendisse malesuada nunc at augue interdum at facilisis ipsum gravida. Nunc congue sapien sed sem tincidunt ut adipiscing neque lacinia. Praesent facilisis quam sed tellus sodales id tristique massa ullamcorper. Donec sem turpis, cursus in elementum id, tincidunt a libero. Etiam feugiat, sem quis dictum imperdiet, nisl ante pharetra erat, ut ornare nulla justo ac sapien.</div>
CSS:
.stretchy
{
margin: 20px;
padding: 5px;
background-color: rgb(240, 240, 240);
overflow: hidden;
position: relative;
padding-bottom: 20px;
}
.inner
{
max-height: 120px;
overflow: hidden;
}
.reveal
{
position: absolute;
bottom: 0px;
}
JavaScript:
$(document).ready(function()
{
$('.stretchy').each(function()
{
if ($(this).height() > 130)
{
$(this).replaceWith('<div class="stretchy"><div class="inner">' + $(this).html() + '</div>Show me more lipsum</div>');
}
});
$('.reveal').toggle(function()
{
$(this).parent().find('.inner').animate({maxHeight: '1000px'});
}, function() {
$(this).parent().find('.inner').animate({maxHeight: '120px'});
});
});
Basically, I iterate over all the <div>s with the class stretchy. If they are too big, I replace them with a <div> with a container and a link at the bottom which changes the max-height of the inner <div> to some ridiculous value.
Just try it. Seeing > having me explain it to you.