I have an HTML table as below:
<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>
I am using the contenteditable directive to make the cells 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
});
}
};
}]);
You can see the Jsfiddle here: http://jsfiddle.net/u1vbeos5/144/
Click to add column and it would add dynamic column. Start typing in row 1, after it will automatically create another dynamic row.
What I want now is to add required field validation for each row so that when someone clicks save it triggers validation and highlights all empty row.
I am not sure how can we do this. I believe we have to do something at the directive end to find out empty row and highlight it.
Any inputs ?
Thanks
No need to change your directive, the built-in ng-required already works. Just add a form controller as mentioned in the comments. If you don't add a form controller, you will need to validate all fields yourself on $scope.save
.
Add ng-required to your model:
<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
means the field is required if it is not the last row (I've assumed this based on how you add rows). Angularjs will set the class ng-invalid
on the td
element if there is no value.
Since there does not seem to be a form, add ng-form
to the table markup. Alternatively, this can be wrapped with a form
tag which should achieve the same thing.
<table class="table table-bordered"
ng-form="targetTableForm"
ng-class="{submitted: targetTableSubmitted}">
On save, check if the form is valid and mark the form as submitted. This will add the submitted
class to the table based on the markup above.
$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
*/
};
Then finally, add css to highlight the table cell:
.table.submitted td.ng-invalid {
background-color: red;
}
Another approach would be disable the save button if the form is invalid.
Note that the Name column does not have an ng-model so it won't be bound to anything and so it wont be validated.
See updated jsfiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With