最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ui-grid : how to show and position a popup menu div onclick of a row element inside the grid? - Stack Overflow

programmeradmin1浏览0评论

I have the below configuration of the UI-grid and menu but I am getting the menu opened for every element shown(i know the problem that same menu is opening for all the items as there is no differentiation in terms of which item's menu to be opened; but I am unable to reference it)

$scope.gridOptions = {
        enableSelectAll: true,
        exporterCsvFilename: 'AGS_Extract.csv',
        exporterMenuPdf: false,
        enableFiltering: true,
        showGridFooter: true,
        paginationPageSizes: [25, 50, 75],
        paginationPageSize: 25,
        useExternalPagination: true,
        enableGridMenu: true,
        exporterAllDataFn: function () {

            var paramsObj = {};
            var url = ":8080/Dashboards/AGSMateervlet";

            paramsObj['query'] = $scope.keyword;
            paramsObj['start'] = 0;
            paramsObj['rows'] = $scope.gridOptions.totalItems;
            return $http.get(url, { params: paramsObj, headers: { 'Content-Type': 'application/json' } }).then(function (res) {
                var myElement = angular.element(document.querySelectorAll(".custom-csv-link-location"));
                $scope.gridApi.exporter.csvExport( $scope.export_row_type, $scope.export_column_type, myElement );
            });
        },
        columnDefs: [
            { name: 'materialnum', displayName: 'Part Number', cellClass: 'partNum', 
            cellTemplate: "<div> <div ng-click='grid.appScope.cellClicked(row)' class='ui-grid-cell-contents' title='{{COL_FIELD CUSTOM_FILTERS}}'>{{COL_FIELD CUSTOM_FILTERS}}</div><div class='subMenu' ng-show='grid.appScope.menu'><div class='subMenuChld'><span class='arrwLeft'></span><h5>View Details <span style='float:right;' ng-click='grid.appScope.menu=false;'>X</span></h5><ul><li ng-click='grid.appScope.menuItemClick(row,&apos;new_price&apos;)'>New Price</li><li ng-click='grid.appScope.menuItemClick(row,&apos;usage_forecast&apos;)'>Usage/Forecast</li><li ng-click='grid.appScope.menuItemClick(row,&apos;inventory&apos;)'>Inventory</li><li ng-click='grid.appScope.menuItemClick(row,&apos;part_bom&apos;)'>Part BOM</li><li ng-click='grid.appScope.menuItemClick(row,&apos;open_order&apos;)'>Open Order</li><li ng-click='grid.appScope.menuItemClick(row,&apos;open_po&apos;)'>Open PO</li><li ng-click='grid.appScope.menuItemClick(row,&apos;return_history&apos;)'>Return History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;supplier_history&apos;)'>Supplier History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;repair_history&apos;)'>Repair History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;alternative_parts&apos;)'>Alternative Parts</li></ul></div></div></div>"
            },
            { name: 'materialdesc', displayName: 'Part Description', 
                cellTemplate:'<div ng-if="row.entity.materialdesc" title="{{row.entity.materialdesc}}">{{row.entity.materialdesc}}</div><div ng-if="!row.entity.materialdesc"></div>',
            },
            {
                name: 'sparable', displayName: 'Sparable', 
                filter: {
                    type: uiGridConstants.filter.SELECT,
                    selectOptions: [
                        { value: 'yes', label: 'YES' },
                        { value: 'no', label: 'NO' }
                    ]
                },
                //cellTemplate:'<div ng-if="row.entity.sparable" class="tcenter">{{row.entity.sparable}}</div><div ng-if="!row.entity.sparable" class="tcenter">-</div>',
                cellClass: function (grid, row, col) {
                    if (grid.getCellValue(row, col) === 'NO') {
                        return 'red tcenter';
                    } 
                    if(grid.getCellValue(row, col) === 'YES') {
                        return 'green tcenter';
                    } 
                    return 'tcenter';
                }
            },

.. .

Below is the function invoked on click of it:

$scope.cellClicked = function (row, col){

    console.log(row.entity.materialnum);
    $scope.menu = true; // All menus are being active
    
};

In addition to showing all the menus, the positioning of the menu is irrelevant now. How can I position or point to the correct click position(its simple in jQuery but I am strictly using Javascript, Angularjs and UI-grid)

Thanks in advance!

################################## EDIT ################################

  1. The menu is opening on the top side of grid whenever clicked on any of the row item; I am unable to position it on the click; we have solutions from jQuery but trying to avoid jQuery, something in Angular or Javascript would suffice.

  2. The grid is having defaulted to 25 items, first 10-12 are shown in the visible part and then it is scrolled down; now if I click on the rows in the visible area then the menu is showing up correctly BUT when I click on the remaining ones which are hidden from visible area then the menu is hidden only header part is shown(i am suspecting the ul/li is creating some issue but I am thinking only for non-visible part items why this problem is. (Tried giving z-indexes and all but didn't work out). Below are the screenshots for the same:

I have the below configuration of the UI-grid and menu but I am getting the menu opened for every element shown(i know the problem that same menu is opening for all the items as there is no differentiation in terms of which item's menu to be opened; but I am unable to reference it)

$scope.gridOptions = {
        enableSelectAll: true,
        exporterCsvFilename: 'AGS_Extract.csv',
        exporterMenuPdf: false,
        enableFiltering: true,
        showGridFooter: true,
        paginationPageSizes: [25, 50, 75],
        paginationPageSize: 25,
        useExternalPagination: true,
        enableGridMenu: true,
        exporterAllDataFn: function () {

            var paramsObj = {};
            var url = "http://test.satellite.:8080/Dashboards/AGSMateervlet";

            paramsObj['query'] = $scope.keyword;
            paramsObj['start'] = 0;
            paramsObj['rows'] = $scope.gridOptions.totalItems;
            return $http.get(url, { params: paramsObj, headers: { 'Content-Type': 'application/json' } }).then(function (res) {
                var myElement = angular.element(document.querySelectorAll(".custom-csv-link-location"));
                $scope.gridApi.exporter.csvExport( $scope.export_row_type, $scope.export_column_type, myElement );
            });
        },
        columnDefs: [
            { name: 'materialnum', displayName: 'Part Number', cellClass: 'partNum', 
            cellTemplate: "<div> <div ng-click='grid.appScope.cellClicked(row)' class='ui-grid-cell-contents' title='{{COL_FIELD CUSTOM_FILTERS}}'>{{COL_FIELD CUSTOM_FILTERS}}</div><div class='subMenu' ng-show='grid.appScope.menu'><div class='subMenuChld'><span class='arrwLeft'></span><h5>View Details <span style='float:right;' ng-click='grid.appScope.menu=false;'>X</span></h5><ul><li ng-click='grid.appScope.menuItemClick(row,&apos;new_price&apos;)'>New Price</li><li ng-click='grid.appScope.menuItemClick(row,&apos;usage_forecast&apos;)'>Usage/Forecast</li><li ng-click='grid.appScope.menuItemClick(row,&apos;inventory&apos;)'>Inventory</li><li ng-click='grid.appScope.menuItemClick(row,&apos;part_bom&apos;)'>Part BOM</li><li ng-click='grid.appScope.menuItemClick(row,&apos;open_order&apos;)'>Open Order</li><li ng-click='grid.appScope.menuItemClick(row,&apos;open_po&apos;)'>Open PO</li><li ng-click='grid.appScope.menuItemClick(row,&apos;return_history&apos;)'>Return History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;supplier_history&apos;)'>Supplier History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;repair_history&apos;)'>Repair History</li><li ng-click='grid.appScope.menuItemClick(row,&apos;alternative_parts&apos;)'>Alternative Parts</li></ul></div></div></div>"
            },
            { name: 'materialdesc', displayName: 'Part Description', 
                cellTemplate:'<div ng-if="row.entity.materialdesc" title="{{row.entity.materialdesc}}">{{row.entity.materialdesc}}</div><div ng-if="!row.entity.materialdesc"></div>',
            },
            {
                name: 'sparable', displayName: 'Sparable', 
                filter: {
                    type: uiGridConstants.filter.SELECT,
                    selectOptions: [
                        { value: 'yes', label: 'YES' },
                        { value: 'no', label: 'NO' }
                    ]
                },
                //cellTemplate:'<div ng-if="row.entity.sparable" class="tcenter">{{row.entity.sparable}}</div><div ng-if="!row.entity.sparable" class="tcenter">-</div>',
                cellClass: function (grid, row, col) {
                    if (grid.getCellValue(row, col) === 'NO') {
                        return 'red tcenter';
                    } 
                    if(grid.getCellValue(row, col) === 'YES') {
                        return 'green tcenter';
                    } 
                    return 'tcenter';
                }
            },

.. .

Below is the function invoked on click of it:

$scope.cellClicked = function (row, col){

    console.log(row.entity.materialnum);
    $scope.menu = true; // All menus are being active
    
};

In addition to showing all the menus, the positioning of the menu is irrelevant now. How can I position or point to the correct click position(its simple in jQuery but I am strictly using Javascript, Angularjs and UI-grid)

Thanks in advance!

################################## EDIT ################################

  1. The menu is opening on the top side of grid whenever clicked on any of the row item; I am unable to position it on the click; we have solutions from jQuery but trying to avoid jQuery, something in Angular or Javascript would suffice.

  2. The grid is having defaulted to 25 items, first 10-12 are shown in the visible part and then it is scrolled down; now if I click on the rows in the visible area then the menu is showing up correctly BUT when I click on the remaining ones which are hidden from visible area then the menu is hidden only header part is shown(i am suspecting the ul/li is creating some issue but I am thinking only for non-visible part items why this problem is. (Tried giving z-indexes and all but didn't work out). Below are the screenshots for the same:

Share Improve this question edited Jul 7, 2020 at 18:41 abbylu 492 bronze badges asked Jul 6, 2017 at 11:47 GOKGOK 2,4386 gold badges36 silver badges68 bronze badges 1
  • 1 Without a plunker demonstrating the issues it is very difficult to answer your question – K Scandrett Commented Jul 10, 2017 at 0:01
Add a ment  | 

3 Answers 3

Reset to default 3

First you don't share your HTML template. For this reason I can't see where you trigger to open menu event. I assume that you trigger openMenu event on row.

Your row HTML shlould be like below. First $index is row index and second $index is column index if there is ng-repeat on columns.

<div ng-repeat="row in rows" class="my-grid-row" ng-click="openMenu($event, $index, 0, row, col)">
      <div  ng-repeat="col in row.cols" class="my-grid-col" ng-click="$parent.openMenu($event, $parent.$index, $index, row, col)">
      </div>
</div>

For positioning you menu you need $event.

$scope.openMenu = function(evt, rowindex, colindex, row, col){

       //first find mouse position;
      var left  = evt.pageX;
      var top = evt.pageY;
      //YOUR MENU SHOULD HAVE POSITION ABSOLUTE.
      //ALSO YOU CAN SET MENU POSITOIN BY USING LOTS OF WAY WITHOUT JQUERY
      var menuStyle = {left:left,top:top};
      1. If each row has own menu you can set the new positoin to scope by binding ng-style="menuStyle"
      $scope.menuStyle = menuStyle;
      $scope.menu = true;
      2. If your menu container have an ID and you are using single menu for all grid
      var menuEl = angular.element('#mygridmenu');
      menuEl.css(menuStyle);
      menuEl.show();

}

If you share your HTML I can post a clear solution.

Why not refer to the row, like this:

$scope.cellClicked = function (row, col){

     row.menu = true; 

};

And then in your cell-template you do:

<div>
  <div ng-click='grid.appScope.cellClicked(row)' class='ui-grid-cell-contents' title='{{COL_FIELD CUSTOM_FILTERS}}'>{{COL_FIELD CUSTOM_FILTERS}}</div>
  <div class='subMenu' ng-show='row.menu'>
    <div class='subMenuChld'>
      <span class='arrwLeft'></span>
      <h5>View Details <span style='float:right;' ng-click='row.menu=false;'>X</span></h5>
      <ul>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;new_price&apos;)'>New Price</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;usage_forecast&apos;)'>Usage/Forecast</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;inventory&apos;)'>Inventory</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;part_bom&apos;)'>Part BOM</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;open_order&apos;)'>Open Order</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;open_po&apos;)'>Open PO</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;return_history&apos;)'>Return History</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;supplier_history&apos;)'>Supplier History</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;repair_history&apos;)'>Repair History</li>
        <li ng-click='grid.appScope.menuItemClick(row,&apos;alternative_parts&apos;)'>Alternative Parts</li>
      </ul>

</div>
</div>
</div>

Note: row.menu instead of grid.appScope.menu.

Enable click events on the grid cell and watch for changes to get the selected ID.

var grid = $("#grid").data("kendoGrid");
var selectedId = '';
$scope.gridOptions {
 ...
 selectable: 'cell'
}

// Watch array changes

$scope.watchCollection('grid.selectedKeyNames()',function(newValue, oldValue) {
  if (newValue != oldValue) {
    selectedId = newValue[0];
  }
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论