A Flash Developer Resource Site

Results 1 to 13 of 13

Thread: [RESOLVED] Truncate Text in Dynamic Text Field?

  1. #1
    Senior Member
    Join Date
    Jan 2006
    Posts
    133

    resolved [RESOLVED] Truncate Text in Dynamic Text Field?

    Hello All,

    I have a Dynamic Text Field placed on stage at authortime.
    I need to truncate the text within that field by replacing the last VISIBLE word with an ellipse.
    Now, the problem I'm encountering is that in a multiline text box with wrapping turned on, I can't figure out a way to get the index of the last visible character, or some other point where I can start truncating.
    Part of the issue is that if you pass a really long SINGLE line string into the text field, Flash will wrap it like you would expect, however, the text gets masked if the text field isn't big enough to display it all, but the text that ISN'T visible still is factored into the values returned by AS3.0

    For example, let's say the text field is only big enough to display 3 lines of text.
    If the long string I'm trying to display has to wrap 17 times, then myTextField.numLines would return 17 because the unseen text still exists... it's just not able to be displayed in the text field.

    Also, myTextField.bottomScrollV doesn't help because the string is all 1 line, so even though you can't see the ENTIRE line, it still returns as visible.

    So, does anyone know how to figure out which is the last visible character in a text box?

    Everything I've seen about truncating text involves coming up with some arbitrary max character amount, and just truncating at that point.
    I would prefer to figure it out dynamically based on the text field's width and height because:
    1) character sizes/widths differ for every font, and
    2) There may actually be several different fonts used in the same text field.

    Thanks!

  2. #2
    Senior Member cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    Here is how you get the visible text at a certain position. I used a button in this example and scrolled the text.

    tf.text = "I have a Dynamic Text Field placed on stage at authortime. I need to truncate the text within that field by replacing the last VISIBLE word with an ellipse. Now, the problem I'm encountering is that in a multiline text box with wrapping turned on, I can't figure out a way to get the index of the last visible character, or some other point where I can start truncating. Part of the issue is that if you pass a really long SINGLE line string into the text field, Flash will wrap it like you would expect, however, the text gets masked if the text field isn't big enough to display it all, but the text that ISN'T visible still is factored into the values returned by AS3.0";
    var myText:String = tf.text;
    but.addEventListener (MouseEvent.CLICK, ch);
    function ch (e:Event)
    {
    var myChar:int = tf.getCharIndexAtPoint(300,40);
    trace (myText.charAt(myChar));
    }
    - The right of the People to create Flash movies shall not be infringed. -

  3. #3
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Interesting... I missed the getCharAtIndex method...

    But, I guess I'm a little confused about your example, where do the values "300" and "40" come from?

    Another problem is that I can't really "hardcode" an x, y point to check because different fonts and characters will take up different amounts of space within the text field... so if I say "I'm always going to check this x,y point", there's no garauntee that a character will be in at that point. Also, if the text box isn't quite tall enough to fit an entire line, Flash won't display half a line of text, so it'll just not display that line, and there will be a larger margin between the last visible text and the bottom of the Text Field.

    Now, the text field's width and height WILL NOT change... so I guess I need a way to dynamically calculate the x,y point using the text field's width/height/format and any other metrics I have access to.

    I suppose I could start checking if there is a character exactly at the bottom-right corner of the Text Field (which there never will be), and then just start moving the x,y point incrementally towards the top-left corner of the Text Field until I run into a character?

    Is that a viable solution?

    It seems the TextLineMetrics object offers a lot of metrics to use... would any of those be helpful??

  4. #4
    Senior Member cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    The x and y are the position from the left upper corner of the textfield. There will always be a letter or space in case there is no letter and it is a fixed position in the textfield. You can get a longer string by getting the letters before or after the position using the text in the textfield as the starting string.
    - The right of the People to create Flash movies shall not be infringed. -

  5. #5
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    hmmm, I'm sorry, I'm not following or I might not have communicated what I'm trying to do properly.

    I have a text field on stage with a given width and height.
    I need to be able to populate that text box with a variety of text strings.... such as a movie title. Then, once the string is in there, (or before I populate the TextField with the string) I need to truncate it.

    SO, if the movie title is "Gamer"... no truncation needed. However, if the movie title is "The Assassination of Jesse James by the Coward Robert Ford"... I'm going to need to truncate the title properly.

    You say that "There will always be a letter or space in case there is no letter and it is a fixed position in the textfield"
    I don't see how that is true, please explain.

    If this is my text field, where "x" is the arbitrary 300, 40 point you just defined:

    Code:
    +---------------------------+
    |                           |
    |                         x |
    +---------------------------+
    If the title is "Gamer", the field will look like this:

    Code:
    +---------------------------+
    | Gamer                     |
    |                         x |
    +---------------------------+
    getCharIndexAt("x point") will return as "-1" telling me there is no character there... whitespace or otherwise, so truncation is not needed.

    However, now I change the text via AS3 to "The Assassination of Jesse James by the Coward Robert Ford".

    If the text field looked like this:

    Code:
    +------------------------+
    | The Assasination of    |
    | Jesse James by the Cow |
    +------------------------+
    ard Robert Ford                <--- below the fold text
    Testing the "x point" would be fine, because it would return the index of the letter "w" in the word "Coward".
    However, that's not how Flash wraps words, so in reality the text field would look like this, because Flash won't hyphenate "Cow-ard", so it puts the entire word on the next line, which extends "below the fold":

    Code:
    +-------------------------+
    | The Assasination of     |
    | Jesse James by the    x |
    +-------------------------+
    Coward Robert Ford          <--- below the fold text
    So testing the "x point" would return as "-1", but I still need to truncate the title, so choosing an arbitrary point doesn't help... unless I'm completely missing something?
    Last edited by badaboom55; 02-25-2010 at 04:26 PM.

  6. #6
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    To clarify further... I would want the text box to look like this:

    Code:
    +-------------------------+
    | The Assasination of     |
    | Jesse James by the ...  |
    +-------------------------+
                                        <--- NO BELOW THE FOLD TEXT
    Although, I suppose if I absolutely couldn't get the above, this would be acceptable as well, although, I fail to see how this would be possible and the above wouldn't:

    Code:
    +-------------------------+
    | The Assasination of     |
    | Jesse James by the ...  |
    +-------------------------+
     Coward Robert Ford        <--- below the fold text

  7. #7
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    I swear to all that was mighty, that this wasn't working when I posted... now it is!

    Ok, anyway, if this is the text box:

    Code:
    +-------------------------+
    | The Assasination of     |
    | Jesse James by the      |
    +-------------------------+
    Coward Robert Ford          <--- below the fold text
    First I get the text from the last line, using bottomScrollV, and if then I can replace the last word/whitespace character with "..." and then append that to the end of the first line

    In short:

    PHP Code:
    var LastLineText_str:String myTextField.getLineText(myTextField.bottomScrollV 1);

    // this gets me "Jesse James by the " in a string
    // Then just run an operation to replace "the" or the " " character with an ellipse 

  8. #8
    Senior Member cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    Well, the magic did its job
    - The right of the People to create Flash movies shall not be infringed. -

  9. #9
    Junior Member
    Join Date
    Nov 2010
    Posts
    5
    what if those words are repeating in the text? then I will be replacing the text even in the center ending with ellipses

  10. #10
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by anandsk View Post
    what if those words are repeating in the text? then I will be replacing the text even in the center ending with ellipses
    I to say you replace the last "word", whatever it may be, not explicitly every instance of "the".
    I think I just used regular expressions to replace the last "word". If you want, I can go find it and post some code.

  11. #11
    Junior Member
    Join Date
    Nov 2010
    Posts
    5
    Hey! Thanks a lot for responding .... so here is the problem.

    I have the text to be displayed only in first 2 lines(even though it may consume more, since space is available). I have the following issues:

    (a) Even when the text is just 3 words and is fitting in 1 line, textField.numLines is giving me more than 1 in return (2 or 3 sometimes).

    (b) If that does not perplex me enough, I still don't know, how to replace the last word, with "lastword" + ..., especially by restricting the number of visible lines to 2.

    (c) I do not know how to restrict the number of lines to 2, even if space is available for more than 2 lines

    Any help will be highly appreciated.

    Thanks!

  12. #12
    Senior Member
    Join Date
    Jan 2006
    Posts
    133
    Quote Originally Posted by anandsk View Post
    (a) Even when the text is just 3 words and is fitting in 1 line, textField.numLines is giving me more than 1 in return (2 or 3 sometimes).
    Interesting... there appears to be some weirdness when trying to get numLines when a TextField is populated at authortime. I just threw an empty dynamic TextField (my_txt) on the stage, and numLines gave me 2. Even if I type some text into the field, the numLines property seems to be +1 greater than what I'm actually seeing on the stage. This MIGHT have something to do with the fact that if you type into a TextField on the stage, it automatically expands on stage to display your entire text (no masking).

    In fact it looks like when you add and populate TextField at authortime there's a "\n" (new line) or "\r" (carriage return) character always at the end of your string, even if you don't hit ENTER to put the cursor on a new line.

    However, if I overwrite the my_txt.text property at runtime via a script, it appears to correct itself:

    PHP Code:
    // Using an empty TextField
    trace(my_txt.numLines); // output: 2
    my_txt.text "";
    trace(my_txt.numLines); // output: 1
    my_txt.text "Eros quia esse appellatio indoles sudo aliquam, vel.";
    trace(my_txt.numLines); // output: 6, or whatever the correct number would be, depending on the size of the TextField. Note, the TextField might only be display 2 of those 6, but numLines returns the total, even the lines "below the fold". 
    I suppose if you really wanted to make sure that numLines returns the correct value for a TextField populated at authortime, you COULD just subtract 1 from the numLines value... or do something like this:

    PHP Code:
    var temp_str:String my_txt.text;
    my_txt.text temp_str.substr(0, (temp_str.length-1)); // Get rid of last character in the string, which in this case is the phantom \r or \n character
    trace(my_txt.numLines); 

    Quote Originally Posted by anandsk View Post
    (b) If that does not perplex me enough, I still don't know, how to replace the last word, with "lastword" + ..., especially by restricting the number of visible lines to 2.
    Well, the best way is to match a Regular Expression pattern, that way you don't explicitly have to remove the word "Coward" etc. Just use the String.replace() method. Granted the syntax for using Reg. Exp. is a bit hard for a human to parse through, but here's a starting point for you:
    http://help.adobe.com/en_US/ActionSc...0204-7fdb.html
    There's also a handy section on "Finding patterns and replacing substrings".

    That being said, while I was looking over my code, replacing the last "word" in the string may lead to some undesirable results. For example, if the last word is longish, like "consciousness", then the ellipsis could appear near the middle of the TextField on the last line.
    So, it might be better just to replace the last 3 characters with a dot. So, you would get "consciousn...", which isn't all that useful to an end-user, but it might look better in the the long run.

    Quote Originally Posted by anandsk View Post
    (c) I do not know how to restrict the number of lines to 2, even if space is available for more than 2 lines
    Well the best way is to draw a TextField on stage that will only display 2 lines of text, anything more than 2 lines won't show up on screen (if the text is populated at runtime). The extra text will still be accessible... it's just below the fold.
    But, if you wanted the TextField to have ONLY the 2 lines, and nothing below the fold, then just use getLineText(1) and getLineText(2) to build a new String consisting of just those 2 lines. Then apply that string to the TextField.
    Last edited by badaboom55; 11-16-2010 at 02:05 PM.

  13. #13
    Junior Member
    Join Date
    Nov 2010
    Posts
    5
    Hey, thanks again. As of now, I carved out a solution with your help. I am happy!

    I will let you know if it breaks.

    --Anand

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center