Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent scrolling of a scrollable div dynamically updated on AngularJs

I have an angular app with a powerpoint-like interface.

The left items (scrollable <div>) are parts of a controller called with a ui-sref, the slide content is from another (child) controller and is updated with an ng-show.

Illustration of the powerpoint-like interface

If I click on an item (on the left of the picture), the slide content (on the right) changes dynamically. The problem is that the scrollable view always scrolls to the top when an item is clicked.

I have tried many approaches described on SO, but nothing works:

  • set the attribute autoscroll to false on the ui-view
  • myModule.value('$anchorScroll', angular.noop);
  • myModule.run(['$anchorScroll', function($anchorScroll) { $anchorScroll = angular.noop; }]);
  • $anchorScrollProvider.disableAutoScrolling();

Edit/ here the attributes of all links tags:

ui-sref="{{linkquestion}}" 
ng-repeat="question in questionnaire.Question | orderBy: 'numero' | filter:{statut: false}" 
ng-mouseenter="options = true" 
ng-mouseleave="options = false"

Anyone have an idea?

like image 951
Gautier Drusch Avatar asked Oct 08 '15 16:10

Gautier Drusch


1 Answers

I'm not totally sure what you are attempting with $anchorScroll, but as comments suggest, leveraging ui-router with ui-view is likely what you are wanting to use instead of an ng-show. Also, it's a bit difficult to completely dissect your example and guide you in the correct direction without sample code or a somewhat working example as a baseline. However, from your diagram, I have at least an idea of what you are after - so I've made a best guess.

I encourage you to scrap using ng-show and reconsider your markup in favor of leveraging ui-view. I have crafted an example that is similar to your concept, and I can dynamically change state and display content without a scroll jump. Observe the following complete working example...

<section class="container">
    <aside>
        <a ng-repeat="n in nav" ui-sref="{{ n.state }}">state: {{ n.state }}</a>
    </aside>
    <div ui-view></div>
</section>

angular.module('app', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
    $stateProvider
        .state('a', { template: '<span>a</span>' })
        .state('b', { template: '<span>b</span>' })
        .state('c', { template: '<span>c</span>' })
        .state('d', { template: '<span>d</span>' })
        .state('e', { template: '<span>e</span>' })
        .state('f', { template: '<span>f</span>' })
        .state('g', { template: '<span>g</span>' })
        .state('h', { template: '<span>h</span>' })
        .state('i', { template: '<span>i</span>' })
        .state('j', { template: '<span>j</span>' })
        .state('k', { template: '<span>k</span>' })
        .state('l', { template: '<span>k</span>' });
}])
.controller('ctrl', ['$scope', function($scope) {
    $scope.nav = [
        {'state': 'a' }, {'state': 'b' }, {'state': 'c' },
        {'state': 'd' }, {'state': 'e' }, {'state': 'f' },
        {'state': 'g' }, {'state': 'h' }, {'state': 'i' },
        {'state': 'j' }, {'state': 'k' }, {'state': 'l' }
    ];
}]);

Excuse my total simplicity for states and content - this is just to demonstate. But, you'll be able to see the behavior in the working example and can hopefully mold this foundation into your working copy.

JSFiddle Link - working demo

As always, be sure to check out the ui-router docs for more information.


Per your comment, this may be a slightly more dynamic way to do this. In this, I am just defining one state that is parameterized and subscribing to the $stateChangeSuccess event - giving me an opportunity to populate scope variables based on a passed $stateParam - perhaps via an ajax call.

Please remember - the dynamic nature of this will vary greatly with what your are trying to do. There are ways to leverage child and nested states, there are ways to add dynamic states - really - you can get get as dynamic as you wish here. Most importantly, leveraging ui-view as intended in the following examples resolves the scroll issue. Observe the following, possibly dynamic, possibly favorable example...

<section class="container">
    <aside>
        <a ng-repeat="n in nav" ui-sref="slide({'id': n.slide })">state: {{ n.slide }}</a>
    </aside>
    <div ui-view><span>dynamic content</span></div>
</section>

.config(['$stateProvider', function($stateProvider) {
    $stateProvider
        .state('slide', { url: 'slide/:id', template: '<span>{{ content }}</span>' })
}])
.controller('ctrl', ['$scope', function($scope) {
    $scope.nav = [
        {'slide': 'a' }, {'slide': 'b' }, {'slide': 'c' },
        {'slide': 'd' }, {'slide': 'e' }, {'slide': 'f' },
        {'slide': 'g' }, {'slide': 'h' }, {'slide': 'i' },
        {'slide': 'j' }, {'slide': 'k' }, {'slide': 'l' }
    ];

    $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { 
        // - just to demo
        // - use this param to get dynamic content 
        // - then populate scope variables in template
        $scope.content = toParams.id;
    });
}]);

JSFiddle Link - a bit more dynamic demo

like image 112
scniro Avatar answered Nov 10 '22 10:11

scniro