Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $location and $anchorScroll to scroll a table row into view

Tags:

angularjs

I'm trying to use $anchorScroll to scroll down the page to ensure that a row of a table is shown. I've read most of the SO threads and docs about $anchorScroll. I'm using it correctly, as far as I can tell. I've stepped through the code with Firebug, and it appears that the element id I'm using is correct.

When I execute the function that should change the scroll location, it does change the scroll location, but it just scrolls up, going all the way to the top. My "target" element that I want to scroll to is further down the page from where I execute the function.

There are no error messages, it just doesn't do what I need.

Here is the simple function that I use:

$scope.scrollTo = function (elementId) {
        console.log("element[" + angular.element(elementId) + "]");
        $location.hash(elementId);
        $timeout(function() {
            $anchorScroll();
        });
    };

I've also tried changing the reference to this so that instead of targetting a table row, it targets the accordion div that encloses the table, but that made no difference. It still just jumps to the top of the page.

Note that before I call "scrollTo", I first ensure that the accordion with the table is opened. In any case, it still doesn't scroll correctly even after it's manually opened.

Update:

Here's a portion of the HTML that I'm trying to scroll to:

                <div ng-controller="WorkflowDefsCtrl">
                <pane accordion-group heading="Workflows" is-open="accordionActiveFlags.workflowDefs" id="workflowDefs">
                    <label for="workflowDefsTable">Workflow Definitions</label>
                    <table id="workflowDefsTable" ng-table class="table">
                        <tr ng-repeat="workflowDef in sunlightConfig.workflowDefinitions | orderBy: workflowDef.order" id="workflowDef{{workflowDef.id}}">
                            <td data-title="'ID'">{{workflowDef.id}}</td>
                            <td data-title="'Name'">{{workflowDef.name}}</td>
                            <td data-title="'Label'">{{workflowDef.label}}</td>
                            <td data-title="'Order'" class="text-right">{{workflowDef.order}}</td>
                            <td data-title="'Render?'">{{workflowDef.render}}</td>
                            <td data-title="'Query Fragment'">{{workflowDef.queryFragment}}</td>
                            <td data-title="'Query Order'" class="text-right">{{workflowDef.queryOrder}}</td>
                        </tr>
                    </table>
                </pane>
            </div>

The two testcases I'm trying are going to element "workflowDefs" and any of the "workflowDef{{workflowDef.id}}" elements.

Update:

I enhanced my "scrollTo" method to deal with scrolling to elements that had just become visible. This doesn't make any difference, however. It still just scrolls to the top no matter what.

Update:

Today I realized that a string argument to "angular.element" should be a CSS selector, not an element id, so I had to add "#" as a prefix. This resulted in the correct element being located, but unfortunately it still had no effect on the display. It still doesn't scroll to the element.

My new "scrollTo" function looks like this:

    scrollTo:   function (elementId) {
        $location.hash("#" + elementId);
        $timeout(function() {
            $anchorScroll();
        });
    },
like image 854
David M. Karr Avatar asked Feb 19 '14 19:02

David M. Karr


1 Answers

I managed to figure this out. I correctly assumed that $anchorScroll has to be executed in the $timeout block, but that isn't sufficient. The call to $location.hash() also has to be in the $timeout block. Once I changed my scrollTo function to the following:

    scrollTo:   function (elementId) {
        $timeout(function() {
            $location.hash(elementId);
            $anchorScroll();
        });
    },

It then started working consistently.

like image 151
David M. Karr Avatar answered Oct 23 '22 23:10

David M. Karr