2

I have a hard time figuring out what to do in my AngularJs single-page . I use ng-repeat to display a number of widgets. The plugin is "Jarvis widget v2.0". My problem is, that the article container does not have the functionality from the Jarvis widget (fullscreen, collapse etc.).

The data is delayed because of a HTTP GET call. If I hard-code the dataSeries it works 100%, but it seems that the Jarvis widgets gets rendered before the success of the HTTP GET. I have tried to find a solution for days and my guess is that a directive is the solution, but I'm lost!

<article class="col-xs-12 col-sm-12 col-md-6 col-lg-6" ng-repeat="chart in dataSeries">
       <div class="jarviswidget" id="wid-id-02" data-widget-editbutton="false" data-widget-colorbutton="false" data-widget-deletebutton="false"></div>
</article>

This is my first post, so if I forgot something i apologize in advance.

ordonezalex
  • 2,645
  • 1
  • 20
  • 33
redlaz
  • 121
  • 3
  • 9

2 Answers2

2

The code inside function setup_widgets_desktop() is going to create the widgets based on the current(!) HTML content. As ng-repeat will render your element after you have a success from your HTTP request, there are no elements present when the function is called.

In order to achieve the behaviour you want, execute setup_widgets_desktop() again after your callback returns. You might need to make sure it is delayed by using $timeout(setup_widgets_desktop, 1000). I am using it this way, but not sure if it is a general requirement to have a delay.

The best option would be to extract the call $('#widget-grid').jarvisWidgets() into an directive. You could replace $('#widget-grid') with getting the current $(element), so it is only bound to the current element and not some fixed ID inside the DOM. If you need more advice on this, just drop me a line.

Edit (sample code):

In my project I am using the following Angular service (you have to replace yourApp, the HTTP URI and the jQuery selector to your needs):

(function(yourApp) {
    "use strict";
    yourApp.factory("presenter", function ($timeout) {
        var layout = function () {
            $("#widgets-grid").jarvisWidgets({
                grid: "article",
                widgets: '.jarviswidget',
                localStorage: false,
//                deleteSettingsKey: '#deletesettingskey-options',
//                settingsKeyLabel: 'Reset settings?',
//                deletePositionKey: '#deletepositionkey-options',
//                positionKeyLabel: 'Reset position?',
                sortable: false,
                buttonsHidden: false,
                // toggle button
                toggleButton: false,
                toggleClass: 'fa fa-minus | fa fa-plus',
                toggleSpeed: 200,
                onToggle: function () {
                },
                // delete btn
                deleteButton: false,
                deleteClass: 'fa fa-times',
                deleteSpeed: 200,
                onDelete: function () {
                },
                // edit btn
                editButton: false,
                editPlaceholder: '.jarviswidget-editbox',
                editClass: 'fa fa-cog | fa fa-save',
                editSpeed: 200,
                onEdit: function () {
                },
                colorButton: false,
                // full screen
                fullscreenButton: true,
                fullscreenClass: 'fa fa-expand | fa fa-compress',
                fullscreenDiff: 3,
                onFullscreen: function (e) {
                },
                // order
                buttonOrder: '%refresh% %custom% %edit% %toggle% %fullscreen% %delete%',
                opacity: 1.0,
                dragHandle: '> header',
                placeholderClass: 'jarviswidget-placeholder',
                indicator: true,
                indicatorTime: 600,
                ajax: true,
                timestampPlaceholder: '.jarviswidget-timestamp',
                timestampFormat: 'Last update: %m%/%d%/%y% %h%:%i%:%s%',
                refreshButton: true,
                refreshButtonClass: 'fa fa-refresh',
                labelError: 'Sorry but there was a error:',
                labelUpdated: 'Last Update:',
                labelRefresh: 'Refresh',
                labelDelete: 'Delete widget:',
                afterLoad: function () {
                },
                rtl: false, // best not to toggle this!
                onChange: function () {
                },
                onSave: function () {
                },
                ajaxnav: $.navAsAjax // declears how the localstorage should be saved
            });
        }

        return {
            layout: function() {
                $timeout(layout, 1000);
            }
        };
    });
})(window.yourApp);

Your controller should then look like this:

function($scope, $http, presenter) {
    ...
    $http("api/data").success(function(data) {
        $scope.dataSeries= data;
        presenter.layout();
    });
    ...
}
Netzdoktor
  • 526
  • 4
  • 15
  • Hi Darneas. Thank you for your reply. Could you elaborate your answer with a little bit of code? I'm very grateful! – redlaz Jul 25 '14 at 15:02
  • It's much clearer, but I still can't get it to work. Do you by chance have a jsfiddle running with an example? – redlaz Jul 25 '14 at 20:55
  • Unfortunately, these widgets are not open-source so I cannot build a fiddle. The code you need is given in the edited answer. When you post your relevant parts (complete controller function), I can have a look at it. – Netzdoktor Jul 26 '14 at 12:29
2

OK, with help from Darneas I came up with a solution.

  1. I implemented this: : Calling a function when ng-repeat has finished
  2. I made sure that "widget-grid" wasn't initialized (I had some test widgets)
  3. I called "setup_widgets_desktop()" from the ngRepeatFinished

This was succesfull. Thank you Darneas. I wouldn't had found a solution otherwise.

I couldn't get the widget directive to work, which looks like a great solution as well.

Community
  • 1
  • 1
redlaz
  • 121
  • 3
  • 9