AngularJs:HTML table 的动态行的必填字段验证和突出显示与 contenteditable
AngularJs: Required field validation and highlight for dynamic rows of HTML table with contenteditable
我有一个 HTML table 如下:
<tbody>
<tr ng-repeat="r in targetTable.rows">
<td contenteditable="true" class=""></td>
<td contenteditable="true"
ng-repeat="column in targetTable.columns"
ng-model="r[column.id]"
ng-blur="!r.id? addNewRow(r[column.id], r): undefined">
</td>
</tr>
</tbody>
我正在使用 contenteditable 指令使单元格 editable。
app.directive('contenteditable', ['$sce', function($sce) {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
var disable = (attrs.contenteditable === "false") || !Boolean(attrs.contenteditable);
if (!ngModel || disable) return; // do nothing if no ng-model
// Write data to the model
var read = function(value) {
var html = element.html() || (typeof value === "string" ? value : "");
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if (attrs.stripBr && html == '<br>') {
html = '';
}
ngModel.$setViewValue(html);
};
// Specify how UI should be updated
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
};
// Listen for change events to enable binding
element.on('blur keyup change', function() {
scope.$evalAsync(read);
});
setTimeout(function() {
read(ngModel.$modelValue); // initialize
});
}
};
}]);
您可以在此处查看 Jsfiddle:http://jsfiddle.net/u1vbeos5/144/
点击添加列,会添加动态列。在第 1 行开始输入,之后它会自动创建另一个动态行。
我现在想要的是为每一行添加必填字段验证,这样当有人点击保存时它会触发验证并突出显示所有空行。
我不知道我们该怎么做。我相信我们必须在指令末尾做一些事情来找出空行并突出显示它。
有任何输入吗?
谢谢
问题是 <td>
不工作。先尝试只用一个,看看如何正确处理 N 列和 N 行。
当有人点击保存时,您可以传递行数组并在该对象中添加一个 valid/invalid 布尔值,然后使用 ng-class 是否突出显示该单元格,具体取决于结果.
<td contenteditable="true" ng-model="r.value"
ng-class="r.invalid ? 'cell-highlighted' : ''">
</td>
$scope.save = function(rows, columns) {
rows.forEach(row => {
if (!row.value || row.value.trim() === '') {
row.invalid = true;
} else {
row.invalid = false;
}
})
alert('please fill table data');
};
我已经修改了你的fiddle,希望你能使用它。
无需更改您的指令,内置的 ng-required 已经可以使用。只需添加评论中提到的 form 控制器即可。如果您不添加表单控制器,则需要在 $scope.save
.
上自行验证所有字段
将 ng-required 添加到您的模型:
<td contenteditable="true"
ng-repeat="column in targetTable.columns"
ng-model="r[column.id]"
ng-blur="!r.id? addNewRow(r[column.id], r): undefined"
ng-required="!$parent.$last"></td>
ng-required=$parent.$last
表示如果该字段不是最后一行,则该字段是必需的(我根据添加行的方式假设了这一点)。如果没有值,Angularjs 将在 td
元素上设置 class ng-invalid
。
由于似乎没有表格,所以将 ng-form
添加到 table 标记中。或者,这可以用一个 form
标签包装起来,它应该能达到同样的效果。
<table class="table table-bordered"
ng-form="targetTableForm"
ng-class="{submitted: targetTableSubmitted}">
保存时,检查表单是否有效并将表单标记为已提交。这将根据上面的标记将 submitted
class 添加到 table。
$scope.save = function() {
$scope.targetTableSubmitted = true;
if ($scope.targetTableForm.$valid) {
alert('submitted');
} else {
alert('please fill table data');
}
/**
* If no form controller is defined, manually loop through all rows
* and columns to check for a value
*/
};
最后,添加 css 以突出显示 table 单元格:
.table.submitted td.ng-invalid {
background-color: red;
}
另一种方法是在表单无效时禁用保存按钮。
请注意,Name 列没有 ng-model,因此它不会绑定到任何东西,因此不会被验证。
查看更新jsfiddle
我有一个 HTML table 如下:
<tbody>
<tr ng-repeat="r in targetTable.rows">
<td contenteditable="true" class=""></td>
<td contenteditable="true"
ng-repeat="column in targetTable.columns"
ng-model="r[column.id]"
ng-blur="!r.id? addNewRow(r[column.id], r): undefined">
</td>
</tr>
</tbody>
我正在使用 contenteditable 指令使单元格 editable。
app.directive('contenteditable', ['$sce', function($sce) {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
var disable = (attrs.contenteditable === "false") || !Boolean(attrs.contenteditable);
if (!ngModel || disable) return; // do nothing if no ng-model
// Write data to the model
var read = function(value) {
var html = element.html() || (typeof value === "string" ? value : "");
// When we clear the content editable the browser leaves a <br> behind
// If strip-br attribute is provided then we strip this out
if (attrs.stripBr && html == '<br>') {
html = '';
}
ngModel.$setViewValue(html);
};
// Specify how UI should be updated
ngModel.$render = function() {
element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));
};
// Listen for change events to enable binding
element.on('blur keyup change', function() {
scope.$evalAsync(read);
});
setTimeout(function() {
read(ngModel.$modelValue); // initialize
});
}
};
}]);
您可以在此处查看 Jsfiddle:http://jsfiddle.net/u1vbeos5/144/
点击添加列,会添加动态列。在第 1 行开始输入,之后它会自动创建另一个动态行。
我现在想要的是为每一行添加必填字段验证,这样当有人点击保存时它会触发验证并突出显示所有空行。
我不知道我们该怎么做。我相信我们必须在指令末尾做一些事情来找出空行并突出显示它。
有任何输入吗?
谢谢
问题是 <td>
不工作。先尝试只用一个,看看如何正确处理 N 列和 N 行。
当有人点击保存时,您可以传递行数组并在该对象中添加一个 valid/invalid 布尔值,然后使用 ng-class 是否突出显示该单元格,具体取决于结果.
<td contenteditable="true" ng-model="r.value"
ng-class="r.invalid ? 'cell-highlighted' : ''">
</td>
$scope.save = function(rows, columns) {
rows.forEach(row => {
if (!row.value || row.value.trim() === '') {
row.invalid = true;
} else {
row.invalid = false;
}
})
alert('please fill table data');
};
我已经修改了你的fiddle,希望你能使用它。
无需更改您的指令,内置的 ng-required 已经可以使用。只需添加评论中提到的 form 控制器即可。如果您不添加表单控制器,则需要在 $scope.save
.
将 ng-required 添加到您的模型:
<td contenteditable="true"
ng-repeat="column in targetTable.columns"
ng-model="r[column.id]"
ng-blur="!r.id? addNewRow(r[column.id], r): undefined"
ng-required="!$parent.$last"></td>
ng-required=$parent.$last
表示如果该字段不是最后一行,则该字段是必需的(我根据添加行的方式假设了这一点)。如果没有值,Angularjs 将在 td
元素上设置 class ng-invalid
。
由于似乎没有表格,所以将 ng-form
添加到 table 标记中。或者,这可以用一个 form
标签包装起来,它应该能达到同样的效果。
<table class="table table-bordered"
ng-form="targetTableForm"
ng-class="{submitted: targetTableSubmitted}">
保存时,检查表单是否有效并将表单标记为已提交。这将根据上面的标记将 submitted
class 添加到 table。
$scope.save = function() {
$scope.targetTableSubmitted = true;
if ($scope.targetTableForm.$valid) {
alert('submitted');
} else {
alert('please fill table data');
}
/**
* If no form controller is defined, manually loop through all rows
* and columns to check for a value
*/
};
最后,添加 css 以突出显示 table 单元格:
.table.submitted td.ng-invalid {
background-color: red;
}
另一种方法是在表单无效时禁用保存按钮。
请注意,Name 列没有 ng-model,因此它不会绑定到任何东西,因此不会被验证。
查看更新jsfiddle