I am using angular x-editable in my project. http://vitalets.github.io/angular-xeditable/#editable-row
Anything works fine except of validation error displaying. Here is my HTML template:
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Width</th>
<th>Length</th>
<th>Sheets quantity</th>
<th>Low price</th>
<th>High price</th>
<th>Currency</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="material in sheetMaterials">
<td>
<span editable-text="material.name" e-name="name" e-form="form" e-required>
{{ material.name }}
</span>
</td>
<td>
<span editable-text="material.width" e-name="width" e-form="form" e-required>
{{ material.width }}
</span>
</td>
<td>
<span editable-text="material.length" e-name="length" e-form="form" e-required>
{{ material.length }}
</span>
</td>
<td>
<span editable-text="material.sheets" e-name="sheets" e-form="form" e-required>
{{ material.sheets }}
</span>
</td>
<td>
<span editable-text="material.priceLow" e-name="priceLow" e-form="form" e-required>
{{ material.priceLow }}
</span>
</td>
<td>
<span editable-text="material.priceHigh" e-name="priceHigh" e-form="form" e-required>
{{ material.priceHigh }}
</span>
</td>
<td>
<span editable-select="material.currency"
e-ng-options="s.value as s.text for s in currencies"
e-name="currency"
e-form="form"
e-required>
{{ showCurrency( material ) }}
</span>
</td>
<td style="white-space: nowrap">
<form editable-form name="form"
onaftersave="updateSheetMaterial( $data, material._id, form )"
ng-show="form.$visible"
class="form-buttons form-inline"
shown="inserted == material">
<button type="submit"
ng-disabled="form.$waiting"
class="btn btn-primary">
Save
</button>
<button type="button"
ng-disabled="form.$waiting"
ng-click="form.$cancel()"
class="btn btn-default">
Cancel
</button>
</form>
<div class="buttons" ng-show="!form.$visible">
<button class="btn btn-primary" ng-click="form.$show()">
Edit
</button>
<button class="btn btn-danger" ng-click="removeSheeteMaterial( materials, $index )">
Delete
</button>
</div>
</td>
</tr>
</tbody>
</table>
<button class="pull-right btn btn-primary" ng-click="createSheetMaterial()">Add</button>
Here is a controller where I handle form behaviour:
angular.module( 'client' )
.controller(
'materialController',
[
'$scope',
'$filter',
'sheetMaterialFactory',
function(
$scope,
$filter,
sheetMaterialFactory
){
/**
* index action
* @return void
*/
$scope.index = function(){
$scope.currencies = [
{ value: 'RUB', text: "Р" },
{ value: 'EUR', text: "€" },
{ value: 'USD', text: "$" },
]
sheetMaterialFactory.getList().then( function( materials ){
$scope.sheetMaterials = materials;
});
$scope.content = "partials/material.html";
}
$scope.showCurrency = function( material ){
var selected = $filter('filter')( $scope.currencies, { value: material.currency });
return ( material.currency && selected.length ) ? selected[ 0 ].text : 'Not set';
}
/**
* update sheet material
* @param data – object of material options
* @param _id – unique id of material
* @return void
*/
$scope.updateSheetMaterial = function( data, _id, form ){
data._id = _id;
var action = data._id ? "update" : "create";
sheetMaterialFactory
[ action ]( data )
.then( function( sheetMaterial ){
if( "update" == action ){
var collection = $scope.sheetMaterials;
collection = collectionService.updateObject( collection, sheetMaterial );
} else {
collection.push( sheetMaterial );
}
}, function( error ){
if( error.data.errors ){
angular.forEach( error.data.errors, function( errorData, field ){
form.$setError( field, errorData.message );
});
} else {
form.$setError( 'name', 'Неизвестная ошибка' );
}
});
}
/**
* create sheet material
* @return void
*/
$scope.createSheetMaterial = function( data ){
if( !data ){
var sheetMaterial = { name: "Some name" };
$scope.sheetMaterials.push( sheetMaterial );
return;
}
}
$scope.index();
}
]
);
I've checked all the minor details and see that form.$setError works perfect. Error text really assigned to form element. But it does not displaying after form submitted. If anyone knows how to fix it – your reply is appreciated.
I had similar problems, until I understood (actually read the docs) that validation of fields should be managed through onbeforesave
. If you want to define validation for one or more elements, which was my case, you can do so by using onbeforesave on the editable-* elements like this:
// on template (using controller as ctrl)
<span editable-select="material.currency"
e-ng-options="s.value as s.text for s in currencies"
e-name="currency"
e-form="form"
onbeforesave="ctrl.validateNotEmpty($data)"
e-required>
{{ showCurrency( material ) }}
</span>
// on controller
vm.validateNotEmpty(val) {
if (!val) {
return "This is a required field";
}
}
The validation method will be called and if it returns a string, then the form will remain open and the errors will be displayed as expected.
-- Update --
The above would apply to error-handling prior to sending the request. If the validation must be done server-side, then the usage of $setError
is of course the right way to go. I just added validation to a form like this, and worked perfectly:
// on controller
vm.updateMethod = function() {
return myHttpUpdateMethod(foo)
.catch(function(errors) {
// Extract field and error_msg
$scope.form.$setError(field, error_msg);
// very important, as we're catching the error reject the
// promise here, to stop the form from closing.
return $q.reject(errors);
});
}
Here is a nice jsFiddle I found: http://jsfiddle.net/NfPcH/81/
But I had to use a catch
instead of an error
in my special case. If you also use a catch
don't forget to return a reject, or else the
form will close.
Well, it seems I found one crappy solution. Not the best one, but it works. Any form element displaying should be typed this way:
<span editable-text="material.name" e-name="name" e-form="form" e-required>
{{ material.name || form.$editables[ 0 ].error }}
</span>
form.$editables[ 0 ].error
– is a direct access to errorText for element number 0 in form
elements array. Solution is bad because you have to watch manually the index of your element and any form changes will cause fixing elements indexes.
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