6 Replies Latest reply on Nov 4, 2011 8:09 AM by drkstr_1

    Scrolling to location in a RichEditableText control

    EricJ32 Level 1

      I'm using a RichEditableText control to display a load of formatted text. This is separated into sections, with links to those sections at the top of the text.

      What I want is for each of those links to scroll the content so that the identified paragraph is at the top of the viewport.

       

      This is what I have tried:

       

      protected function application1_initializeHandler(event:FlexEvent):void

      {

      var flow:TextFlow = TextConverter.importToFlow("<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'><p styleName='link'><a href='event:goto_section1'>Section 1</a></p><p styleName='link'><a href='event:goto_section2'>Section 2</a></p><p id='section1' styleName='header'>Section 1</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent et ultrices sem. Nullam sit amet felis sem, luctus ornare mauris. Proin tincidunt porta ante, lobortis placerat odio sagittis dignissim. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis vel dui sapien, non imperdiet lorem. Donec leo lacus, viverra nec porttitor non, ullamcorper vehicula nunc.</p><p>Pellentesque molestie scelerisque lorem nec lobortis. Mauris ultricies, diam at lacinia congue, diam ante fermentum ipsum, nec semper ligula est quis velit. Etiam dictum nisi vitae lectus pretium sit amet fermentum nunc mollis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Nulla suscipit, massa id lobortis consequat, eros augue dapibus turpis, eu ullamcorper lacus sapien pulvinar felis. Mauris in eleifend ligula. Nullam aliquet, justo ut malesuada rhoncus, libero quam sodales enim, ut aliquet risus neque sit amet diam.</p><p id='section2' styleName='header'>Section 2</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent et ultrices sem. Nullam sit amet felis sem, luctus ornare mauris. Proin tincidunt porta ante, lobortis placerat odio sagittis dignissim. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis vel dui sapien, non imperdiet lorem. Donec leo lacus, viverra nec porttitor non, ullamcorper vehicula nunc.</p><p>Pellentesque molestie scelerisque lorem nec lobortis. Mauris ultricies, diam at lacinia congue, diam ante fermentum ipsum, nec semper ligula est quis velit. Etiam dictum nisi vitae lectus pretium sit amet fermentum nunc mollis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Nulla suscipit, massa id lobortis consequat, eros augue dapibus turpis, eu ullamcorper lacus sapien pulvinar felis. Mauris in eleifend ligula. Nullam aliquet, justo ut malesuada rhoncus, libero quam sodales enim, ut aliquet risus neque sit amet diam.</p></TextFlow>", TextConverter.TEXT_LAYOUT_FORMAT);

                              flow.format = null;

                                              flow.addEventListener(FlowElementMouseEvent.CLICK, clickHandler);

                                              richText.textFlow = flow;

      }

       

      protected function clickHandler(event:FlowElementMouseEvent):void

                                    {

                                              if(event.flowElement is LinkElement)

                                              {

                                                        var link:LinkElement = event.flowElement as LinkElement;

       

                                                        if(link.href.substr(0,11) == "event:goto_")

                                                        {

                                                                  var scrollToElement:FlowElement = richText.textFlow.getElementByID(link.href.substr(11));

       

                                                                  if(scrollToElement != null)

                                                                  {

                                                                            var scrollToStart:int = scrollToElement.getAbsoluteStart();

                                                                            richText.scrollToRange(scrollToStart, scrollToStart);

                                                                  }

                                                        }

                                              }

                                    }

       

       

       

      <s:Scroller id="scroller" width="400" height="200">

        <s:RichEditableText id="richText"

                                                                            textAlign="justify"

                                                                            width="100%"

                                                                            editable="false" /> 

      </s:Scroller>

       

       

       

      Now, the problem is that this scrolls so that the header is at the BOTTOM of the page, whereas I want it at the top (where the length of the text allows that). I just can't figure how to do that. Any ideas? Thanks.

        • 1. Re: Scrolling to location in a RichEditableText control
          Flex harUI Adobe Employee

          I would think you would want to try something like:

              richText.scrollToRange(scrollToSta rt, scrollToStart + richText.height);

           

          So the range would have some height to it.

          • 2. Re: Scrolling to location in a RichEditableText control
            EricJ32 Level 1

            Yes, I've tried plenty of things like that, but the problem is that scrollToStart isn't the vertical position of the paragraph in the textFlow. I need some way of converting between the start position and the vertical position so that I can perform an add like this. I've also considered a simple assignment to richText's verticalScrollPosition, but again, I need to be able to convert between the value returned by getAbsoluteStart() - which appears to be the character count of the textflow - and the vertical position.

            • 3. Re: Scrolling to location in a RichEditableText control
              drkstr_1 Level 4

              You should be able to get the text line of a charachter (can't remember the specific method off the top of my head), then use that text line number as the verticalScrollPosition.

               

              Post back tomorrow if you're still having trouble and I can take a look at my code. From what I can remember, i needed to find the text line number(s) of a range before I could determine the display bounds (or vertical scroll index in your case) of an element in the TextFlow.

              • 4. Re: Scrolling to location in a RichEditableText control
                drkstr_1 Level 4

                Sorry to double post but I just remembered a bit more about how I solved my problem. It actually a bit tricker then calling a simple method.

                 

                You should have a textLines property somewhere for the RichEditbleText field (need you use namespace mx_internal I think). The process is to loop through each of the TextLine objects and increment the atomCount property. When totalAtomCount is >= your absolute start, you have found your line index to scroll to.

                 

                DISCLAIMER: there is possibly (should be, if not) a better way to do this, but I wasn't able to find one so this is what I ended up going with

                • 5. Re: Scrolling to location in a RichEditableText control
                  EricJ32 Level 1

                  OK, I've sorted it. At last.

                   

                  The textLines propert wasn't a help, since it only held the visible lines, not anything that was outside of the viewport's boundaries.

                   

                  This was my solution (not vigorously tested):

                   

                  if(event.flowElement is LinkElement)

                                                          {

                                                                    var link:LinkElement = event.flowElement as LinkElement;

                   

                                                                    if(link.href.substr(0,11) == "event:goto_")

                                                                    {

                                                                              var id:String = link.href.substr(11);

                   

                                                                              for each(var tfl:TextFlowLine in StandardFlowComposer(richText.textFlow.flowComposer).lines)

                                                                              {

                                                                                        if(tfl.paragraph.id == id)

                                                                                        {

                                                                                                  richText.verticalScrollPosition = tfl.y;

                                                                                                  break;

                                                                                        }

                   

                                                                              }

                   

                                                                    }

                                                          }

                  • 6. Re: Scrolling to location in a RichEditableText control
                    drkstr_1 Level 4

                    Ah, good catch. In my situation I didnt have to worry about scrollable text. Usint the flowComposer to reference the lines seems much more sound. I will update my own solution to match.

                     

                    Cheers!