ui.grid.edit 功能允许对表格数据进行内嵌编辑。要启用, 必须包括 “ui.grid.edit” 模块, 必须在表格元素上包括ui-grid-edit编辑指令。
api 文档中提供了编辑功能的文档, 特别是:
可以使用列定义中的 enableCellEdit 选项来允许列可编辑。
通过双击、f2、或开始键入任何 non-navigable 键来调用编辑。可以通过tab, enter 或 esc 结束单元格的编辑, 并且tab, 左或右箭头, enter或 esc 为也可以应用在下拉中。
默认情况下, 为所有字段提供了输入元素, 其中有数字、日期和复选框编辑器, 用于为指定了 “数字”、“日期” 和 “布尔” 类型的字段提供一个简单的文本编辑器。(关于日期编辑器的一点值得注意的是, 对于要启用的日期编辑器, 变量的数据类型也应该是 “日期”)
通过 columnDef 上设置 editableCellTemplate : ui-grid/dropdownEditor, 还可以使用下拉编辑器。当使用下拉编辑器时, 您需要通过 columnDef 的 editDropDownOptionsArray 属性提供一个选项数组。默认情况下, 此数组应为 {id: xxx, value: xxx}, 还可以通过使用 editDropdownIdLabel 和 editDropdownValueLabel 选项来更改字段标记。
通过columnDef 上设置 editableCellTemplate : ui-grid/fileChooserEditor, 可以使用文件选择器。此文件选择器将打开用户选择的文件, 并向模型元素分配该文件的值。在下面的示例中, 我们使用文件选择器加载一个文件, 我们在单元格中显示文件名。文件存储在隐藏列中的行, 我们可以保存到服务器或其他进程。
自定义编辑模板应用于除默认编辑器以外的任何编辑, 但请注意, 您可能还需要提供类似于 uiGridEditor 指令的自定义指令, 以便提供 BEGIN_CELL_EDIT、CANCEL_CELL_EDIT 和 END_CELL_EDIT 事件。
ColumnDef Options:
- editModelField (default: undefined) -要使用的可绑定表达式, 而不是 colDef.field 绑定编辑控件时的字段。
- editableCellTemplate (default: ‘ui-grid/cellEditor’) - 在调用编辑模式时返回要编译的 html 内容中有效的html、templateCache id 或 url。
- enableCellEdit (default: 默认所有列都为true) -true 将启用编辑和 false 将禁用它。
- cellEditableCondition (default: true)- 可以设置为一个布尔值或函数, 它将用cellScope 观察器来调用, 以确定是否应在编辑模式下调用该单元格。
- type (default: ‘string’)-如果设置为 “数字”、“布尔” 或 “日期”, 则为编辑提供的默认编辑器将分别为数字或布尔值或日期编辑器。如果设置为 “对象”, 则默认情况下该列将不可编辑。请注意, 此类型列也用于 ui-grid中的其他用途, 包括排序逻辑。
- editDropdownOptionsArray-如果下拉列表, 需要用一个值数组填充, 默认情况下, 这些值应该为 {id: xxx, value: xxx}, 标签可以用下面两个选项进行调整。
- editDropdownIdLabel (default: ‘id’) - 控制选项数组中的 id 标签, 因此, 如果数组恰好包含 “代码”, 则可以使用它而不必重新处理数组。
- editDropdownValueLabel (default: ‘value’) - 控制选项数组中的值标签-如果数组恰好包含 “name”, 则可以使用它而不必重新处理数组。
- editDropdownRowEntityOptionsArrayPath - 当下拉列表的内容依赖于该行支持的实体时, 可以作为 editDropdownOptionsArray 的替代方法。
- editDropdownOptionsFunction - 当可以使用参数为行实体和列定义的函数检索内容时, 可以作为 editDropdownOptionsArray 的另一种替代方法。
- editDropdownFilter (default: ‘’) - 允许您将筛选器应用于 “编辑” 下拉选项中的值, 例如, 如果您使用的是角平移, 则将此设置为 “平移”
只有在使用 cellNav 功能时, 以下选项才可用
- enableCellEditOnFocus - true 当单元格具有焦点时调用编辑器
请注意, 编辑功能使用本机 html5 编辑部件-日期选取器、下拉列表和输入框本身。如果你的浏览器没有实现这些小部件, 你就不会得到它们。如果您的浏览器以一种不理想的方式实现这些小部件 (例如, 某些浏览器不允许使用数字字段开始 “.”, 因此您不能键入 “. 五”), 然后您需要提供一个自定义编辑器。在中期路线图中, 有意图提供bootstrap 功能, 这将提供与 angular-bootstrap 指令兼容的指令, 允许使用bootstrap datepicker 和输入字段。
$scope.gridOptions.columnDefs = [
{ name: 'name', enableCellEdit: true },
{ name: 'age', enableCellEdit: true, type: 'number'},
{ name: 'registered', displayName: 'Registered' , type: 'date'},
{ name: 'address', displayName: 'Address', type: 'object'},
{ name: 'address.city', enableCellEdit: true, displayName: 'Address (even rows editable)', cellEditableCondition: function($scope){return $scope.rowRenderIndex%2} }
{ name: 'isActive', enableCellEdit: true, type: 'boolean'},
]
代码
index.html
<!doctype html>
<html ng-app="app">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="/release/ui-grid.js"></script>
<script src="/release/ui-grid.css"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MainCtrl">
<strong>Data Length:</strong> {{ gridOptions.data.length | number }}
<br>
<strong>Last Cell Edited:</strong> {{msg.lastCellEdited}}
<br>
<div ui-grid="gridOptions" ui-grid-edit class="grid"></div>
<br>
<div><strong>Last file uploaded:</strong></div>
<div>{{lastFile}}</div>
</div>
</body>
</html>
main.css
.grid {
width: 600px;
height: 450px;
}
app.js
var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.edit', 'addressFormatter']);
angular.module('addressFormatter', []).filter('address', function () {
return function (input) {
return input.street + ', ' + input.city + ', ' + input.state + ', ' + input.zip;
};
});
app.controller('MainCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
$scope.gridOptions = { };
$scope.storeFile = function( gridRow, gridCol, files ) {
// ignore all but the first file, it can only select one anyway
// set the filename into this column
gridRow.entity.filename = files[0].name;
// read the file and set it into a hidden column, which we may do stuff with later
var setFile = function(fileContent){
gridRow.entity.file = fileContent.currentTarget.result;
// put it on scope so we can display it - you'd probably do something else with it
$scope.lastFile = fileContent.currentTarget.result;
$scope.$apply();
};
var reader = new FileReader();
reader.onload = setFile;
reader.readAsText( files[0] );
};
$scope.gridOptions.columnDefs = [
{ name: 'id', enableCellEdit: false, width: '10%' },
{ name: 'name', displayName: 'Name (editable)', width: '20%' },
{ name: 'age', displayName: 'Age' , type: 'number', width: '10%' },
{ name: 'gender', displayName: 'Gender', editableCellTemplate: 'ui-grid/dropdownEditor', width: '20%',
cellFilter: 'mapGender', editDropdownValueLabel: 'gender', editDropdownOptionsArray: [
{ id: 1, gender: 'male' },
{ id: 2, gender: 'female' }
] },
{ name: 'registered', displayName: 'Registered' , type: 'date', cellFilter: 'date:"yyyy-MM-dd"', width: '20%' },
{ name: 'address', displayName: 'Address', type: 'object', cellFilter: 'address', width: '30%' },
{ name: 'address.city', displayName: 'Address (even rows editable)', width: '20%',
cellEditableCondition: function($scope){
return $scope.rowRenderIndex%2
}
},
{ name: 'isActive', displayName: 'Active', type: 'boolean', width: '10%' },
{ name: 'pet', displayName: 'Pet', width: '20%', editableCellTemplate: 'ui-grid/dropdownEditor',
editDropdownRowEntityOptionsArrayPath: 'foo.bar[0].options', editDropdownIdLabel: 'value'
},
{ name: 'status', displayName: 'Status', width: '20%', editableCellTemplate: 'ui-grid/dropdownEditor',
cellFilter: 'mapStatus',
editDropdownOptionsFunction: function(rowEntity, colDef) {
var single;
var married = {id: 3, value: 'Married'};
if (rowEntity.gender === 1) {
single = {id: 1, value: 'Bachelor'};
return [single, married];
} else {
single = {id: 2, value: 'Nubile'};
return $timeout(function() {
return [single, married];
}, 100);
}
}
},
{ name: 'filename', displayName: 'File', width: '20%', editableCellTemplate: 'ui-grid/fileChooserEditor',
editFileChooserCallback: $scope.storeFile }
];
$scope.msg = {};
$scope.gridOptions.onRegisterApi = function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope,function(rowEntity, colDef, newValue, oldValue){
$scope.msg.lastCellEdited = 'edited row id:' + rowEntity.id + ' Column:' + colDef.name + ' newValue:' + newValue + ' oldValue:' + oldValue ;
$scope.$apply();
});
};
$http.get('/data/500_complex.json')
.success(function(data) {
for(i = 0; i < data.length; i++){
data[i].registered = new Date(data[i].registered);
data[i].gender = data[i].gender==='male' ? 1 : 2;
if (i % 2) {
data[i].pet = 'fish'
data[i].foo = {bar: [{baz: 2, options: [{value: 'fish'}, {value: 'hamster'}]}]}
}
else {
data[i].pet = 'dog'
data[i].foo = {bar: [{baz: 2, options: [{value: 'dog'}, {value: 'cat'}]}]}
}
}
$scope.gridOptions.data = data;
});
}])
.filter('mapGender', function() {
var genderHash = {
1: 'male',
2: 'female'
};
return function(input) {
if (!input){
return '';
} else {
return genderHash[input];
}
};
})
.filter('mapStatus', function() {
var genderHash = {
1: 'Bachelor',
2: 'Nubile',
3: 'Married'
};
return function(input) {
if (!input){
return '';
} else {
return genderHash[input];
}
};
})
;
Demo
文章来源:西柚叨叨的个人博客