(function (angular) { var module = angular.module('framework.directives.UI'); module.directive('fieldFor', fieldForDirective); module.directive('formFor', formForDirective); module.filter('propSearch', propertySearchFilter); formForDirective.$inject = ['Model']; function formForDirective(Model) { return { restrict: 'A', scope: true, transclude: true, template: function (element, attrs) { return '
'; }, link: function (scope, element, attrs, ctrls, transcludeFn) { scope.formFor = (scope.formFor || {}); scope.formFor.target = scope.$eval(attrs.formFor); scope.formFor.schema = (attrs.schema) ? Model[attrs.schema].$schema : scope.target.$$schema; scope.formFor.mode = 'EDIT'; scope.$watch(function () { return scope.target; }, function (newvalue) { }); if (attrs.mode) { scope.formFor.mode = attrs.mode; attrs.$observe('mode', function (newvalue) { scope.formFor.mode = newvalue; }); } transcludeFn(scope, function (clone, scope) { element.children('.transclude-target').append(clone); }); } } }; fieldForDirective.$inject = ['Model']; function fieldForDirective(Model) { var defaults = { inputType: 'text', required: false, selectTheme: 'selectize', selectSelectedTemplate: '{{$select.selected.Name}}', selectOptionTemplate: '
{{option.Description}}' }; return { restrict: 'A', scope: true, template: function (element, attrs) { var formParent = element.closest('[form-for]'), subformParent = element.closest('[sub-form-for]'), schemaName = ((subformParent.length) ? subformParent : formParent).attr('schema'), ctor = Model[schemaName], schema = ctor && ctor.$schema, fieldDef = schema && schema[attrs.fieldFor], subForm = subformParent.attr('sub-form-for') || ''; if (!fieldDef) { return; } var inputConfig = angular.extend({ display: attrs.fieldFor, inputType: 'text' }, defaults, fieldDef, fieldDef.input, attrs); //need to fetch these. var labelText = attrs.display || attrs.fieldFor, fieldName = attrs.fieldFor, selectFrom = attrs.selectFrom; var template = '' + '
' + '' + '
' + '

' + '
' + '
'; if (selectFrom) { template += '' + '' + '' + inputConfig.selectSelectedTemplate + '' + '' + inputConfig.selectOptionTemplate + ''+ ''; } else if (inputConfig.type === moment) { template += '' + '
' + buildElement('input', { class: 'form-control', type: 'text', name: subForm + fieldName + 'Input', ngModel: 'formFor.target.' + ((subForm) ? (subForm + '.') : '') + fieldName, ngRequired: inputConfig.required, datepickerPopup: 'dd/MM/yyyy', isOpen: 'opened', placeholder: 'DD/MM/YYYY', ngDisabled: angular.isDefined(inputConfig.editable) && !inputConfig.editable }) + '' + '' + '' + '
'; } else { if (inputConfig.append || inputConfig.prepend) { template += '
'; } if (inputConfig.prepend) { template += '' + '' + '' } template += buildElement('input', { class: 'form-control', type: inputConfig.inputType, name: subForm + fieldName + 'Input', ngModel: 'formFor.target.' + ((subForm) ? (subForm + '.') : '') + fieldName, ngRequired: inputConfig.required, placeholder: inputConfig.placeholder }); if (inputConfig.append) { template += '' + '' + '' } if (inputConfig.append || inputConfig.prepend) { template += '
'; } } template += '' + '
' + '
' + inputConfig.display + ' is required.
' + '
' + inputConfig.display + ' is incorrectly formatted.
' + '
' + inputConfig.display + ' is not a valid e-mail.
' + '
' + '
'; template += '
'; return template; }, link: function (scope, element, attrs) { scope.opened = false; scope.openCalendar = function (event) { event.preventDefault(); event.stopPropagation(); scope.opened = true; } } }; }; function propertySearchFilter() { return function (items, props) { var out = []; if (angular.isArray(items)) { items.forEach(function (item) { var itemMatches = false; var keys = Object.keys(props); for (var i = 0; i < keys.length; i++) { var prop = keys[i]; var text = props[prop].toLowerCase(); if (item[prop].toString().toLowerCase().indexOf(text) !== -1) { itemMatches = true; break; } } if (itemMatches) { out.push(item); } }); } else { // Let the output be the input untouched out = items; } return out; }; }; function buildElement(elementType, attrs) { var result = '<' + elementType + ' '; angular.forEach(attrs, function (value, key) { if (angular.isDefined(value) && value !== null) result += normalise(key) + '="' + value + '"'; }); if (elementType === 'input') { result += ' />'; } else { result += ' >'; } return result; } function normalise(input) { var result = ''; for (var i = 0; i < input.length; i++) { var char = input[i]; if (char == char.toUpperCase()) { result += '-' + char.toLowerCase(); } else { result += char; } } return result; } }(angular));