tags:

views:

558

answers:

12

How would you go about Cutting strings short so it doesnt go to the next line in a div tag For example my message string contained the following:

We prefer questions that can be answered, not just discussed. Provide details. Write clearly and simply. If your question is about this website, ask it on meta instead.

And i want to preferably display it as

We prefer questions that can be answered, not just discussed. Provide ... Read More

Im thinking cutting the string short using PHP but then you have the following problem

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ... Read More

You can see that the above string can still be expanded a bit more. Any way to do this or Not, Thanks in Advance

+1  A: 

Check the size, if the size is greater than your maximum, take the leftmost characters.

Leftmost # = Total size - size("... read more"). Then append the read more to the left most characters.

Jacob

TheJacobTaylor
A: 

Here is an example taken from http://snippetdb.com/php/truncate-string:

function Truncate ($str, $length=10, $trailing='...')  
{ 
      // take off chars for the trailing 
      $length-=strlen($trailing); 
      if (strlen($str) > $length)  
      { 
         // string exceeded length, truncate and add trailing dots 
         return substr($str,0,$length).$trailing; 
      }  
      else  
      {  
         // string was already short enough, return the string 
         $res = $str;  
      } 

      return $res; 
} 
Oren
A: 
$maxlength = 100;

if (strlen($string) > $maxlength) {
    $string = substr($string,0,$maxlength - 3) . '...';
}
sixfoottallrabbit
dont you think this code will strip a word into half if the 97th character of string lies in the center of that word
Umair
+3  A: 

How you can shorten a string is already answered, but your main question:

How would you go about Cutting strings short so it doesnt go to the next line in a div tag

this will not work in most cases.

for example:

iiiiiiiiii

wwwwwwwwww

You see the problem ?

this only works if your chars have the same width like:

iiiiiiiiii
wwwwwwwwww
Rufinus
A: 

It all depends on the font. Of course, you can use a monospace font, but that isn't a solution. Anyway, why would you like to do this? Even if you manage to make it work on a certain font, it might be that an user doesn't have it. Then a different font will be used, and everything may break...

Ignas R
The question was more based on, can it be done. :D
Shahmir Javaid
A: 

It would be basically impossible to do this in PHP with a non monospace font (even with a monospace font, it is difficult to tell exactly how long a string in going to be in a certain browser. The only way I can think of doing this in a browser is to put it in a and set the width of a the span to be a certain width then use overflow: hidden.

Kris Erickson
+2  A: 

Using PHP, you can use the wordwrap function to perform truncation:

function truncate_to_length($text, $length, $text_if_longer = "...") 
{
    if (strlen($text) > $length) 
    {
        $text = wordwrap($text, $length);
        $text = substr($text, 0, strpos($text, "\n"));
        return $text . $text_if_longer;
    }
    return $text;
}
John Rasch
+1  A: 

Oooo i came up with something that works but not works completely... Id like to share

div.string{

    height:15px;     
    overflow:hidden;
}

It solves the problem that it will hide the whole word that wont fit in to the end of line.., because of the overflow and the height is set to one line only. However the above still dosent do the Problem shown by Rufinus:

iiiiiiiiiiiiii

wwwwwwwwwwwwww

Shahmir Javaid
+1 This is my preferred method. Never limit your server-side variables for a client-side problem, especially one likely to change over time :)
Al
Change the height to "1em" and you'll get +1.
outis
oo thanks i was wondering if there was some thing such as that :D
Shahmir Javaid
+1  A: 

I asked this question a few months ago. My eventual solution is there too.

Jeremy DeGroot
A: 

If you know what true-type font the browser is using, you can use the imagettfbbox() in the GD library to calculate the width of your text. Then iterate and drop characters off of the end of the text until it fits into your div.

This may not be very efficient, I know that, but it does the job. You could fine-tune and optimize for your specific solution.

<?
    $width = 280; // max. width in pixels that the text should have
    $font = 'C:\Windows\Fonts\verdana.TTF';
    $text = 'The quick brown fox jumps over the lazy dog';

    function getWidth($text) {
     list($x1, , $x2) = imagettfbbox(12, 0, $font, $text);
     return $x2-$x1;
    }

    while (getWidth($text.'...') > $width) $text = substr($text, 0, -1);
?>

<style type='text/css'>
    #my_div {
        font-family: Verdana; 
        font-size: 12pt; 
        border: 1px solid black; 
        width: 280px; 
        padding: 0
    }
</style>

<div id='my_div'>
    <?=$text?>...
</div>
Wil
I wouldn't recommend an image for restricting text width. I suggest elegant CSS!
Al
A: 

Depending on what browser you're using, this one line of CSS could do the trick:

div.string {
    word-wrap: break-word;
}
Nathan Kleyn
That didnt Work for Me
Shahmir Javaid
+1  A: 

The following mostly works; the main issue is that the "...Read more" notice can cover up part of a letter. It also uses a bunch of presentational elements and requires JS. It makes me feel unclean.

The outermost element (of class .string) is used to set the overall size. .text holds the text to display. Between .string and .text in the descendent hierarchy is an element with a large width. This puts all the text in .text on one line. JS is used to show or hide the "...Read more" notice.

<style type="text/css">
  .string {
    height: 1em;
    width: 25%;
    position: relative; /* create containing block for children */
    border: 1px solid black;
    overflow: hidden;
    background: white; /* or whatever, as long as it's not "transparent". */
  }
  .string .line {
    width: 5000px; /* long enough for you? */
  }
  .string .notice {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1;
    display: none;
    background: inherit; /* so that the notice will completely cover up whatever's beneath */
  }
</style>

<div class="string">
  <div class="line"><span class="text">We prefer questions that can be answered, 
    not just discussed. Provide details. Write clearly and simply. If your 
    question is about this website, ask it on meta instead.</span></div>
</div>
<hr />
<div class="string">
  <div class="line"><span class="text">Lorem ipsum dolor sit amet.</span></div>
</div>

<script>
  function isOverflowed(elt) {
      return elt.offsetWidth > elt.parentNode.parentNode.clientWidth;
  }
  function getNotice(textElt) {
       try {
           return (textElt.parentNode.parentNode.getElementsByClassName('notice'))[0];
       } catch (e) {
           return {style: {}};
       }
  }
  function show(elt) {
      elt.style.display = 'block';
  }
  function hide(elt) {
      elt.style.display = 'none';
  }
  function showReadMoreNotices() {
    var text=document.getElementsByClassName('text');
    for (var i=0; i<text.length; ++i) {
      if (isOverflowed(text[i])) {
          show(getNotice(text[i]));
      } else {
          hide(getNotice(text[i]));
      }
    }
  }

  var strings = document.getElementsByClassName('string');
  var notice = document.createElement('div');
  notice.appendChild(document.createTextNode('\u2026Read more'));
  notice.className = 'notice';
  for (var i=0; i<strings.length; ++i) {
      strings[i].appendChild(notice.cloneNode(true));
  }

  showReadMoreNotices();
  /* use your favorite event registration method here. Not that the traditional 
   * model is my favorite, it's just simple.
   */
  window.onresize = showReadMoreNotices;
</script>
outis
I gota run now but il come back and test your code :D
Shahmir Javaid
The code I first posted wasn't suitable for publication; the portion that created the notice elements was missing. It's fixed now.
outis