粘性列中的ag-grid菜单

时间:2018-05-20 16:37:31

标签: javascript html css css3 ag-grid

有没有办法为粘性列中的每一行添加菜单(在Ag网格中)?

在官方文件中没有提到这样的功能,所以我不确定它是否可能。我尝试了几种方法,但菜单总是被困在粘性列包装器中。

我能够(至少)部分工作的唯一方法是设置:

.ag-body-container .ag-row {
        z-index: 0;
    }

    .ag-ltr .ag-hacked-scroll .ag-pinned-right-cols-viewport {
        overflow: visible !important;
    }

但这完全破坏了垂直滚动。

var columnDefs = [
    {headerName: "ID", width: 50,
        valueGetter: 'node.id',
        cellRenderer: 'loadingRenderer'
    },
    {headerName: "Athlete", field: "athlete", width: 150},
    {headerName: "Age", field: "age", width: 90},
    {headerName: "Country", field: "country", width: 120},
    {headerName: "Year", field: "year", width: 90},
    {headerName: "Date", field: "date", width: 110},
    {headerName: "Sport", field: "sport", width: 210},
    {headerName: "Gold", field: "gold", width: 300},
    {headerName: "Silver", field: "silver", width: 400},
    {headerName: "Bronze", field: "bronze", width: 200},
    {headerName: "Menu", field: "", width: 100, pinned: 'right', cellRenderer: 'menuRenderer' }
  ];
  
  function MenuRenderer( params ) {
  }	

	MenuRenderer.prototype.init = function(params) {
		this.eGui = document.createElement('div');
		this.eGui.classList.add('menu');
		var menuElement = `
			<a href="#">  * </a> 
			<div class="menu--list"> 
			</div>
		`;
		this.eGui.innerHTML = menuElement;
	};

	MenuRenderer.prototype.getGui = function() {
		return this.eGui;
	};


  var gridOptions = {
    components:{
        loadingRenderer: function(params) {
            if (params.value !== undefined) {
                return params.value;
            } else {
                return '<img src="./loading.gif">'
            }
        },
		'menuRenderer': MenuRenderer

    },
    columnDefs: columnDefs,
	rowBuffer: 0,
	rowModelType: 'infinite',
	paginationPageSize: 100,
	cacheOverflowSize: 2,
	maxConcurrentDatasourceRequests: 2,
	infiniteInitialRowCount: 0,
	maxBlocksInCache: 2,
	//embedFullWidthRows:true, 
    onGridReady: function (params) {
      params.api.sizeColumnsToFit();
    }
  }

  // wait for the document to be loaded, otherwise,
  // ag-Grid will not find the div in the document.

  document.addEventListener("DOMContentLoaded", function() {
    // lookup the container we want the Grid to use
    var eGridDiv = document.querySelector('#myGrid');

    // create the grid passing in the div to use together with the columns & data we want to use
    new agGrid.Grid(eGridDiv, gridOptions);
	
	 agGrid.simpleHttpRequest({url: 'https://raw.githubusercontent.com/ag-grid/ag-grid-docs/master/src/olympicWinners.json'}).then(function(data) {
        var dataSource = {
            rowCount: null, // behave as infinite scroll
            getRows: function (params) {
                console.log('asking for ' + params.startRow + ' to ' + params.endRow);
                // At this point in your code, you would call the server, using $http if in AngularJS 1.x.
                // To make the demo look real, wait for 500ms before returning
                setTimeout( function() {
                    // take a slice of the total rows
                    var rowsThisPage = data.slice(params.startRow, params.endRow);
                    // if on or after the last page, work out the last row.
                    var lastRow = -1;
                    if (data.length <= params.endRow) {
                        lastRow = data.length;
                    }
                    // call the success callback
                    params.successCallback(rowsThisPage, lastRow);
                }, 500);
            }
        };

        gridOptions.api.setDatasource(dataSource);
    });
  });
/* Menu */
	.menu {
		z-index: 2 !important;
		position: fixed;
		top: 20%;
		left: 50%;
	}
	
	.menu a {
		text-decoration: none;
	}
	
	.menu .menu--list {
		display: none;
		position: absolute;
		top: 0;
		right: 0px;
		width: 100px;
		height: 50px;
		border: 1px solid red;
	}
	
	.ag-body-container .ag-row {
		z-index: 0;
	}

	.ag-ltr .ag-hacked-scroll .ag-pinned-right-cols-viewport {
		overflow: visible !important;
	}
	
	.ag-pinned-right-cols-viewport .ag-row:first-child .menu--list{
		display: block;
	}

	/* [Layout] */
  .fill-height-or-more {
    min-height: 100%;
    display: flex;
    flex-direction: column;
    border: 1px solid red;
  }
  .fill-height-or-more > div {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .some-area > div {
    padding: 1rem;
  }
  .some-area > div:nth-child(1) {
    flex-grow:0;
    background: #88cc66;
  }
  .some-area > div:nth-child(2) {
    flex-grow: 0;
    background: #ec971f;
  }
  .some-area > div:nth-child(3) {
    position: relative;
    padding: 0;
    justify-content: stretch;
    align-content: flex-start;;
    flex-grow:1;
    background: #8cbfd9;
  }
  .some-area > div:nth-child(4) {
    flex-grow: 0;
	position: absolute;
    background: #ec971f;
  }
  .some-area > div h2 {
    margin: 0 0 0.2rem 0;
  }
  .some-area > div p {
    margin: 0;
  }
  .inner{ position: absolute; top: 0; bottom: 0; left: 0; right: 0; }

  html, body {
    padding:0;
	margin: 0;
    height: 100%;
	overflow: hidden;
  }
  
  .ag-body-viewport {
	-webkit-overflow-scrolling: touch;
	}
<head>
  <script src="https://unpkg.com/ag-grid/dist/ag-grid.min.js"></script>
</head>

<html>
  <body>
  <section class="some-area fill-height-or-more">
    <div>
      Header
    </div>
    <div>
      Action bar
    </div>
    <div>
      <div class="inner">
        <div id="myGrid" style="height: 100%; width:100%; font-size: 1.4rem" class="ag-theme-fresh"></div>
      </div>
    </div>
  </section>
  </body> 	
</html>

1 个答案:

答案 0 :(得分:2)

我会完全放弃在单元格中添加菜单的想法。

我要做的是:

  • 在网格外添加隐藏的菜单
  • 将链接保留在单元格中(这会稍后触发菜单)
  • 将点击事件添加到此链接
  • 为菜单创建一个类(可以是全局的,因为只有一个菜单,具有更改的上下文)
    • 这会隐藏/显示菜单
    • 拥有存储上下文的参数(来自网格的数据或其他内容)
  • 来自网格的链接上的点击事件将包含显示菜单的代码

这样的事情: 为简洁起见,此示例没有错误处理。

install.packages("mxnet.zip", repos=NULL, type="win.binary")

这是网格内链接的示例点击事件:

var gridMenu = function(selector) {
    var instance = this;
    instance.element = document.querySelector(selector);
    instance.context = null; // this can be any data, depends on your project

    // sender is the link from your cell
    // context is your data (see above)
    instance.open = function(sender, context) {
        instance.context = context;
        // you may even add the sender element to your context

        instance.element.style.display('block');
        // alternatively, you could use instance.element.classList.add('some_class_to_make_menu_visible')
        // you may need to add some positioning code here (sender would contain valuable data for that)
    }

    instance.close = function () {
        instance.context = null;
        instance.element.style.display = 'none';
        // or you may remove visibility class
    }

    // click events for menu items (if you use some Javascript processing, and the menu doesn't use simple links)
    instance.menuItem1Click = function(e) {
         // do whatever you wish here
         instance.close();
         // call this at the end of each of your menu item click event handlers
    }

    // ... more click event handlers for your other menu items (one for each menu item)

    return instance;
}

// Create your menu item somewhere in your document ready code, or even where you initiate your grid (before initializing the grid)
var menu = new gridMenu("#my_awesome_floating_menu");