views:

713

answers:

3

Hi there,

I'm developing a Classic ASP page that pulls some content from a database and creates a Read more link after the first 100 characters as follows;

<div class="contentdetail"><%=StripHTML(rspropertyresults.Fields.Item("ContentDetails").Value)%></div>

<script type="text/javascript">
    $(function() {

     var cutoff = 200;
     var text = $('div.contentdetail').text();
     var rest = $('div.contentdetail').text().substring(cutoff);
     if (text.length > 200) {
       var period = rest.indexOf('.');
       var space = rest.indexOf(' ');
       cutoff += Math.max(Math.min(period, space), 0);
     }

        var visibleText = $('div.contentdetail').text().substring(0, cutoff);

        $('div.contentdetail')
            .html(visibleText + ('<span>' + rest + '</span>'))
            .append('<a title="Read More" style="font-weight:bold;display: block; cursor: pointer;">Read More&hellip;</a>')
            .click(function() {
                $(this).find('span').toggle();
                $(this).find('a:last').hide();
            });

        $('div.contentdetail span').hide();
    });
</script>

However, the script obviously just cuts the text off after 100 characters. Preferably I would like it to keep on writing text until the first period or space, for example. Is this possible to do?

Thank you.

A: 
var cutoff = 100;
var text = $('div.contentdetail').text();
var rest = text.substring(cutoff);
if (text.length > 100) {
  var period = rest.indexOf('.');
  var space = rest.indexOf(' ');
  cutoff += Math.max(Math.min(period, space), 0);
}
// Assign the rest again, because we recalculated the cutoff
rest = text.substring(cutoff);
var visibleText = $('div.contentdetail').text().substring(0, cutoff);

EDIT: shortened it a bit. EDIT: Fixed a bug

moxn
@moxn Thank you for the code. For some reason it isn't shortening the text or creating the Read more link. Perhaps my jQuery code is now not working with the code that you have provided? I'll edit the post to show the code I have now.
Neil Bradley
I edited my post. I forgot to introduce `text` as variable.
moxn
Thanks man. There's a strange little bug. My text first cuts off as follows; "Situated in the highly regarded area of Molescroft Beverley is this well presented detached family home" but then when I click on read more it seems to add some of the characters from the last word onto the end as follows; Situated in the highly regarded area of Molescroft Beverley is this well presented detached family homeome ..."
Neil Bradley
I fixed the bug. Of course the rest had to be extracted again with substring() after `cutoff` got adjusted. But probably bobince's solution is better performancewise...
moxn
Awesome. Thank you man.
Neil Bradley
You are welcome.
moxn
A: 

Here is a fairly simple approach to getting endings at the word level, and shooting for about your given limit in characters.

var limit        = 100,
    text         = $('div.contentdetail').text().split(/\s+/),
    word,
    letter_count = 0,
    trunc        = '',
    i            = 0;

while (i < text.length && letter_count < limit) {
  word         = text[i++];
  trunc       += word+' ';
  letter_count = trunc.length-1;

}

trunc = $.trim(trunc)+'...';
console.log(trunc);
Alex Sexton
+2  A: 

How about:

var text= $('div.contentdetail').text();
var match= text.match( /^(.{100}([^ .]{0,20}[ .])?)(.{20,})$/ );
if (match!==null) {
    var visibleText = match[1];
    var textToHide = match[3];
    ...do replacement...
}

The {0,20} will look forward for a space or period for up to 20 characters before giving up and breaking at exactly 100 characters. This stops an extremely long word from breaking out of the length limitation. The {20,} at the end stops a match being made when it would only hide a pointlessly small amount of content.

As for the replacement code, don't do this:

.html(visibleText + ('<span>' + textToHide + '</span>'))

This is inserting plain-text into an HTML context without any escaping. If visibleText or textToHide contains any < or & characters you will be mangling them, perhaps causing a XSS security problem in the process.

Instead create the set the text() of the div and the span separately, since that's the way you read the text in the first place.

bobince