ui-网格编辑功能无法正常工作
ui-grid Edit Feature not working properly
我正在使用 ui-网格。我使用 ui-grid-edit 启用了编辑功能。问题是日期选择器。
我希望日期选择器可以在所有浏览器中工作,但是启用类型 : "date" 是不可能的,因为它将提供 HTML5 支持的相同日期选择器。
所以我想使用自定义模板为 angular 启用 bootstrap 日期选择器
通过添加 editableCellTemplate
columnDefs : {
field:'accbirthdate',displayName :"Birth Date",enableCellEditOnFocus:true,editableCellTemplate: '<input type="text" ng-input="COL_FIELD" ng-model="COL_FIELD" datepicker-popup="dd-MM-yyyy" datepicker-append-to-body="true"/>'}
}
但它根本不起作用。我发现即使是输入文本中的 ng-click 也不是 working.So 任何人请帮助如何在 angular ui-grid
中启用 bootstarp 日期选择器
一个月前我遇到了同样的问题。但我找不到解决方案。所以我改变主意使用自定义网格。
我使用了 table、tr、td 标签
看到这是我的 html 代码
<table ng-show="TimeSheetList.length!==0" class="table">
<tr>
<th style="background-color: #BBE1EF">Start Date</th>
<th style="background-color: #BBE1EF">Start Time</th>
<th style="background-color: #BBE1EF">End Time</th>
<th style="background-color: #BBE1EF">Total Hours</th>
<th style="background-color: #BBE1EF">Description</th>
<th style="background-color: #BBE1EF">Remarks</th>
</tr>
<tr ng-repeat="timesheetlist in TimeSheetList">
<td ng-dblclick="ChangeVal(this,'StartDate')"><span ng-hide="timesheetlist.IsEditStartDate">{{timesheetlist.StartDate}}</span>
<input style="width: 150px" type="text" class="form-control" date-time required="true" view="hours" partial="true" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="StartDate{{$index}}" ng-show="timesheetlist.IsEditStartDate" ng-model="timesheetlist.StartDate" />
</td>
<td><span ng-dblclick="ChangeVal(this,'StartTime')" ng-hide="timesheetlist.IsEditStartTime">{{timesheetlist.StartTime}}</span>
<timepicker hour-step="1" minute-step="1" show-meridian="true" ng-change="UpdateTimeSheet(this.timesheetlist)" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="StartTime{{$index}}" ng-show="timesheetlist.IsEditStartTime" ng-model="timesheetlist.StartTime"></timepicker>
</td>
<td><span ng-dblclick="ChangeVal(this,'EndTime')" ng-hide="timesheetlist.IsEditEndTime">{{timesheetlist.EndTime}}</span>
<timepicker hour-step="1" minute-step="1" show-meridian="true" ng-change="UpdateTimeSheet(this.timesheetlist)" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="EndTime{{$index}}" ng-show="timesheetlist.IsEditEndTime" ng-model="timesheetlist.EndTime"></timepicker>
</td>
<td>
<input type="text" readonly="true" class="form-control" ng-model="timesheetlist.TotalHours" style="width: 200px" autofocus="">
</td>
<td><span ng-dblclick="ChangeVal(this,'Description')" ng-hide="timesheetlist.IsEditDescription">{{timesheetlist.Description}}</span>
<input style="width: 200px" type="text" class="form-control" ng-blur="UpdateTimeSheet(this.timesheetlist)" ng-show="timesheetlist.IsEditDescription" ng-model="timesheetlist.Description" /></td>
<td><span ng-dblclick="ChangeVal(this,'Remarks')" ng-hide="timesheetlist.IsEditRemarks">{{timesheetlist.Remarks}}</span>
<input style="width: 200px" type="text" class="form-control" ng-blur="UpdateTimeSheet(this.timesheetlist)" ng-show="timesheetlist.IsEditRemarks" ng-model="timesheetlist.Remarks" /></td>
</tr>
</table>
这是我的控制器代码
function loadTimeSheets(date) {
$http({
method: 'GET',
url: rootUrl + '/api/TimeSheet/LoadTimeSheet?date=' + date,
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).success(function (response) {
$scope.TimeSheetList = response;
if ($scope.TimeSheetList.length == 0) {
alert('You did not add your works in this date');
}
}).error(function (response, errorCode) {
if (errorCode == 444) {
//toastr.error('Your email address is does not verrified ', 'Error');
}
})
}
希望您可以根据需要自定义我的网格。
如果你不喜欢那样,那么你可以去 ng-Grid
是的,我认为这是因为当我们直接在 editableCellTemplate 上使用它时 HTML 代码没有被编译。
有关 Angular 模板编译如何工作的更多信息,请参阅此处
Angular Template Compiling
以下是我为解决此问题所做的工作。我将我的列 defs editableCellTemplate 替换为以下
columnDefs : {
field:'accbirthdate',displayName :"Birth Date",enableCellEditOnFocus: true,editableCellTemplate: '<input type="text" class="form-control" datepicker-popup="dd/MM/yyyy" ng-class="\'colt\' + col.index" ng-model="row.entity[col.field]" datepicker-append-to-body="true" is-open="istableDate" close-text="Close" table-date/>'}
}
与 gridEditor 一样,我在 directive.js 中创建了自己的指令 directive.js 我已经创建了指令
app.directive('tableDate',function($filter){
function parseDateString(dateString) {
if (typeof(dateString) === 'undefined' || dateString === '') {
return null;
}
var parts = dateString.split('/');
if (parts.length !== 3) {
return null;
}
var year = parseInt(parts[2], 10);
var month = parseInt(parts[1], 10);
var day = parseInt(parts[0], 10);
if (month < 1 || year < 1 || day < 1) {
return null;
}
return new Date(year, (month - 1), day);
}
function pad(s) { return (s < 10) ? '0' + s : s; }
return {
priority: -100, // run after default uiGridEditor directive
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
scope.istableDate = false;
scope.$on( 'uiGridEventBeginCellEdit', function () {
scope.istableDate = true;
});
element.on("click",function(){
scope.istableDate = true;
});
element.bind( 'blur', function () {
if(!scope.istableDate){
scope.$emit( 'uiGridEventEndCellEdit' );
}else{
scope.istableDate = false;
}
}); //when leaving the input element, emit the 'end cell edit' event
if (ngModel) {
ngModel.$formatters.push(function (modelValue) {
var modelValue= new Date(modelValue);
ngModel.$setValidity(null,(!modelValue || !isNaN(modelValue.getTime())));
return $filter('date')(modelValue, 'dd/MM/yyyy');
});
ngModel.$parsers.push(function (viewValue) {
if (viewValue ) {
var dateString = [pad(viewValue.getDate()), pad(viewValue.getMonth()+1), viewValue.getFullYear()].join('/')
var dateValue = parseDateString(dateString);
ngModel.$setValidity(null, (dateValue && !isNaN(dateValue.getTime())));
return dateValue;
}
else {
ngModel.$setValidity(null, true);
return null;
}
});
}
}
};
});
我的日期格式是 dd/MM/yyyy,在我们发出事件后选择您的格式,它会提到已更改。
现在我的 bootstrap 日期选择器在所有浏览器上为我的 ui-grid 工作。
如果您对此有任何疑问,请随时问我。我花了一天时间在这上面,我想把我的经验分享给其他人。
糟糕,不在 IE6 中:)
我也遇到了日期选择器的这个问题,因此决定添加一个默认的 jquery-ui。实际上,您可以添加任何人。
下面的代码需要ui一些解释。
首先,您的模板应如下所示:
editableCellTemplate: '<input datepicker ng-model="MODEL_COL_FIELD" readonly>'
它必须包含值为 MODEL_COL_FIELD
的 ng-model
属性。该值意味着您的输入将与单元格的模型绑定。 IE。停止编辑模式后的单元格(通常是 <div>
元素)将从我们的输入中获取值。 MODEL_COL_FIELD
值被 ui-grid 引擎替换为模型的真实名称。在我们的例子中,这是 row.entity['startDate']
。你看一个属性$attrs.ngModel
就可以看出这一点。
eval('$scope.' + $attrs.ngModel + ' = "' + value + '";');
之所以出现这样的行,是因为我们不知道模型的名称。此名称由 ui-grid 引擎自动指定。您可以创建一个函数来代替 eval
来访问 $scope
的值并解析 $attrs.ngModel
值。
其次,当您创建一些指令时,所有 DOM 修改都应替换为 compile
部分。
第三,如果您在 ui-grid 中创建自己的编辑模式指令,则必须手动触发 BEGIN_CELL_EDIT、CANCEL_CELL_EDIT 和 END_CELL_EDIT 事件(请参阅http://ui-grid.info/docs/#/tutorial/201_editable)。在我们的代码中,我们在日期选择器的 onClose
属性 中执行此操作。我们不使用 onSelect
因为我们可以在输入上失去焦点并且日期选择器将关闭,但输入仍将打开。要停止编辑模式,我们必须触发 END_CELL_EDIT 事件:
$scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
JS代码:
var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
app.controller('MainController', function($scope) {
$scope.gridOptions = {
columnDefs: [{
name: 'startDate',
editableCellTemplate: '<input datepicker ng-model="MODEL_COL_FIELD" readonly>',
enableCellEdit: true,
width: 150
}],
data: [{
startDate: ''
}]
};
});
app.directive('datepicker', ['uiGridEditConstants', function(uiGridEditConstants) {
return {
restrict: 'A',
require: 'ngModel',
compile: function() {
return {
pre: function($scope, $elm, $attrs) {},
post: function($scope, $elm, $attrs) {
function setValueToScope(value) {
eval('$scope.' + $attrs.ngModel + ' = "' + value + '";');
$scope.$apply();
}
$elm = $($elm);
$elm.datepicker({
dateFormat: 'mm/dd/yy',
onSelect: function(date) {
setValueToScope(date);
},
onClose: function() {
$scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
}
});
$elm[0].focus();
}
};
}
};
}]);
您可以在此处查看完整代码及其工作原理:http://plnkr.co/edit/NfMuGpNDqIjvoAGJ2R1B
我正在使用 ui-网格。我使用 ui-grid-edit 启用了编辑功能。问题是日期选择器。 我希望日期选择器可以在所有浏览器中工作,但是启用类型 : "date" 是不可能的,因为它将提供 HTML5 支持的相同日期选择器。 所以我想使用自定义模板为 angular 启用 bootstrap 日期选择器 通过添加 editableCellTemplate
columnDefs : {
field:'accbirthdate',displayName :"Birth Date",enableCellEditOnFocus:true,editableCellTemplate: '<input type="text" ng-input="COL_FIELD" ng-model="COL_FIELD" datepicker-popup="dd-MM-yyyy" datepicker-append-to-body="true"/>'}
}
但它根本不起作用。我发现即使是输入文本中的 ng-click 也不是 working.So 任何人请帮助如何在 angular ui-grid
中启用 bootstarp 日期选择器一个月前我遇到了同样的问题。但我找不到解决方案。所以我改变主意使用自定义网格。
我使用了 table、tr、td 标签
看到这是我的 html 代码
<table ng-show="TimeSheetList.length!==0" class="table">
<tr>
<th style="background-color: #BBE1EF">Start Date</th>
<th style="background-color: #BBE1EF">Start Time</th>
<th style="background-color: #BBE1EF">End Time</th>
<th style="background-color: #BBE1EF">Total Hours</th>
<th style="background-color: #BBE1EF">Description</th>
<th style="background-color: #BBE1EF">Remarks</th>
</tr>
<tr ng-repeat="timesheetlist in TimeSheetList">
<td ng-dblclick="ChangeVal(this,'StartDate')"><span ng-hide="timesheetlist.IsEditStartDate">{{timesheetlist.StartDate}}</span>
<input style="width: 150px" type="text" class="form-control" date-time required="true" view="hours" partial="true" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="StartDate{{$index}}" ng-show="timesheetlist.IsEditStartDate" ng-model="timesheetlist.StartDate" />
</td>
<td><span ng-dblclick="ChangeVal(this,'StartTime')" ng-hide="timesheetlist.IsEditStartTime">{{timesheetlist.StartTime}}</span>
<timepicker hour-step="1" minute-step="1" show-meridian="true" ng-change="UpdateTimeSheet(this.timesheetlist)" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="StartTime{{$index}}" ng-show="timesheetlist.IsEditStartTime" ng-model="timesheetlist.StartTime"></timepicker>
</td>
<td><span ng-dblclick="ChangeVal(this,'EndTime')" ng-hide="timesheetlist.IsEditEndTime">{{timesheetlist.EndTime}}</span>
<timepicker hour-step="1" minute-step="1" show-meridian="true" ng-change="UpdateTimeSheet(this.timesheetlist)" ng-blur="UpdateTimeSheet(this.timesheetlist)" id="EndTime{{$index}}" ng-show="timesheetlist.IsEditEndTime" ng-model="timesheetlist.EndTime"></timepicker>
</td>
<td>
<input type="text" readonly="true" class="form-control" ng-model="timesheetlist.TotalHours" style="width: 200px" autofocus="">
</td>
<td><span ng-dblclick="ChangeVal(this,'Description')" ng-hide="timesheetlist.IsEditDescription">{{timesheetlist.Description}}</span>
<input style="width: 200px" type="text" class="form-control" ng-blur="UpdateTimeSheet(this.timesheetlist)" ng-show="timesheetlist.IsEditDescription" ng-model="timesheetlist.Description" /></td>
<td><span ng-dblclick="ChangeVal(this,'Remarks')" ng-hide="timesheetlist.IsEditRemarks">{{timesheetlist.Remarks}}</span>
<input style="width: 200px" type="text" class="form-control" ng-blur="UpdateTimeSheet(this.timesheetlist)" ng-show="timesheetlist.IsEditRemarks" ng-model="timesheetlist.Remarks" /></td>
</tr>
</table>
这是我的控制器代码
function loadTimeSheets(date) {
$http({
method: 'GET',
url: rootUrl + '/api/TimeSheet/LoadTimeSheet?date=' + date,
headers: {
'Content-Type': "application/json; charset=utf-8"
}
}).success(function (response) {
$scope.TimeSheetList = response;
if ($scope.TimeSheetList.length == 0) {
alert('You did not add your works in this date');
}
}).error(function (response, errorCode) {
if (errorCode == 444) {
//toastr.error('Your email address is does not verrified ', 'Error');
}
})
}
希望您可以根据需要自定义我的网格。
如果你不喜欢那样,那么你可以去 ng-Grid
是的,我认为这是因为当我们直接在 editableCellTemplate 上使用它时 HTML 代码没有被编译。 有关 Angular 模板编译如何工作的更多信息,请参阅此处 Angular Template Compiling
以下是我为解决此问题所做的工作。我将我的列 defs editableCellTemplate 替换为以下
columnDefs : {
field:'accbirthdate',displayName :"Birth Date",enableCellEditOnFocus: true,editableCellTemplate: '<input type="text" class="form-control" datepicker-popup="dd/MM/yyyy" ng-class="\'colt\' + col.index" ng-model="row.entity[col.field]" datepicker-append-to-body="true" is-open="istableDate" close-text="Close" table-date/>'}
}
与 gridEditor 一样,我在 directive.js 中创建了自己的指令 directive.js 我已经创建了指令
app.directive('tableDate',function($filter){
function parseDateString(dateString) {
if (typeof(dateString) === 'undefined' || dateString === '') {
return null;
}
var parts = dateString.split('/');
if (parts.length !== 3) {
return null;
}
var year = parseInt(parts[2], 10);
var month = parseInt(parts[1], 10);
var day = parseInt(parts[0], 10);
if (month < 1 || year < 1 || day < 1) {
return null;
}
return new Date(year, (month - 1), day);
}
function pad(s) { return (s < 10) ? '0' + s : s; }
return {
priority: -100, // run after default uiGridEditor directive
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
scope.istableDate = false;
scope.$on( 'uiGridEventBeginCellEdit', function () {
scope.istableDate = true;
});
element.on("click",function(){
scope.istableDate = true;
});
element.bind( 'blur', function () {
if(!scope.istableDate){
scope.$emit( 'uiGridEventEndCellEdit' );
}else{
scope.istableDate = false;
}
}); //when leaving the input element, emit the 'end cell edit' event
if (ngModel) {
ngModel.$formatters.push(function (modelValue) {
var modelValue= new Date(modelValue);
ngModel.$setValidity(null,(!modelValue || !isNaN(modelValue.getTime())));
return $filter('date')(modelValue, 'dd/MM/yyyy');
});
ngModel.$parsers.push(function (viewValue) {
if (viewValue ) {
var dateString = [pad(viewValue.getDate()), pad(viewValue.getMonth()+1), viewValue.getFullYear()].join('/')
var dateValue = parseDateString(dateString);
ngModel.$setValidity(null, (dateValue && !isNaN(dateValue.getTime())));
return dateValue;
}
else {
ngModel.$setValidity(null, true);
return null;
}
});
}
}
};
});
我的日期格式是 dd/MM/yyyy,在我们发出事件后选择您的格式,它会提到已更改。 现在我的 bootstrap 日期选择器在所有浏览器上为我的 ui-grid 工作。
如果您对此有任何疑问,请随时问我。我花了一天时间在这上面,我想把我的经验分享给其他人。
糟糕,不在 IE6 中:)
我也遇到了日期选择器的这个问题,因此决定添加一个默认的 jquery-ui。实际上,您可以添加任何人。
下面的代码需要ui一些解释。
首先,您的模板应如下所示:
editableCellTemplate: '<input datepicker ng-model="MODEL_COL_FIELD" readonly>'
它必须包含值为 MODEL_COL_FIELD
的 ng-model
属性。该值意味着您的输入将与单元格的模型绑定。 IE。停止编辑模式后的单元格(通常是 <div>
元素)将从我们的输入中获取值。 MODEL_COL_FIELD
值被 ui-grid 引擎替换为模型的真实名称。在我们的例子中,这是 row.entity['startDate']
。你看一个属性$attrs.ngModel
就可以看出这一点。
eval('$scope.' + $attrs.ngModel + ' = "' + value + '";');
之所以出现这样的行,是因为我们不知道模型的名称。此名称由 ui-grid 引擎自动指定。您可以创建一个函数来代替 eval
来访问 $scope
的值并解析 $attrs.ngModel
值。
其次,当您创建一些指令时,所有 DOM 修改都应替换为 compile
部分。
第三,如果您在 ui-grid 中创建自己的编辑模式指令,则必须手动触发 BEGIN_CELL_EDIT、CANCEL_CELL_EDIT 和 END_CELL_EDIT 事件(请参阅http://ui-grid.info/docs/#/tutorial/201_editable)。在我们的代码中,我们在日期选择器的 onClose
属性 中执行此操作。我们不使用 onSelect
因为我们可以在输入上失去焦点并且日期选择器将关闭,但输入仍将打开。要停止编辑模式,我们必须触发 END_CELL_EDIT 事件:
$scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
JS代码:
var app = angular.module('app', ['ui.grid', 'ui.grid.edit']);
app.controller('MainController', function($scope) {
$scope.gridOptions = {
columnDefs: [{
name: 'startDate',
editableCellTemplate: '<input datepicker ng-model="MODEL_COL_FIELD" readonly>',
enableCellEdit: true,
width: 150
}],
data: [{
startDate: ''
}]
};
});
app.directive('datepicker', ['uiGridEditConstants', function(uiGridEditConstants) {
return {
restrict: 'A',
require: 'ngModel',
compile: function() {
return {
pre: function($scope, $elm, $attrs) {},
post: function($scope, $elm, $attrs) {
function setValueToScope(value) {
eval('$scope.' + $attrs.ngModel + ' = "' + value + '";');
$scope.$apply();
}
$elm = $($elm);
$elm.datepicker({
dateFormat: 'mm/dd/yy',
onSelect: function(date) {
setValueToScope(date);
},
onClose: function() {
$scope.$emit(uiGridEditConstants.events.END_CELL_EDIT);
}
});
$elm[0].focus();
}
};
}
};
}]);
您可以在此处查看完整代码及其工作原理:http://plnkr.co/edit/NfMuGpNDqIjvoAGJ2R1B