0

I have JQuery li element that I want simulate the click on. I've written a small function in angular to do so, but it doesn't seem to be working.

settings.triggerClick = function (levels) {
    for (var i = 0; i < levels.length; i++) {  
        $("#Monday-" + levels[i].LevelCode + "-tab").trigger("click");
    }
  }

This is called here:

// Get Service Levels to Build Delivery Rules Accordion
settings.getDeliveryServices = function() {
    $http.get(resourceBase + "api/service/levels").success(function(data) {
        settings.serviceLevels = data;
        // Get Service Days
        $http.get(resourceBase + "api/service/days").success(function(days) {
            settings.serviceDays = days;
            // Build the Accordion
            settings.accordian(settings.serviceLevels);
                settings.triggerClick(settings.serviceLevels);
            });
        });
    }

The getDeliveryServices function is called when the page / angular load.

I've debugged through and so far I've ruled out the serviceLevels being empty, so there shouldn't be an issue there. I've also made sure the debugger is entering the for loop. When I get that element using the console it finds the correct JQuery dom element. So I'm not sure what the problem is. Could also be worth mentioning that the elements are generated by an angular ng-repeat loop.

<li id="{{day.Day}}-{{level.LevelCode}}-tab" ng-repeat="day in settings.serviceDays">
    <a id="{{day.Day}}-{{level.LevelCode}}" href="#tabContent-{{day.Day}}-{{level.LevelCode}}" ng-click="settings.changeTab(day, level, $event)">{{day.Day}}</a>
</li>

So I don't know if it's got something to do with the elements not being available before I look for them, however I assume that's not the issue because I'm calling the settings.triggerClick() method inside a success/error promise.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Web Develop Wolf
  • 5,996
  • 12
  • 52
  • 101
  • This seems to be anti-pattern, However use native click `$(selector).get(0).click();` instead of `.trigger("click")` – Satpal Sep 04 '17 at 13:08
  • you know that SO has an js/html engine for running the code – Edwin Sep 04 '17 at 13:12
  • Didn't work unfortunately – Web Develop Wolf Sep 04 '17 at 13:24
  • Consider using [UI Bootstrap Tabs](https://angular-ui.github.io/bootstrap/#!#tabs). They provide Bootstrap Tabs directives which are integrated with the AngularJS framework. With the AngularJS framework, controllers shouldn't manipulate DOM directly. DOM manipulation should be encapsulated in [AngularJS directives](https://docs.angularjs.org/guide/directive). – georgeawg Sep 04 '17 at 18:13

2 Answers2

0

Maybe I'm remembering Angular wrong, but when you set

settings.serviceDays = days;

doesn't that make your ng-repeat="day in settings.serviceDays" run again? If so, then it seems possible that the elements simply havent had time to be rendered (and gotten assigned a onclick callback) yet.

You should be able to test if this is the case by delaying the call to settings.triggerClick(settings.serviceLevels); even further (it's already delayed by the API call, like you hinted). setTimeoutwould be good enough to test the theory:

setTimeout(() => settings.triggerClick(settings.serviceLevels), 500)

I don't know what the proper way would be to delay a function call until a ng-repeat is finished (if that turns out to be the source of your problem), but I found this SO question that has some ideas: ng-repeat finish event

jonahe
  • 4,820
  • 1
  • 15
  • 19
0

Fixed it in the end by calling the bootstrap tab functions to force the tab to be active and all the others to be inactive:

for (var i = 0; i < levels.length; i++) {
    $("#Monday-" + levels[i].LevelTmsCode + "-tab").tab("show");
    $("#tabContent-Tuesday-" + levels[i].LevelTmsCode).hide();
    $("#tabContent-Wednesday-" + levels[i].LevelTmsCode).hide();
    $("#tabContent-Thursday-" + levels[i].LevelTmsCode).hide();
    $("#tabContent-Friday-" + levels[i].LevelTmsCode).hide();
    $("#tabContent-Saturday-" + levels[i].LevelTmsCode).hide();
    $("#tabContent-Sunday-" + levels[i].LevelTmsCode).hide();
}

And then called the function on a time out to allow angular time to render:

setTimeout(() => settings.triggerClick(settings.serviceLevels), 500);
Web Develop Wolf
  • 5,996
  • 12
  • 52
  • 101