Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
AutoFields Repeater
<div class="autofields-repeater">
<div ui-sortable="sortableOptions" ng-model="ngModel">
<div class="autofields-repeater-container panel panel-default" ng-repeat="item in ngModel">
<div class="panel-heading">
<h4 class="panel-title" ng-bind="field.title"></h4>
<button type="button" class="close" title="Remove" ng-click="removeItem(item, $index)">&times;</button>
</div>
<auto:fields fields="field.fields" class="panel-body" data="item" options="field.options" form="item{{$index}}"></auto:fields>
</div>
</div>
<button type="button" class="btn btn-default" ng-click="addItem()" ng-if="addIf">Add {{field.title}}</button>
</div>
'use strict';
angular.module('app')
.directive('autofieldsRepeater', ['$compile', '$timeout', function ($compile, $timeout) {
return {
restrict: 'E',
templateUrl: '/Client/directives/angular-repeater.html',
require: '?ngModel',
replace: true,
scope: true,
link: function (scope, el, attr, ctrl) {
scope.$watch(attr.field, function (value) {
scope.field = value;
if (scope.field.options != null && scope.field.options.startWithOne && (ctrl.$modelValue == null || ctrl.$modelValue.length == 0)) {
scope.addItem();
}
});
scope.$watch(attr.ngModel, function (value) {
if (typeof value != 'object') return;
scope.ngModel = value;
});
scope.addItem = function () {
var data = ctrl.$modelValue || [];
var newItem = {}
if (scope.field.options && scope.field.options.addItem) scope.field.options.addItem(newItem, scope);
data.push(newItem);
ctrl.$setViewValue(data);
ctrl.$validate();
};
scope.removeItem = function (item, index) {
var data = ctrl.$modelValue;
if (scope.field.options && scope.field.options.removeItem) scope.field.options.removeItem(item, scope);
data.splice(index, 1);
ctrl.$setViewValue(data);
ctrl.$validate();
};
scope.sortableOptions = {
axis: 'y',
placeholder: 'repeater-placeholder',
forcePlaceholderSize: true,
opacity: .5,
tolerance: 'pointer'
};
scope.addIf = true;
scope.validate = function () {
$timeout(function () {
ctrl.$validate();
}, 0);
}
// Validation
//============================================
ctrl.$validators = {
'required': function (values) {
if (!attr.required || attr.require === false) return true;
if (!values) return false;
return values.length != 0;
},
'max': function (values) {
if (!attr.max) return true;
if (!values) return false;
return values.length <= attr.max;
},
'min': function (values) {
if (!attr.min) return true;
if (!values) return false;
return values.length >= attr.min;
},
'custom': function (values) {
if (scope.field && scope.field.options && scope.field.options.addIf) scope.addIf = scope.field.options.addIf(values, scope);
if (scope.field && scope.field.options && scope.field.options.validate) {
console.log(scope.field.options.validate(values));
return scope.field.options.validate(values);
}
return true;
}
};
}
}
}]);
'use strict';
angular.module('autofields.extended', ['autofields', 'ui.bootstrap'])
.config(['$autofieldsProvider', function ($autofieldsProvider) {
// Repeater
$autofieldsProvider.registerHandler('repeater', function (directive, field, index) {
var fieldElements = $autofieldsProvider.field(directive, field, '<autofields-repeater/>', { field: '$schema[' + index + ']', ngModelOptions:'{ allowInvalid: true}', ngClass: "{'has-error': $form.$property.$invalid}" });
fieldElements.input.attr('class', '');
return fieldElements.fieldContainer;
});
}]);
angular.module('app',['ui.bootstrap', 'autofields', 'autofields.extended'])
.run(function($rootScope){
$rootScope.fields = [
{
property: 'users', label: '', type: 'repeater', attr: { min: 1, max: 3, required: true }, title: 'User', fields: [
{ property: 'name', attr: { required: true } },
{ property: 'email', type: 'email' attr: { required: true } },
{ property: 'age', type: 'number', attr: { required: true, min: 0 } }
],
options: {
startWithOne: true
}
}
]
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment