Bob Horn
Bob Horn

Reputation: 34325

ui-grid-draggable-rows thinks my data is just a string

I just followed the directions to get ui-grid-draggable-rows working. They show a working example here.

My issue is that I'm getting this error:

TypeError: this.splice is not a function

At this line of code:

this.splice(to, 0, this.splice(from, 1)[0]);

Just before the splice line, I log this:

console.log(this);

This is the output:

app.Tasks

So it's a string literal. That would explain why splice isn't working. However, that string literal works in my ui-grid to display the tasks. This is in my angular controller:

$scope.gridOptions = {
    data: 'app.Tasks',

So what do I do to get this to work? It seems like a conflict if the draggable plugin treats the data as a literal string, yet the grid uses that literal string to point to the array of data.

Note: In the working example referenced above, they use a hard-coded array of data as the data for the grid. That's obviously okay for an example, but not for real-world use.

Edit - This is what app.Tasks looks like in the console:

enter image description here

Edit 2 - This is the entire code in appController:

function appController($scope, $http, $routeParams, uiGridConstants) {
    $scope.loading = 1;
    $scope.app = null;
    $scope.appId = $routeParams.appId;

    $scope.gridOptions = {
        data: 'app.Tasks',
        multiSelect: false,
        enableRowHeaderSelection: false, // We don't want to have to click a row header to select a row. We want to just click the row itself.
        // Got the row template from https://github.com/cdwv/ui-grid-draggable-rows:
        rowTemplate: '<div grid="grid" class="ui-grid-draggable-row" draggable="true"><div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{ \'ui-grid-row-header-cell\': col.isRowHeader, \'custom\': true }" ui-grid-cell></div></div>',
        columnDefs: [{ field: 'Sequence', displayName: 'Order', width: "8%", resizable: true, sort: { direction: uiGridConstants.ASC, priority: 1 } },
                     { field: 'Description', displayName: 'Description', width: "62%" },
                     { field: 'PrestoTaskType', displayName: 'Type', width: "16%" },
                     { field: 'FailureCausesAllStop', displayName: 'Stop', width: "12%" }]
    };

    $scope.gridOptions.onRegisterApi = function (gridApi) {
        gridApi.draggableRows.on.rowDropped($scope, function (info, dropTarget) {
            console.log("Dropped", info);
        });
    };

    $scope.gridOptions2 = {
        data: 'app.CustomVariableGroups',
        multiSelect: false,
        enableRowHeaderSelection: false, // We don't want to have to click a row header to select a row. We want to just click the row itself.
        columnDefs: [{ field: 'Name', displayName: 'Name', width: "98%", resizable: true }]
    };

    $http.get('/PrestoWeb/api/app/' + $scope.appId)
              .then(function (result) {
                  $scope.app = result.data;
                  $scope.loading = 0;
              },
              function () {
                  $scope.loading = 0;
                  alert("An error occurred and the app could not be loaded.");
              });
}

Upvotes: 1

Views: 543

Answers (1)

Bob Horn
Bob Horn

Reputation: 34325

I was able to get this to work by doing two things:

  1. Remove setting the data property from within $scope.gridOptions.

    $scope.gridOptions = {
    //data: 'app.Tasks', // deleted this line
    multiSelect: false
    // more properties assigned here
    };

  2. Assign that property on its own line after getting the data.

    $scope.gridOptions.data = result.data.Tasks;

Upvotes: 1

Related Questions