Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

javascript - Using jqgrid with popover from angular ui bootstrap

I have a table that I created using jqGrid. I am planning to add a popover functionality, so that when a user click on a cell / grid, then a custom popover is displayed. And I am planning to use the popover from angular ui bootstrap.

I have my grid, and I also have my button that can display a pop over. but when I tried to combine both, it doesn't work. I tried to do this with one of my colModel:

formatter: function(cellvalue, options, rowObject){
                return "<button class='btn btn-primary' popover-placement="top" ng-click='ctrl.handle()'>"+cellvalue+"</button>";
       }

I have my controller that include angular pop-over as the dependency, but this doesn't work. Is this possible?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I should start with the words that I'm not angular developer and I have never used popover before. So the code which I post below could be not good enough from the angular point of view. Nevertheless it works and it do what you need. Having working code you can improve it probably.

The demo display popover on click on the custom button, which stay opened. Additionally alert message will be displayed from the JavaScript function bound using ng-click:

enter image description here

It uses the following HTML markup

<body ng-app="myApp" ng-controller="MyController">
    <ng-jq-grid config="config" data="data"></ng-jq-grid>
</body>

and the following JavaScript code which contains from three parts. In the first one do the standard thing

var myApp = angular.module("myApp", ["ui.bootstrap"]);

it's important just don't forget to include "ui.bootstrap" module required for popover.

In the second part one use myApp.directive with $compile as parameter, which are used for compiling the grid twice: once before placing an empty <table> on the HTML page (in <ng-jq-grid>...</ng-jq-grid>) and once more inside of loadComplete:

myApp.directive("ngJqGrid", function ($compile) {
    return {
        restrict: "E",
        scope: {
            config: "=",
            data: "="
        },
        link: function (scope, element, attrs) {
            var $grid;

            scope.$watch("config", function (newValue) {

                element.children().empty();
                $grid = angular.element("<table></table>");
                element.append($compile($grid)(scope));

                element.append($grid);
                angular.extend(newValue, {
                    autoencode: true,
                    iconSet: "fontAwesome",
                    cmTemplate: { autoResizable: true }, 
                    autoResizing: { compact: true },
                    autoresizeOnLoad: true,
                    loadComplete: function () {
                        $compile(this)(scope);
                    }
                });

                angular.element($grid)
                    .jqGrid(newValue)
                    .jqGrid("navGrid")
                    .jqGrid("filterToolbar");
            });
            scope.$watch("data", function (newValue, oldValue) {
                $grid.jqGrid("clearGridData");
                $grid.jqGrid("setGridParam", {data: newValue});
                $grid.trigger("reloadGrid");
            });
        }
    };
});

I used free jqGrid 4.8 in the demo, so one don't need to generate and id for the <table> element. If you have to use an old version of jqGrid then you should replace the line

$grid = angular.element("<table></table>");

to something like

$grid = angular.element("<table id='" + $.jgrid.jqID() + "'></table>");

The options autoResizing and autoresizeOnLoad are specific for free jqGrid and follows setting of the width of the columns based on the width of the data in the column. The options are described in the readme and in the wiki.

In the last part of the code I use myApp.controller to initialize $scope.config and $scope.data with initial data.

myApp.controller("MyController", function ($scope) {
    $scope.config = {
        myClick: function (rowid) {
            alert("Test buton is clicked on rowid=" + rowid);
        },
        colNames: ["Client", "", "Date", "Closed", "Shipped via", "Amount", "Tax", "Total", "Notes"],
        colModel: [
            { name: "name", align: "center", width: 65, editrules: {required: true},
                searchoptions: { sopt: ["tcn", "tnc", "teq", "tne", "tbw", "tbn", "tew", "ten"] }},
            { name: "myLink", align: "center",
                formatter: function (cellvalue, options, rowObject) {
                    return "<button class='btn btn-primary' popover-placement='top' popover='" +
                         rowObject.note + "' ng-click='config.myClick(" + options.rowId + ")'>Test</button>";
                }},
            { name: "invdate", width: 125, align: "center", sorttype: "date",
                formatter: "date", formatoptions: { newformat: "d-M-Y" },
                editoptions: { dataInit: initDateEdit },
                searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: initDateSearch } },
            { name: "closed", width: 70, template: "booleanCheckboxFa" },
            { name: "ship_via", width: 105, align: "center", formatter: "select",
                edittype: "select", editoptions: { value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "IN" },
                stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;FE:FedEx;TN:TNT;IN:IN" } },
            { name: "amount", width: 75, template: "number" },
            { name: "tax", width: 52, template: "number", hidden: true },
            { name: "total", width: 60, template: "number" },
            { name: "note", width: 60, sortable: false, edittype: "textarea" }
        ]
    };
    $scope.data = [
        { id: "11",  invdate: "2007-10-01", name: "test",   note: "note",   amount: 0, tax: 0, closed: true,  ship_via: "TN", total: 0 },
        { id: "21",  invdate: "2007-10-02", name: "test2",  note: "note2",  amount: 351.75, tax: 23.45, closed: false, ship_via: "FE", total: 375.2 },
        { id: "31",  invdate: "2007-09-01", name: "test3",  note: "note3",  amount: 400, tax: 30, closed: false, ship_via: "FE", total: 430 },
        { id: "41",  invdate: "2007-10-04", name: "test4",  note: "note4",  amount: 200, tax: 10, closed: true,  ship_via: "TN", total: 210 },
        { id: "51",  invdate: "2007-10-31", name: "test5",  note: "note5",  amount: 300, tax: 20, closed: false, ship_via: "FE", total: 320 },
        { id: "61",  invdate: "2007-09-06", name: "test6",  note: "note6",  amount: 400, tax: 30, closed: false, ship_via: "FE", total: 430 },
        { id: "71",  invdate: "2007-10-04", name: "test7",  note: "note7",  amount: 200, tax: 10, closed: true,  ship_via: "TN", total: 210 },
        { id: "81",  invdate: "2007-10-03", name: "test8",  note: "note8",  amount: 300, tax: 20, closed: false, ship_via: "FE", total: 320 },
        { id: "91",  invdate: "2007-09-01", name: "test9",  note: "note9",  amount: 400, tax: 30, closed: false, ship_via: "TN", total: 430 },
        { id: "101", invdate: "2007-09-08", name: "test10", note: "note10", amount: 500, tax: 30, closed: true,  ship_via: "TN", total: 530 },
        { id: "111", invdate: "2007-09-08", name: "test10", note: "note11", amount: 500, tax: 30, closed: false, ship_via: "FE", total: 530 },
        { id: "121", invdate: "2007-09-10", name: "test12", note: "note12", amount: 500, tax: 30, closed: false, ship_via: "FE", total: 530 }
    ];
});

The custom formatter looks like

formatter: function (cellvalue, options, rowObject) {
    return "<button class='btn btn-primary' popover-placement='top' popover='" +
         rowObject.note + "' ng-click='config.myClick(" +
         options.rowId + ")'>Test</button>";
}

I hope that I commented the most important parts of the code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...