1

I'm a newbie in angularJS

I use angularJS with ui-router and a slickgrid I try to call a method from a click on a image to call a web service and delete the row

I have this controller :

app.controller('customerController', ['$scope', '$compile', 'CustomerService',      function ($scope, $compile, CustomerService) {
    // function to get customers
    $scope.getCustomers = function () {
        CustomerService.getCustomers($("#userId").val(), $scope.getArchived).then(function (customers) {
            dataView.beginUpdate();
            dataView.setItems(customers);
            dataView.endUpdate();
            grid.invalidate();
        }, function (reason) {
            noty({ text: reason, type: 'error' });
        });
    }
    // function to archive customer
    $scope.archiveCustomer = function(customerId) {
        if (confirm(translate("LBL_DELETE_CUSTOMER_CONFIRMATION"))) {
            CustomerService.archiveCustomer(customerId).then(function () {
                $scope.getCustomers();
            }, function (reason) {
                   noty({ text: reason, type: 'error' });
            });
        }
        return false;
    }

    // create grid
    var dataView,
        grid;
    var options = {
        enableCellNavigation: true,
        enableColumnReorder: false,
        autoHeight: true
    };

    var columns = [
        { id: "id", name: "", field: "id", width: 20, formatter: deleteFormatter, cssClass: "centeredColumn" },
        { id: "customer", name: translate("Customer"), field: "customer", width: 250 }
    ];

    function deleteFormatter(row, cell, value, columnDef, dataContext) {
        html = "<img src='images/delete.gif' alt='" + translate("LBL_DELETE_CUSTOMER") + "' style='cursor:pointer;' ng-click='archiveCustomer(" + dataContext.id + ");' />";
        linker = $compile(angular.element(html));
        htmlElements = linker($scope);
        html = htmlElements[0].outerHTML;
        return html;
    }

dataView = new Slick.Data.DataView({ inlineFilters: true });
    grid = new Slick.Grid("#customersGrid", dataView, columns, options);

    $scope.getCustomers();
}]);

My problem is with the ng-click on the img element added by the deleteFormatter. What is wrong? I saw sample with directive but it's not clear in my mind... could you light me?

Edit

Try with asyncPostRender without success: columns definition :

var columns = [
        { id: "id", name: "", field: "id", width: 20, formatter: asyncFormatter, asyncPostRender: deleteRender, cssClass: "centeredColumn" },
        { id: "customer", name: translate("Customer"), field: "customer", width: 250 }
    ];

formatter and render:

function asyncFormatter(row, cell, value, columnDef, dataContext) {
    return "Data loading...";
}

function deleteRender(cellNode, row, dataContext, colDef) {
    html = "<img src='images/delete.gif' alt='" + translate("LBL_DELETE_CUSTOMER") + "' style='cursor:pointer;' ng-click='archiveCustomer(" + dataContext.id + ");' />";
    linker = $compile(angular.element(html));
    htmlElements = linker($scope);
    $(cellNode).empty()
    cellNode.innerHTML = htmlElements[0].outerHTML;
}
Troopers
  • 5,127
  • 1
  • 37
  • 64

2 Answers2

1

UPDATED

"formatter" seem to be just a configuration function of given column. You need to use a render function for that column like "asyncPostRender". See this example.

Your new element (delete img) is out of any Angular scope. You need to $compile it into Angular in the render event of grid row.

Kursad Gulseven
  • 1,978
  • 1
  • 24
  • 26
  • Sorry, just an error in rewriting the code : i have some double quotes in my code. There is no error in the console – Troopers Nov 04 '14 at 11:51
  • What is the live Html of that img? – Kursad Gulseven Nov 04 '14 at 11:59
  • 1
    If by live html you tell html produce by angular, it's: #LBL_DELETE_CUSTOMER# – Troopers Nov 04 '14 at 12:03
  • This doesn't work. the img is render but ng-click as no effect. See my edit – Troopers Nov 04 '14 at 15:25
  • I read SlickGrid docs and issues. See mleibman's post at the bottom of [this page](https://github.com/mleibman/SlickGrid/issues/196)."You can't programmatically create DOM nodes in your formatters, only HTML strings" he says. I think you need to find another way. If you can create a simple fiddle, then I try to help you find a workaround. – Kursad Gulseven Nov 04 '14 at 20:32
1

The answer with the help of Kursad Gulseven (Thank you) and this post

The controller declaration :

app.controller('customerController', ['$scope', '$rootScope', '$compile', '$interpolate', 'CustomerService', function ($scope, $rootScope, $compile, $interpolate, CustomerService) {

Columns definition :

var columns = [
    { id: "id", name: "", field: "id", width: 20, formatter: deleteFormatter, asyncPostRender: deleteRender, cssClass: "centeredColumn" },
    { id: "customer", name: translate("Customer"), field: "customer", width: 250 }
];

formatter and render:

function deleteFormatter(row, cell, value, columnDef, dataContext) {
    return "<img src='images/delete.gif' alt='delete' style='cursor:pointer;' ng-click='archiveCustomer(" + dataContext.id + ");' />";
}

function deleteRender(cellNode, row, dataContext, colDef) {
    // compile the html with angular to get ng-click with the correct scope
    var interpolated = $interpolate($(cellNode).html())($scope);
    var linker = $compile(interpolated);
    var htmlElements = linker($scope);
    $(cellNode).empty()
    $(cellNode).append(htmlElements);
}

the archive customer function :

$scope.archiveCustomer = function (customerId) {
    if (confirm(translate("LBL_DELETE_CUSTOMER_CONFIRMATION"))) {
        CustomerService.archiveCustomer(customerId).then(function () {
            $scope.getCustomers();
        }, function (reason) {
            noty({ text: reason, type: 'error' });
        });
    }
}
Community
  • 1
  • 1
Troopers
  • 5,127
  • 1
  • 37
  • 64