Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

angular-schema-form

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-schema-form - npm Package Compare versions

Comparing version 0.8.0 to 0.8.2

bower_components/ace-builds/demo/kitchen-sink/ace-logo.png

2

bower.json

@@ -7,3 +7,3 @@ {

],
"version": "0.8.0",
"version": "0.8.2",
"authors": [

@@ -10,0 +10,0 @@ "Textalk",

angular.module("schemaForm").run(["$templateCache", function($templateCache) {$templateCache.put("directives/decorators/bootstrap/actions-trcl.html","<div class=\"btn-group schema-form-actions {{form.htmlClass}}\" ng-transclude=\"\"></div>");
$templateCache.put("directives/decorators/bootstrap/actions.html","<div class=\"btn-group schema-form-actions {{form.htmlClass}}\"><input ng-repeat-start=\"item in form.items\" type=\"submit\" class=\"btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}\" value=\"{{item.title}}\" ng-if=\"item.type === \'submit\'\"> <button ng-repeat-end=\"\" class=\"btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}\" type=\"button\" ng-disabled=\"form.readonly\" ng-if=\"item.type !== \'submit\'\" ng-click=\"buttonClick($event,item)\"><span ng-if=\"item.icon\" class=\"{{item.icon}}\"></span>{{item.title}}</button></div>");
$templateCache.put("directives/decorators/bootstrap/array.html","<div sf-array=\"form\" class=\"schema-form-array {{form.htmlClass}}\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\"><h3 ng-show=\"form.title && form.notitle !== true\">{{ form.title }}</h3><ol class=\"list-group\" ng-model=\"modelArray\" ui-sortable=\"\"><li class=\"list-group-item {{form.fieldHtmlClass}}\" ng-repeat=\"item in modelArray track by $index\"><button ng-hide=\"form.readonly || form.remove === null\" ng-click=\"deleteFromArray($index)\" style=\"position: relative; z-index: 20;\" type=\"button\" class=\"close pull-right\"><span aria-hidden=\"true\">&times;</span><span class=\"sr-only\">Close</span></button><sf-decorator ng-init=\"arrayIndex = $index\" form=\"copyWithIndex($index)\"></sf-decorator></li></ol><div class=\"clearfix\" style=\"padding: 15px;\"><button ng-hide=\"form.readonly || form.add === null\" ng-click=\"appendToArray()\" type=\"button\" class=\"btn {{ form.style.add || \'btn-default\' }} pull-right\"><i class=\"glyphicon glyphicon-plus\"></i> {{ form.add || \'Add\'}}</button></div><div class=\"help-block\" ng-show=\"(hasError() && errorMessage(schemaError())) || form.description\" ng-bind-html=\"(hasError() && errorMessage(schemaError())) || form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/checkbox.html","<div class=\"checkbox schema-form-checkbox {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><label><input type=\"checkbox\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" class=\"{{form.fieldHtmlClass}}\" name=\"{{form.key.slice(-1)[0]}}\"> <span ng-bind-html=\"form.title\"></span></label><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/checkboxes.html","<div sf-array=\"form\" ng-model=\"$$value$$\" class=\"form-group schema-form-checkboxes {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><label class=\"control-label\" ng-show=\"showTitle()\">{{form.title}}</label><div class=\"checkbox\" ng-repeat=\"val in titleMapValues track by $index\"><label><input type=\"checkbox\" ng-disabled=\"form.readonly\" sf-changed=\"form\" class=\"{{form.fieldHtmlClass}}\" ng-model=\"titleMapValues[$index]\" schema-vaidate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"> <span ng-bind-html=\"form.titleMap[$index].name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/default.html","<div class=\"form-group schema-form-{{form.type}} {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess(), \'has-feedback\': form.feedback !== false }\"><label class=\"control-label\" ng-class=\"{\'sr-only\': !showTitle()}\" for=\"{{form.key.slice(-1)[0]}}\">{{form.title}}</label> <input ng-if=\"!form.fieldAddonLeft && !form.fieldAddonRight\" ng-show=\"form.key\" type=\"{{form.type}}\" step=\"any\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" ng-model-options=\"form.ngModelOptions\" ng-model=\"$$value$$\" ng-disabled=\"form.readonly\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\" aria-describedby=\"{{form.key.slice(-1)[0] + \'Status\'}}\"><div ng-if=\"form.fieldAddonLeft || form.fieldAddonRight\" ng-class=\"{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}\"><span ng-if=\"form.fieldAddonLeft\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonLeft\"></span> <input ng-show=\"form.key\" type=\"{{form.type}}\" step=\"any\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" ng-model-options=\"form.ngModelOptions\" ng-model=\"$$value$$\" ng-disabled=\"form.readonly\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\" aria-describedby=\"{{form.key.slice(-1)[0] + \'Status\'}}\"> <span ng-if=\"form.fieldAddonRight\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonRight\"></span></div><span ng-if=\"form.feedback !== false\" class=\"form-control-feedback\" ng-class=\"evalInScope(form.feedback) || {\'glyphicon\': true, \'glyphicon-ok\': hasSuccess(), \'glyphicon-remove\': hasError() }\" aria-hidden=\"true\"></span> <span ng-if=\"hasError() || hasSuccess()\" id=\"{{form.key.slice(-1)[0] + \'Status\'}}\" class=\"sr-only\">{{ hasSuccess() ? \'(success)\' : \'(error)\' }}</span><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/checkbox.html","<div class=\"checkbox schema-form-checkbox {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><label class=\"{{form.labelHtmlClass}}\"><input type=\"checkbox\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" class=\"{{form.fieldHtmlClass}}\" name=\"{{form.key.slice(-1)[0]}}\"> <span ng-bind-html=\"form.title\"></span></label><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/checkboxes.html","<div sf-array=\"form\" ng-model=\"$$value$$\" class=\"form-group schema-form-checkboxes {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><label class=\"control-label {{form.labelHtmlClass}}\" ng-show=\"showTitle()\">{{form.title}}</label><div class=\"checkbox\" ng-repeat=\"val in titleMapValues track by $index\"><label><input type=\"checkbox\" ng-disabled=\"form.readonly\" sf-changed=\"form\" class=\"{{form.fieldHtmlClass}}\" ng-model=\"titleMapValues[$index]\" schema-vaidate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"> <span ng-bind-html=\"form.titleMap[$index].name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/default.html","<div class=\"form-group schema-form-{{form.type}} {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess(), \'has-feedback\': form.feedback !== false }\"><label class=\"control-label {{form.labelHtmlClass}}\" ng-class=\"{\'sr-only\': !showTitle()}\" for=\"{{form.key.slice(-1)[0]}}\">{{form.title}}</label> <input ng-if=\"!form.fieldAddonLeft && !form.fieldAddonRight\" ng-show=\"form.key\" type=\"{{form.type}}\" step=\"any\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" ng-model-options=\"form.ngModelOptions\" ng-model=\"$$value$$\" ng-disabled=\"form.readonly\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\" aria-describedby=\"{{form.key.slice(-1)[0] + \'Status\'}}\"><div ng-if=\"form.fieldAddonLeft || form.fieldAddonRight\" ng-class=\"{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}\"><span ng-if=\"form.fieldAddonLeft\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonLeft\"></span> <input ng-show=\"form.key\" type=\"{{form.type}}\" step=\"any\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" ng-model-options=\"form.ngModelOptions\" ng-model=\"$$value$$\" ng-disabled=\"form.readonly\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\" aria-describedby=\"{{form.key.slice(-1)[0] + \'Status\'}}\"> <span ng-if=\"form.fieldAddonRight\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonRight\"></span></div><span ng-if=\"form.feedback !== false\" class=\"form-control-feedback\" ng-class=\"evalInScope(form.feedback) || {\'glyphicon\': true, \'glyphicon-ok\': hasSuccess(), \'glyphicon-remove\': hasError() }\" aria-hidden=\"true\"></span> <span ng-if=\"hasError() || hasSuccess()\" id=\"{{form.key.slice(-1)[0] + \'Status\'}}\" class=\"sr-only\">{{ hasSuccess() ? \'(success)\' : \'(error)\' }}</span><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/fieldset-trcl.html","<fieldset ng-disabled=\"form.readonly\" class=\"schema-form-fieldset {{form.htmlClass}}\"><legend ng-show=\"form.title\">{{ form.title }}</legend><div class=\"help-block\" ng-show=\"form.description\" ng-bind-html=\"form.description\"></div><div ng-transclude=\"\"></div></fieldset>");
$templateCache.put("directives/decorators/bootstrap/fieldset.html","<fieldset ng-disabled=\"form.readonly\" class=\"schema-form-fieldset {{form.htmlClass}}\"><legend ng-show=\"form.title\">{{ form.title }}</legend><div class=\"help-block\" ng-show=\"form.description\" ng-bind-html=\"form.description\"></div><sf-decorator ng-repeat=\"item in form.items\" form=\"item\"></sf-decorator></fieldset>");
$templateCache.put("directives/decorators/bootstrap/help.html","<div class=\"helpvalue schema-form-helpvalue {{form.htmlClass}}\" ng-bind-html=\"form.helpvalue\"></div>");
$templateCache.put("directives/decorators/bootstrap/radio-buttons.html","<div class=\"form-group schema-form-radiobuttons {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><div><label class=\"control-label\" ng-show=\"showTitle()\">{{form.title}}</label></div><div class=\"btn-group\"><label class=\"btn {{ (item.value === $$value$$) ? form.style.selected || \'btn-default\' : form.style.unselected || \'btn-default\'; }}\" ng-class=\"{ active: item.value === $$value$$ }\" ng-repeat=\"item in form.titleMap\"><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" style=\"display: none;\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/radios-inline.html","<div class=\"form-group schema-form-radios-inline {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><label class=\"control-label\" ng-show=\"showTitle()\">{{form.title}}</label><div><label class=\"radio-inline\" ng-repeat=\"item in form.titleMap\"><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/radios.html","<div class=\"form-group schema-form-radios {{form.htmlClass}}\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><label class=\"control-label\" ng-show=\"showTitle()\">{{form.title}}</label><div class=\"radio\" ng-repeat=\"item in form.titleMap\"><label><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/radio-buttons.html","<div class=\"form-group schema-form-radiobuttons {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><div><label class=\"control-label {{form.labelHtmlClass}}\" ng-show=\"showTitle()\">{{form.title}}</label></div><div class=\"btn-group\"><label class=\"btn {{ (item.value === $$value$$) ? form.style.selected || \'btn-default\' : form.style.unselected || \'btn-default\'; }}\" ng-class=\"{ active: item.value === $$value$$ }\" ng-repeat=\"item in form.titleMap\"><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" style=\"display: none;\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/radios-inline.html","<div class=\"form-group schema-form-radios-inline {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><label class=\"control-label {{form.labelHtmlClass}}\" ng-show=\"showTitle()\">{{form.title}}</label><div><label class=\"radio-inline\" ng-repeat=\"item in form.titleMap\"><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/radios.html","<div class=\"form-group schema-form-radios {{form.htmlClass}}\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><label class=\"control-label {{form.labelHtmlClass}}\" ng-show=\"showTitle()\">{{form.title}}</label><div class=\"radio\" ng-repeat=\"item in form.titleMap\"><label><input type=\"radio\" class=\"{{form.fieldHtmlClass}}\" sf-changed=\"form\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" ng-value=\"item.value\" name=\"{{form.key.join(\'.\')}}\"> <span ng-bind-html=\"item.name\"></span></label></div><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/section.html","<div class=\"schema-form-section {{form.htmlClass}}\"><sf-decorator ng-repeat=\"item in form.items\" form=\"item\"></sf-decorator></div>");
$templateCache.put("directives/decorators/bootstrap/select.html","<div class=\"form-group {{form.htmlClass}} schema-form-select\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess(), \'has-feedback\': form.feedback !== false}\"><label class=\"control-label\" ng-show=\"showTitle()\">{{form.title}}</label><select ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" ng-disabled=\"form.readonly\" sf-changed=\"form\" class=\"form-control {{form.fieldHtmlClass}}\" schema-validate=\"form\" ng-options=\"item.value as item.name group by item.group for item in form.titleMap\" name=\"{{form.key.slice(-1)[0]}}\"></select><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/select.html","<div class=\"form-group {{form.htmlClass}} schema-form-select\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess(), \'has-feedback\': form.feedback !== false}\"><label class=\"control-label {{form.labelHtmlClass}}\" ng-show=\"showTitle()\">{{form.title}}</label><select ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" ng-disabled=\"form.readonly\" sf-changed=\"form\" class=\"form-control {{form.fieldHtmlClass}}\" schema-validate=\"form\" ng-options=\"item.value as item.name group by item.group for item in form.titleMap\" name=\"{{form.key.slice(-1)[0]}}\"></select><div class=\"help-block\" sf-message=\"form.description\"></div></div>");
$templateCache.put("directives/decorators/bootstrap/submit.html","<div class=\"form-group schema-form-submit {{form.htmlClass}}\"><input type=\"submit\" class=\"btn {{ form.style || \'btn-primary\' }} {{form.fieldHtmlClass}}\" value=\"{{form.title}}\" ng-disabled=\"form.readonly\" ng-if=\"form.type === \'submit\'\"> <button class=\"btn {{ form.style || \'btn-default\' }}\" type=\"button\" ng-click=\"buttonClick($event,form)\" ng-disabled=\"form.readonly\" ng-if=\"form.type !== \'submit\'\"><span ng-if=\"form.icon\" class=\"{{form.icon}}\"></span> {{form.title}}</button></div>");
$templateCache.put("directives/decorators/bootstrap/tabarray.html","<div sf-array=\"form\" ng-init=\"selected = { tab: 0 }\" class=\"clearfix schema-form-tabarray schema-form-tabarray-{{form.tabType || \'left\'}} {{form.htmlClass}}\"><div ng-if=\"!form.tabType || form.tabType !== \'right\'\" ng-class=\"{\'col-xs-3\': !form.tabType || form.tabType === \'left\'}\"><ul class=\"nav nav-tabs\" ng-class=\"{ \'tabs-left\': !form.tabType || form.tabType === \'left\'}\"><li ng-repeat=\"item in modelArray track by $index\" ng-click=\"$event.preventDefault() || (selected.tab = $index)\" ng-class=\"{active: selected.tab === $index}\"><a href=\"#\">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide=\"form.readonly\" ng-click=\"$event.preventDefault() || (selected.tab = appendToArray().length - 1)\"><a href=\"#\"><i class=\"glyphicon glyphicon-plus\"></i> {{ form.add || \'Add\'}}</a></li></ul></div><div ng-class=\"{\'col-xs-9\': !form.tabType || form.tabType === \'left\' || form.tabType === \'right\'}\"><div class=\"tab-content {{form.fieldHtmlClass}}\"><div class=\"tab-pane clearfix\" ng-repeat=\"item in modelArray track by $index\" ng-show=\"selected.tab === $index\" ng-class=\"{active: selected.tab === $index}\"><sf-decorator ng-init=\"arrayIndex = $index\" form=\"copyWithIndex($index)\"></sf-decorator><button ng-hide=\"form.readonly\" ng-click=\"selected.tab = deleteFromArray($index).length - 1\" type=\"button\" class=\"btn {{ form.style.remove || \'btn-default\' }} pull-right\"><i class=\"glyphicon glyphicon-trash\"></i> {{ form.remove || \'Remove\'}}</button></div></div></div><div ng-if=\"form.tabType === \'right\'\" class=\"col-xs-3\"><ul class=\"nav nav-tabs tabs-right\"><li ng-repeat=\"item in modelArray track by $index\" ng-click=\"$event.preventDefault() || (selected.tab = $index)\" ng-class=\"{active: selected.tab === $index}\"><a href=\"#\">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide=\"form.readonly\" ng-click=\"$event.preventDefault() || appendToArray()\"><a href=\"#\"><i class=\"glyphicon glyphicon-plus\"></i> {{ form.add || \'Add\'}}</a></li></ul></div></div>");
$templateCache.put("directives/decorators/bootstrap/tabs.html","<div ng-init=\"selected = { tab: 0 }\" class=\"schema-form-tabs {{form.htmlClass}}\"><ul class=\"nav nav-tabs\"><li ng-repeat=\"tab in form.tabs\" ng-disabled=\"form.readonly\" ng-click=\"$event.preventDefault() || (selected.tab = $index)\" ng-class=\"{active: selected.tab === $index}\"><a href=\"#\">{{ tab.title }}</a></li></ul><div class=\"tab-content {{form.fieldHtmlClass}}\"><div class=\"tab-pane\" ng-disabled=\"form.readonly\" ng-repeat=\"tab in form.tabs\" ng-show=\"selected.tab === $index\" ng-class=\"{active: selected.tab === $index}\"><bootstrap-decorator ng-repeat=\"item in tab.items\" form=\"item\"></bootstrap-decorator></div></div></div>");
$templateCache.put("directives/decorators/bootstrap/textarea.html","<div class=\"form-group has-feedback {{form.htmlClass}} schema-form-textarea\" ng-class=\"{\'has-error\': hasError(), \'has-success\': hasSuccess()}\"><label ng-class=\"{\'sr-only\': !showTitle()}\" for=\"{{form.key.slice(-1)[0]}}\">{{form.title}}</label> <textarea ng-if=\"!form.fieldAddonLeft && !form.fieldAddonRight\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"></textarea><div ng-if=\"form.fieldAddonLeft || form.fieldAddonRight\" ng-class=\"{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}\"><span ng-if=\"form.fieldAddonLeft\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonLeft\"></span> <textarea class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"></textarea> <span ng-if=\"form.fieldAddonRight\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonRight\"></span></div><span class=\"help-block\" sf-message=\"form.description\"></span></div>");}]);
$templateCache.put("directives/decorators/bootstrap/textarea.html","<div class=\"form-group has-feedback {{form.htmlClass}} schema-form-textarea\" ng-class=\"{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}\"><label class=\"{{form.labelHtmlClass}}\" ng-class=\"{\'sr-only\': !showTitle()}\" for=\"{{form.key.slice(-1)[0]}}\">{{form.title}}</label> <textarea ng-if=\"!form.fieldAddonLeft && !form.fieldAddonRight\" class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"></textarea><div ng-if=\"form.fieldAddonLeft || form.fieldAddonRight\" ng-class=\"{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}\"><span ng-if=\"form.fieldAddonLeft\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonLeft\"></span> <textarea class=\"form-control {{form.fieldHtmlClass}}\" id=\"{{form.key.slice(-1)[0]}}\" sf-changed=\"form\" placeholder=\"{{form.placeholder}}\" ng-disabled=\"form.readonly\" ng-model=\"$$value$$\" ng-model-options=\"form.ngModelOptions\" schema-validate=\"form\" name=\"{{form.key.slice(-1)[0]}}\"></textarea> <span ng-if=\"form.fieldAddonRight\" class=\"input-group-addon\" ng-bind-html=\"form.fieldAddonRight\"></span></div><span class=\"help-block\" sf-message=\"form.description\"></span></div>");}]);
angular.module('schemaForm').config(['schemaFormDecoratorsProvider', function(decoratorsProvider) {

@@ -20,0 +20,0 @@ var base = 'directives/decorators/bootstrap/';

@@ -1,1 +0,1 @@

angular.module("schemaForm").run(["$templateCache",function(e){e.put("directives/decorators/bootstrap/actions-trcl.html",'<div class="btn-group schema-form-actions {{form.htmlClass}}" ng-transclude=""></div>'),e.put("directives/decorators/bootstrap/actions.html",'<div class="btn-group schema-form-actions {{form.htmlClass}}"><input ng-repeat-start="item in form.items" type="submit" class="btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}" value="{{item.title}}" ng-if="item.type === \'submit\'"> <button ng-repeat-end="" class="btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}" type="button" ng-disabled="form.readonly" ng-if="item.type !== \'submit\'" ng-click="buttonClick($event,item)"><span ng-if="item.icon" class="{{item.icon}}"></span>{{item.title}}</button></div>'),e.put("directives/decorators/bootstrap/array.html",'<div sf-array="form" class="schema-form-array {{form.htmlClass}}" ng-model="$$value$$" ng-model-options="form.ngModelOptions"><h3 ng-show="form.title && form.notitle !== true">{{ form.title }}</h3><ol class="list-group" ng-model="modelArray" ui-sortable=""><li class="list-group-item {{form.fieldHtmlClass}}" ng-repeat="item in modelArray track by $index"><button ng-hide="form.readonly || form.remove === null" ng-click="deleteFromArray($index)" style="position: relative; z-index: 20;" type="button" class="close pull-right"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><sf-decorator ng-init="arrayIndex = $index" form="copyWithIndex($index)"></sf-decorator></li></ol><div class="clearfix" style="padding: 15px;"><button ng-hide="form.readonly || form.add === null" ng-click="appendToArray()" type="button" class="btn {{ form.style.add || \'btn-default\' }} pull-right"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</button></div><div class="help-block" ng-show="(hasError() && errorMessage(schemaError())) || form.description" ng-bind-html="(hasError() && errorMessage(schemaError())) || form.description"></div></div>'),e.put("directives/decorators/bootstrap/checkbox.html",'<div class="checkbox schema-form-checkbox {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><label><input type="checkbox" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" class="{{form.fieldHtmlClass}}" name="{{form.key.slice(-1)[0]}}"> <span ng-bind-html="form.title"></span></label><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/checkboxes.html",'<div sf-array="form" ng-model="$$value$$" class="form-group schema-form-checkboxes {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><label class="control-label" ng-show="showTitle()">{{form.title}}</label><div class="checkbox" ng-repeat="val in titleMapValues track by $index"><label><input type="checkbox" ng-disabled="form.readonly" sf-changed="form" class="{{form.fieldHtmlClass}}" ng-model="titleMapValues[$index]" schema-vaidate="form" name="{{form.key.slice(-1)[0]}}"> <span ng-bind-html="form.titleMap[$index].name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/default.html",'<div class="form-group schema-form-{{form.type}} {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess(), \'has-feedback\': form.feedback !== false }"><label class="control-label" ng-class="{\'sr-only\': !showTitle()}" for="{{form.key.slice(-1)[0]}}">{{form.title}}</label> <input ng-if="!form.fieldAddonLeft && !form.fieldAddonRight" ng-show="form.key" type="{{form.type}}" step="any" sf-changed="form" placeholder="{{form.placeholder}}" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" ng-model-options="form.ngModelOptions" ng-model="$$value$$" ng-disabled="form.readonly" schema-validate="form" name="{{form.key.slice(-1)[0]}}" aria-describedby="{{form.key.slice(-1)[0] + \'Status\'}}"><div ng-if="form.fieldAddonLeft || form.fieldAddonRight" ng-class="{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}"><span ng-if="form.fieldAddonLeft" class="input-group-addon" ng-bind-html="form.fieldAddonLeft"></span> <input ng-show="form.key" type="{{form.type}}" step="any" sf-changed="form" placeholder="{{form.placeholder}}" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" ng-model-options="form.ngModelOptions" ng-model="$$value$$" ng-disabled="form.readonly" schema-validate="form" name="{{form.key.slice(-1)[0]}}" aria-describedby="{{form.key.slice(-1)[0] + \'Status\'}}"> <span ng-if="form.fieldAddonRight" class="input-group-addon" ng-bind-html="form.fieldAddonRight"></span></div><span ng-if="form.feedback !== false" class="form-control-feedback" ng-class="evalInScope(form.feedback) || {\'glyphicon\': true, \'glyphicon-ok\': hasSuccess(), \'glyphicon-remove\': hasError() }" aria-hidden="true"></span> <span ng-if="hasError() || hasSuccess()" id="{{form.key.slice(-1)[0] + \'Status\'}}" class="sr-only">{{ hasSuccess() ? \'(success)\' : \'(error)\' }}</span><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/fieldset-trcl.html",'<fieldset ng-disabled="form.readonly" class="schema-form-fieldset {{form.htmlClass}}"><legend ng-show="form.title">{{ form.title }}</legend><div class="help-block" ng-show="form.description" ng-bind-html="form.description"></div><div ng-transclude=""></div></fieldset>'),e.put("directives/decorators/bootstrap/fieldset.html",'<fieldset ng-disabled="form.readonly" class="schema-form-fieldset {{form.htmlClass}}"><legend ng-show="form.title">{{ form.title }}</legend><div class="help-block" ng-show="form.description" ng-bind-html="form.description"></div><sf-decorator ng-repeat="item in form.items" form="item"></sf-decorator></fieldset>'),e.put("directives/decorators/bootstrap/help.html",'<div class="helpvalue schema-form-helpvalue {{form.htmlClass}}" ng-bind-html="form.helpvalue"></div>'),e.put("directives/decorators/bootstrap/radio-buttons.html",'<div class="form-group schema-form-radiobuttons {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><div><label class="control-label" ng-show="showTitle()">{{form.title}}</label></div><div class="btn-group"><label class="btn {{ (item.value === $$value$$) ? form.style.selected || \'btn-default\' : form.style.unselected || \'btn-default\'; }}" ng-class="{ active: item.value === $$value$$ }" ng-repeat="item in form.titleMap"><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" style="display: none;" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/radios-inline.html",'<div class="form-group schema-form-radios-inline {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><label class="control-label" ng-show="showTitle()">{{form.title}}</label><div><label class="radio-inline" ng-repeat="item in form.titleMap"><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/radios.html",'<div class="form-group schema-form-radios {{form.htmlClass}}" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><label class="control-label" ng-show="showTitle()">{{form.title}}</label><div class="radio" ng-repeat="item in form.titleMap"><label><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/section.html",'<div class="schema-form-section {{form.htmlClass}}"><sf-decorator ng-repeat="item in form.items" form="item"></sf-decorator></div>'),e.put("directives/decorators/bootstrap/select.html",'<div class="form-group {{form.htmlClass}} schema-form-select" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess(), \'has-feedback\': form.feedback !== false}"><label class="control-label" ng-show="showTitle()">{{form.title}}</label><select ng-model="$$value$$" ng-model-options="form.ngModelOptions" ng-disabled="form.readonly" sf-changed="form" class="form-control {{form.fieldHtmlClass}}" schema-validate="form" ng-options="item.value as item.name group by item.group for item in form.titleMap" name="{{form.key.slice(-1)[0]}}"></select><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/submit.html",'<div class="form-group schema-form-submit {{form.htmlClass}}"><input type="submit" class="btn {{ form.style || \'btn-primary\' }} {{form.fieldHtmlClass}}" value="{{form.title}}" ng-disabled="form.readonly" ng-if="form.type === \'submit\'"> <button class="btn {{ form.style || \'btn-default\' }}" type="button" ng-click="buttonClick($event,form)" ng-disabled="form.readonly" ng-if="form.type !== \'submit\'"><span ng-if="form.icon" class="{{form.icon}}"></span> {{form.title}}</button></div>'),e.put("directives/decorators/bootstrap/tabarray.html",'<div sf-array="form" ng-init="selected = { tab: 0 }" class="clearfix schema-form-tabarray schema-form-tabarray-{{form.tabType || \'left\'}} {{form.htmlClass}}"><div ng-if="!form.tabType || form.tabType !== \'right\'" ng-class="{\'col-xs-3\': !form.tabType || form.tabType === \'left\'}"><ul class="nav nav-tabs" ng-class="{ \'tabs-left\': !form.tabType || form.tabType === \'left\'}"><li ng-repeat="item in modelArray track by $index" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide="form.readonly" ng-click="$event.preventDefault() || (selected.tab = appendToArray().length - 1)"><a href="#"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</a></li></ul></div><div ng-class="{\'col-xs-9\': !form.tabType || form.tabType === \'left\' || form.tabType === \'right\'}"><div class="tab-content {{form.fieldHtmlClass}}"><div class="tab-pane clearfix" ng-repeat="item in modelArray track by $index" ng-show="selected.tab === $index" ng-class="{active: selected.tab === $index}"><sf-decorator ng-init="arrayIndex = $index" form="copyWithIndex($index)"></sf-decorator><button ng-hide="form.readonly" ng-click="selected.tab = deleteFromArray($index).length - 1" type="button" class="btn {{ form.style.remove || \'btn-default\' }} pull-right"><i class="glyphicon glyphicon-trash"></i> {{ form.remove || \'Remove\'}}</button></div></div></div><div ng-if="form.tabType === \'right\'" class="col-xs-3"><ul class="nav nav-tabs tabs-right"><li ng-repeat="item in modelArray track by $index" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide="form.readonly" ng-click="$event.preventDefault() || appendToArray()"><a href="#"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</a></li></ul></div></div>'),e.put("directives/decorators/bootstrap/tabs.html",'<div ng-init="selected = { tab: 0 }" class="schema-form-tabs {{form.htmlClass}}"><ul class="nav nav-tabs"><li ng-repeat="tab in form.tabs" ng-disabled="form.readonly" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{ tab.title }}</a></li></ul><div class="tab-content {{form.fieldHtmlClass}}"><div class="tab-pane" ng-disabled="form.readonly" ng-repeat="tab in form.tabs" ng-show="selected.tab === $index" ng-class="{active: selected.tab === $index}"><bootstrap-decorator ng-repeat="item in tab.items" form="item"></bootstrap-decorator></div></div></div>'),e.put("directives/decorators/bootstrap/textarea.html",'<div class="form-group has-feedback {{form.htmlClass}} schema-form-textarea" ng-class="{\'has-error\': hasError(), \'has-success\': hasSuccess()}"><label ng-class="{\'sr-only\': !showTitle()}" for="{{form.key.slice(-1)[0]}}">{{form.title}}</label> <textarea ng-if="!form.fieldAddonLeft && !form.fieldAddonRight" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" sf-changed="form" placeholder="{{form.placeholder}}" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" name="{{form.key.slice(-1)[0]}}"></textarea><div ng-if="form.fieldAddonLeft || form.fieldAddonRight" ng-class="{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}"><span ng-if="form.fieldAddonLeft" class="input-group-addon" ng-bind-html="form.fieldAddonLeft"></span> <textarea class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" sf-changed="form" placeholder="{{form.placeholder}}" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" name="{{form.key.slice(-1)[0]}}"></textarea> <span ng-if="form.fieldAddonRight" class="input-group-addon" ng-bind-html="form.fieldAddonRight"></span></div><span class="help-block" sf-message="form.description"></span></div>')}]),angular.module("schemaForm").config(["schemaFormDecoratorsProvider",function(e){var s="directives/decorators/bootstrap/";e.createDecorator("bootstrapDecorator",{textarea:s+"textarea.html",fieldset:s+"fieldset.html",array:s+"array.html",tabarray:s+"tabarray.html",tabs:s+"tabs.html",section:s+"section.html",conditional:s+"section.html",actions:s+"actions.html",select:s+"select.html",checkbox:s+"checkbox.html",checkboxes:s+"checkboxes.html",number:s+"default.html",password:s+"default.html",submit:s+"submit.html",button:s+"submit.html",radios:s+"radios.html","radios-inline":s+"radios-inline.html",radiobuttons:s+"radio-buttons.html",help:s+"help.html","default":s+"default.html"},[]),e.createDirectives({textarea:s+"textarea.html",select:s+"select.html",checkbox:s+"checkbox.html",checkboxes:s+"checkboxes.html",number:s+"default.html",submit:s+"submit.html",button:s+"submit.html",text:s+"default.html",date:s+"default.html",password:s+"default.html",datepicker:s+"datepicker.html",input:s+"default.html",radios:s+"radios.html","radios-inline":s+"radios-inline.html",radiobuttons:s+"radio-buttons.html"})}]).directive("sfFieldset",function(){return{transclude:!0,scope:!0,templateUrl:"directives/decorators/bootstrap/fieldset-trcl.html",link:function(e,s,t){e.title=e.$eval(t.title)}}});
angular.module("schemaForm").run(["$templateCache",function(e){e.put("directives/decorators/bootstrap/actions-trcl.html",'<div class="btn-group schema-form-actions {{form.htmlClass}}" ng-transclude=""></div>'),e.put("directives/decorators/bootstrap/actions.html",'<div class="btn-group schema-form-actions {{form.htmlClass}}"><input ng-repeat-start="item in form.items" type="submit" class="btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}" value="{{item.title}}" ng-if="item.type === \'submit\'"> <button ng-repeat-end="" class="btn {{ item.style || \'btn-default\' }} {{form.fieldHtmlClass}}" type="button" ng-disabled="form.readonly" ng-if="item.type !== \'submit\'" ng-click="buttonClick($event,item)"><span ng-if="item.icon" class="{{item.icon}}"></span>{{item.title}}</button></div>'),e.put("directives/decorators/bootstrap/array.html",'<div sf-array="form" class="schema-form-array {{form.htmlClass}}" ng-model="$$value$$" ng-model-options="form.ngModelOptions"><h3 ng-show="form.title && form.notitle !== true">{{ form.title }}</h3><ol class="list-group" ng-model="modelArray" ui-sortable=""><li class="list-group-item {{form.fieldHtmlClass}}" ng-repeat="item in modelArray track by $index"><button ng-hide="form.readonly || form.remove === null" ng-click="deleteFromArray($index)" style="position: relative; z-index: 20;" type="button" class="close pull-right"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button><sf-decorator ng-init="arrayIndex = $index" form="copyWithIndex($index)"></sf-decorator></li></ol><div class="clearfix" style="padding: 15px;"><button ng-hide="form.readonly || form.add === null" ng-click="appendToArray()" type="button" class="btn {{ form.style.add || \'btn-default\' }} pull-right"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</button></div><div class="help-block" ng-show="(hasError() && errorMessage(schemaError())) || form.description" ng-bind-html="(hasError() && errorMessage(schemaError())) || form.description"></div></div>'),e.put("directives/decorators/bootstrap/checkbox.html",'<div class="checkbox schema-form-checkbox {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><label class="{{form.labelHtmlClass}}"><input type="checkbox" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" class="{{form.fieldHtmlClass}}" name="{{form.key.slice(-1)[0]}}"> <span ng-bind-html="form.title"></span></label><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/checkboxes.html",'<div sf-array="form" ng-model="$$value$$" class="form-group schema-form-checkboxes {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><label class="control-label {{form.labelHtmlClass}}" ng-show="showTitle()">{{form.title}}</label><div class="checkbox" ng-repeat="val in titleMapValues track by $index"><label><input type="checkbox" ng-disabled="form.readonly" sf-changed="form" class="{{form.fieldHtmlClass}}" ng-model="titleMapValues[$index]" schema-vaidate="form" name="{{form.key.slice(-1)[0]}}"> <span ng-bind-html="form.titleMap[$index].name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/default.html",'<div class="form-group schema-form-{{form.type}} {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess(), \'has-feedback\': form.feedback !== false }"><label class="control-label {{form.labelHtmlClass}}" ng-class="{\'sr-only\': !showTitle()}" for="{{form.key.slice(-1)[0]}}">{{form.title}}</label> <input ng-if="!form.fieldAddonLeft && !form.fieldAddonRight" ng-show="form.key" type="{{form.type}}" step="any" sf-changed="form" placeholder="{{form.placeholder}}" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" ng-model-options="form.ngModelOptions" ng-model="$$value$$" ng-disabled="form.readonly" schema-validate="form" name="{{form.key.slice(-1)[0]}}" aria-describedby="{{form.key.slice(-1)[0] + \'Status\'}}"><div ng-if="form.fieldAddonLeft || form.fieldAddonRight" ng-class="{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}"><span ng-if="form.fieldAddonLeft" class="input-group-addon" ng-bind-html="form.fieldAddonLeft"></span> <input ng-show="form.key" type="{{form.type}}" step="any" sf-changed="form" placeholder="{{form.placeholder}}" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" ng-model-options="form.ngModelOptions" ng-model="$$value$$" ng-disabled="form.readonly" schema-validate="form" name="{{form.key.slice(-1)[0]}}" aria-describedby="{{form.key.slice(-1)[0] + \'Status\'}}"> <span ng-if="form.fieldAddonRight" class="input-group-addon" ng-bind-html="form.fieldAddonRight"></span></div><span ng-if="form.feedback !== false" class="form-control-feedback" ng-class="evalInScope(form.feedback) || {\'glyphicon\': true, \'glyphicon-ok\': hasSuccess(), \'glyphicon-remove\': hasError() }" aria-hidden="true"></span> <span ng-if="hasError() || hasSuccess()" id="{{form.key.slice(-1)[0] + \'Status\'}}" class="sr-only">{{ hasSuccess() ? \'(success)\' : \'(error)\' }}</span><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/fieldset-trcl.html",'<fieldset ng-disabled="form.readonly" class="schema-form-fieldset {{form.htmlClass}}"><legend ng-show="form.title">{{ form.title }}</legend><div class="help-block" ng-show="form.description" ng-bind-html="form.description"></div><div ng-transclude=""></div></fieldset>'),e.put("directives/decorators/bootstrap/fieldset.html",'<fieldset ng-disabled="form.readonly" class="schema-form-fieldset {{form.htmlClass}}"><legend ng-show="form.title">{{ form.title }}</legend><div class="help-block" ng-show="form.description" ng-bind-html="form.description"></div><sf-decorator ng-repeat="item in form.items" form="item"></sf-decorator></fieldset>'),e.put("directives/decorators/bootstrap/help.html",'<div class="helpvalue schema-form-helpvalue {{form.htmlClass}}" ng-bind-html="form.helpvalue"></div>'),e.put("directives/decorators/bootstrap/radio-buttons.html",'<div class="form-group schema-form-radiobuttons {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><div><label class="control-label {{form.labelHtmlClass}}" ng-show="showTitle()">{{form.title}}</label></div><div class="btn-group"><label class="btn {{ (item.value === $$value$$) ? form.style.selected || \'btn-default\' : form.style.unselected || \'btn-default\'; }}" ng-class="{ active: item.value === $$value$$ }" ng-repeat="item in form.titleMap"><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" style="display: none;" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/radios-inline.html",'<div class="form-group schema-form-radios-inline {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><label class="control-label {{form.labelHtmlClass}}" ng-show="showTitle()">{{form.title}}</label><div><label class="radio-inline" ng-repeat="item in form.titleMap"><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/radios.html",'<div class="form-group schema-form-radios {{form.htmlClass}}" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><label class="control-label {{form.labelHtmlClass}}" ng-show="showTitle()">{{form.title}}</label><div class="radio" ng-repeat="item in form.titleMap"><label><input type="radio" class="{{form.fieldHtmlClass}}" sf-changed="form" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" ng-value="item.value" name="{{form.key.join(\'.\')}}"> <span ng-bind-html="item.name"></span></label></div><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/section.html",'<div class="schema-form-section {{form.htmlClass}}"><sf-decorator ng-repeat="item in form.items" form="item"></sf-decorator></div>'),e.put("directives/decorators/bootstrap/select.html",'<div class="form-group {{form.htmlClass}} schema-form-select" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess(), \'has-feedback\': form.feedback !== false}"><label class="control-label {{form.labelHtmlClass}}" ng-show="showTitle()">{{form.title}}</label><select ng-model="$$value$$" ng-model-options="form.ngModelOptions" ng-disabled="form.readonly" sf-changed="form" class="form-control {{form.fieldHtmlClass}}" schema-validate="form" ng-options="item.value as item.name group by item.group for item in form.titleMap" name="{{form.key.slice(-1)[0]}}"></select><div class="help-block" sf-message="form.description"></div></div>'),e.put("directives/decorators/bootstrap/submit.html",'<div class="form-group schema-form-submit {{form.htmlClass}}"><input type="submit" class="btn {{ form.style || \'btn-primary\' }} {{form.fieldHtmlClass}}" value="{{form.title}}" ng-disabled="form.readonly" ng-if="form.type === \'submit\'"> <button class="btn {{ form.style || \'btn-default\' }}" type="button" ng-click="buttonClick($event,form)" ng-disabled="form.readonly" ng-if="form.type !== \'submit\'"><span ng-if="form.icon" class="{{form.icon}}"></span> {{form.title}}</button></div>'),e.put("directives/decorators/bootstrap/tabarray.html",'<div sf-array="form" ng-init="selected = { tab: 0 }" class="clearfix schema-form-tabarray schema-form-tabarray-{{form.tabType || \'left\'}} {{form.htmlClass}}"><div ng-if="!form.tabType || form.tabType !== \'right\'" ng-class="{\'col-xs-3\': !form.tabType || form.tabType === \'left\'}"><ul class="nav nav-tabs" ng-class="{ \'tabs-left\': !form.tabType || form.tabType === \'left\'}"><li ng-repeat="item in modelArray track by $index" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide="form.readonly" ng-click="$event.preventDefault() || (selected.tab = appendToArray().length - 1)"><a href="#"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</a></li></ul></div><div ng-class="{\'col-xs-9\': !form.tabType || form.tabType === \'left\' || form.tabType === \'right\'}"><div class="tab-content {{form.fieldHtmlClass}}"><div class="tab-pane clearfix" ng-repeat="item in modelArray track by $index" ng-show="selected.tab === $index" ng-class="{active: selected.tab === $index}"><sf-decorator ng-init="arrayIndex = $index" form="copyWithIndex($index)"></sf-decorator><button ng-hide="form.readonly" ng-click="selected.tab = deleteFromArray($index).length - 1" type="button" class="btn {{ form.style.remove || \'btn-default\' }} pull-right"><i class="glyphicon glyphicon-trash"></i> {{ form.remove || \'Remove\'}}</button></div></div></div><div ng-if="form.tabType === \'right\'" class="col-xs-3"><ul class="nav nav-tabs tabs-right"><li ng-repeat="item in modelArray track by $index" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{interp(form.title,{\'$index\':$index, value: item}) || $index}}</a></li><li ng-hide="form.readonly" ng-click="$event.preventDefault() || appendToArray()"><a href="#"><i class="glyphicon glyphicon-plus"></i> {{ form.add || \'Add\'}}</a></li></ul></div></div>'),e.put("directives/decorators/bootstrap/tabs.html",'<div ng-init="selected = { tab: 0 }" class="schema-form-tabs {{form.htmlClass}}"><ul class="nav nav-tabs"><li ng-repeat="tab in form.tabs" ng-disabled="form.readonly" ng-click="$event.preventDefault() || (selected.tab = $index)" ng-class="{active: selected.tab === $index}"><a href="#">{{ tab.title }}</a></li></ul><div class="tab-content {{form.fieldHtmlClass}}"><div class="tab-pane" ng-disabled="form.readonly" ng-repeat="tab in form.tabs" ng-show="selected.tab === $index" ng-class="{active: selected.tab === $index}"><bootstrap-decorator ng-repeat="item in tab.items" form="item"></bootstrap-decorator></div></div></div>'),e.put("directives/decorators/bootstrap/textarea.html",'<div class="form-group has-feedback {{form.htmlClass}} schema-form-textarea" ng-class="{\'has-error\': form.disableErrorState !== true && hasError(), \'has-success\': form.disableSuccessState !== true && hasSuccess()}"><label class="{{form.labelHtmlClass}}" ng-class="{\'sr-only\': !showTitle()}" for="{{form.key.slice(-1)[0]}}">{{form.title}}</label> <textarea ng-if="!form.fieldAddonLeft && !form.fieldAddonRight" class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" sf-changed="form" placeholder="{{form.placeholder}}" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" name="{{form.key.slice(-1)[0]}}"></textarea><div ng-if="form.fieldAddonLeft || form.fieldAddonRight" ng-class="{\'input-group\': (form.fieldAddonLeft || form.fieldAddonRight)}"><span ng-if="form.fieldAddonLeft" class="input-group-addon" ng-bind-html="form.fieldAddonLeft"></span> <textarea class="form-control {{form.fieldHtmlClass}}" id="{{form.key.slice(-1)[0]}}" sf-changed="form" placeholder="{{form.placeholder}}" ng-disabled="form.readonly" ng-model="$$value$$" ng-model-options="form.ngModelOptions" schema-validate="form" name="{{form.key.slice(-1)[0]}}"></textarea> <span ng-if="form.fieldAddonRight" class="input-group-addon" ng-bind-html="form.fieldAddonRight"></span></div><span class="help-block" sf-message="form.description"></span></div>')}]),angular.module("schemaForm").config(["schemaFormDecoratorsProvider",function(e){var t="directives/decorators/bootstrap/";e.createDecorator("bootstrapDecorator",{textarea:t+"textarea.html",fieldset:t+"fieldset.html",array:t+"array.html",tabarray:t+"tabarray.html",tabs:t+"tabs.html",section:t+"section.html",conditional:t+"section.html",actions:t+"actions.html",select:t+"select.html",checkbox:t+"checkbox.html",checkboxes:t+"checkboxes.html",number:t+"default.html",password:t+"default.html",submit:t+"submit.html",button:t+"submit.html",radios:t+"radios.html","radios-inline":t+"radios-inline.html",radiobuttons:t+"radio-buttons.html",help:t+"help.html","default":t+"default.html"},[]),e.createDirectives({textarea:t+"textarea.html",select:t+"select.html",checkbox:t+"checkbox.html",checkboxes:t+"checkboxes.html",number:t+"default.html",submit:t+"submit.html",button:t+"submit.html",text:t+"default.html",date:t+"default.html",password:t+"default.html",datepicker:t+"datepicker.html",input:t+"default.html",radios:t+"radios.html","radios-inline":t+"radios-inline.html",radiobuttons:t+"radio-buttons.html"})}]).directive("sfFieldset",function(){return{transclude:!0,scope:!0,templateUrl:"directives/decorators/bootstrap/fieldset-trcl.html",link:function(e,t,s){e.title=e.$eval(s.title)}}});

@@ -0,1 +1,10 @@

(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['angular', 'ObjectPath', 'tv4'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('angular'), require('ObjectPath'), require('tv4'));
} else {
root.schemaForm = factory(root.angular, root.ObjectPath, root.tv4);
}
}(this, function(angular, ObjectPath, tv4) {
// Deps is sort of a problem for us, maybe in the future we will ask the user to depend

@@ -23,3 +32,3 @@ // on modules for add-ons

angular.module('schemaForm', deps);
var schemaForm = angular.module('schemaForm', deps);

@@ -163,4 +172,4 @@ angular.module('schemaForm').provider('sfPath',

$compileProvider.directive(name,
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage',
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage) {
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage', 'sfPath',
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage, sfPath) {

@@ -292,2 +301,3 @@ return {

(scope.ngModel && scope.ngModel.$modelValue) || '',
(scope.ngModel && scope.ngModel.$viewValue) || '',
scope.form,

@@ -337,2 +347,8 @@ scope.options && scope.options.validationMessage

if (form.condition) {
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
if (form.key) {
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
}
angular.forEach(element.children(), function(child) {

@@ -344,8 +360,7 @@ var ngIf = child.getAttribute('ng-if');

'(' + ngIf +
') || (evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex }))'
: 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex })'
') || (' + evalExpr +')'
: evalExpr
);
});
}
$compile(element.contents())(scope);

@@ -380,3 +395,2 @@ });

}
console.log('settings validationMessage', validationMessage)
form.validationMessage[error] = validationMessage;

@@ -387,5 +401,7 @@ }

// Setting or removing a validity can change the field to believe its valid
// but its not. So lets trigger its validation as well.
scope.$broadcast('schemaFormValidate');
if (validity === true) {
// Setting or removing a validity can change the field to believe its valid
// but its not. So lets trigger its validation as well.
scope.$broadcast('schemaFormValidate');
}
}

@@ -558,3 +574,3 @@ })

'default': 'Field does not validate',
0: 'Invalid type, expected {{schema.type}})',
0: 'Invalid type, expected {{schema.type}}',
1: 'No enum match for: {{value}}',

@@ -566,15 +582,15 @@ 10: 'Data does not match any schemas from "anyOf"',

// Numeric errors
100: 'Value {{value}} is not a multiple of {{schema.multipleOf}}',
101: 'Value {{value}} is less than minimum {{schema.minimum}}',
102: 'Value {{value}} is equal to exclusive minimum {{schema.minimum}}',
103: 'Value {{value}} is greater than maximum {{schema.maximum}}',
104: 'Value {{value}} is equal to exclusive maximum {{schema.maximum}}',
105: 'Value {{value}} is not a valid number',
100: 'Value is not a multiple of {{schema.divisibleBy}}',
101: '{{viewValue}} is less than the allowed minimum of {{schema.minimum}}',
102: '{{viewValue}} is equal to the exclusive minimum {{schema.minimum}}',
103: '{{viewValue}} is greater than the allowed maximum of {{schema.maximum}}',
104: '{{viewValue}} is equal to the exclusive maximum {{schema.maximum}}',
105: 'Value is not a valid number',
// String errors
200: 'String is too short ({{value.length}} chars), minimum {{schema.minimum}}',
201: 'String is too long ({{value.length}} chars), maximum {{schema.maximum}}',
200: 'String is too short ({{viewValue.length}} chars), minimum {{schema.minLength}}',
201: 'String is too long ({{viewValue.length}} chars), maximum {{schema.maxLength}}',
202: 'String does not match pattern: {{schema.pattern}}',
// Object errors
300: 'Too few properties defined, minimum {{schema.minimum}}',
301: 'Too many properties defined, maximum {{schema.maximum}}',
300: 'Too few properties defined, minimum {{schema.minProperties}}',
301: 'Too many properties defined, maximum {{schema.maxProperties}}',
302: 'Required',

@@ -584,4 +600,4 @@ 303: 'Additional properties not allowed',

// Array errors
400: 'Array is too short ({{value.length}}), minimum {{schema.minimum}}',
401: 'Array is too long ({{value.length}}), maximum {{schema.maximum}}',
400: 'Array is too short ({{value.length}}), minimum {{schema.maxItems}}',
401: 'Array is too long ({{value.length}}), maximum {{schema.minItems}}',
402: 'Array items are not unique',

@@ -598,2 +614,11 @@ 403: 'Additional items not allowed',

// In some cases we get hit with an angular validation error
defaultMessages.number = defaultMessages[105];
defaultMessages.required = defaultMessages[302];
defaultMessages.min = defaultMessages[101];
defaultMessages.max = defaultMessages[103];
defaultMessages.maxlength = defaultMessages[201];
defaultMessages.minlength = defaultMessages[200];
defaultMessages.pattern = defaultMessages[202];
this.setDefaultMessages = function(messages) {

@@ -623,2 +648,3 @@ defaultMessages = messages;

* @param {Any} value the actual model value.
* @param {Any} viewValue the viewValue
* @param {Object} form a form definition object for this field

@@ -629,3 +655,3 @@ * @param {Object} global the global validation messages object (even though its called global

*/
service.interpolate = function(error, value, form, global) {
service.interpolate = function(error, value, viewValue, form, global) {
global = global || {};

@@ -656,2 +682,3 @@ var validationMessage = form.validationMessage || {};

value: value,
viewValue: viewValue,
form: form,

@@ -1512,3 +1539,3 @@ schema: form.schema,

var update = function(valid) {
if (valid && scope.hasError()) {
if (valid && !scope.hasError()) {
element.html(msg);

@@ -1523,16 +1550,4 @@ } else {

// TODO: Make that optional
// tv4- errors take precedence
var error = errors[0];
if (errors.length > 1) {
error = errors.reduce(function(prev, value) {
if (prev && prev.indexOf('tv4-') === 0) {
return prev;
}
return value;
});
console.log('reduced',errors, error)
}
if (error) {

@@ -1542,2 +1557,3 @@ element.html(sfErrorMessage.interpolate(

scope.ngModel.$modelValue,
scope.ngModel.$viewValue,
scope.form,

@@ -1772,2 +1788,7 @@ scope.options && scope.options.validationMessage

// Omit TV4 validation
if (scope.options && scope.options.tv4Validation === false) {
return viewValue;
}
var result = sfValidator.validate(form, viewValue);

@@ -1835,1 +1856,4 @@ // Since we might have different tv4 errors we must clear all

}]);
return schemaForm;
}));

@@ -1,1 +0,1 @@

var deps=[];try{angular.module("ngSanitize"),deps.push("ngSanitize")}catch(e){}try{angular.module("ui.sortable"),deps.push("ui.sortable")}catch(e){}try{angular.module("angularSpectrumColorpicker"),deps.push("angularSpectrumColorpicker")}catch(e){}angular.module("schemaForm",deps),angular.module("schemaForm").provider("sfPath",[function(){var e={parse:ObjectPath.parse};e.stringify=1===angular.version.major&&angular.version.minor<3?function(e){return Array.isArray(e)?e.join("."):e.toString()}:ObjectPath.stringify,e.normalize=function(r,t){return e.stringify(Array.isArray(r)?r:e.parse(r),t)},this.parse=e.parse,this.stringify=e.stringify,this.normalize=e.normalize,this.$get=function(){return e}}]),angular.module("schemaForm").factory("sfSelect",["sfPath",function(e){var r=/^\d+$/;return function(t,n,a){n||(n=this);var i="string"==typeof t?e.parse(t):t;if("undefined"!=typeof a&&1===i.length)return n[i[0]]=a,n;"undefined"!=typeof a&&"undefined"==typeof n[i[0]]&&(n[i[0]]=i.length>2&&r.test(i[1])?[]:{});for(var o=n[i[0]],l=1;l<i.length;l++){if(""===i[l])return void 0;if("undefined"!=typeof a){if(l===i.length-1)return o[i[l]]=a,a;var u=o[i[l]];("undefined"==typeof u||null===u)&&(u=r.test(i[l+1])?[]:{},o[i[l]]=u),o=u}else o&&(o=o[i[l]])}return o}}]),angular.module("schemaForm").provider("schemaFormDecorators",["$compileProvider","sfPathProvider",function(e,r){var t="",n={},a=function(e,r){"sfDecorator"===e&&(e=t);for(var a=n[e],i=a.rules,o=0;o<i.length;o++){var l=i[o](r);if(l)return l}return a.mappings[r.type]?a.mappings[r.type]:a.mappings["default"]},i=function(t){e.directive(t,["$parse","$compile","$http","$templateCache","$interpolate","$q","sfErrorMessage",function(e,n,i,o,l,u,s){return{restrict:"AE",replace:!1,transclude:!1,scope:!0,require:"?^sfSchema",link:function(e,c,f,m){e.$on("schemaFormPropagateNgModelController",function(r,t){r.stopPropagation(),r.preventDefault(),e.ngModel=t}),e.showTitle=function(){return e.form&&e.form.notitle!==!0&&e.form.title},e.listToCheckboxValues=function(e){var r={};return angular.forEach(e,function(e){r[e]=!0}),r},e.checkboxValuesToList=function(e){var r=[];return angular.forEach(e,function(e,t){e&&r.push(t)}),r},e.buttonClick=function(r,t){angular.isFunction(t.onClick)?t.onClick(r,t):angular.isString(t.onClick)&&(m?m.evalInParentScope(t.onClick,{$event:r,form:t}):e.$eval(t.onClick,{$event:r,form:t}))},e.evalExpr=function(r,t){return m?m.evalInParentScope(r,t):e.$eval(r,t)},e.evalInScope=function(r,t){return r?e.$eval(r,t):void 0},e.interp=function(e,r){return e&&l(e)(r)},e.hasSuccess=function(){return e.ngModel?e.ngModel.$valid&&(!e.ngModel.$pristine||!e.ngModel.$isEmpty(e.ngModel.$modelValue)):!1},e.hasError=function(){return e.ngModel?e.ngModel.$invalid&&!e.ngModel.$pristine:!1},e.errorMessage=function(r){return s.interpolate(r&&r.code+""||"default",e.ngModel&&e.ngModel.$modelValue||"",e.form,e.options&&e.options.validationMessage)};var d=e.$watch(f.form,function(l){if(l){l.ngModelOptions=l.ngModelOptions||{},e.form=l;var s;if("template"===l.type&&l.template)s=u.when(l.template);else{var f="template"===l.type?l.templateUrl:a(t,l);s=i.get(f,{cache:o}).then(function(e){return e.data})}s.then(function(t){if(l.key){var a=l.key?r.stringify(l.key).replace(/"/g,"&quot;"):"";t=t.replace(/\$\$value\$\$/g,"model"+("["!==a[0]?".":"")+a)}c.html(t),l.condition&&angular.forEach(c.children(),function(e){var r=e.getAttribute("ng-if");e.setAttribute("ng-if",r?"("+r+') || (evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex }))':'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex })')}),n(c.contents())(e)}),l.key&&e.$on("schemaForm.error."+l.key.join("."),function(r,t,n,a){(n===!0||n===!1)&&(a=n,n=void 0),e.ngModel&&t&&(e.ngModel.$setDirty()?e.ngModel.$setDirty():(e.ngModel.$dirty=!0,e.ngModel.$pristine=!1),n&&(l.validationMessage||(l.validationMessage={}),console.log("settings validationMessage",n),l.validationMessage[t]=n),e.ngModel.$setValidity(t,a===!0),e.$broadcast("schemaFormValidate"))}),d()}})}}}])},o=function(r,t,n){n=angular.isDefined(n)?n:!1,e.directive("sf"+angular.uppercase(r[0])+r.substr(1),function(){return{restrict:"EAC",scope:!0,replace:!0,transclude:n,template:'<sf-decorator form="form"></sf-decorator>',link:function(e,t,n){var a={items:"c",titleMap:"c",schema:"c"},i={type:r},o=!0;angular.forEach(n,function(r,t){if("$"!==t[0]&&0!==t.indexOf("ng")&&"sfField"!==t){var l=function(r){angular.isDefined(r)&&r!==i[t]&&(i[t]=r,o&&i.type&&(i.key||angular.isUndefined(n.key))&&(e.form=i,o=!1))};"model"===t?e.$watch(r,function(r){r&&e.model!==r&&(e.model=r)}):"c"===a[t]?e.$watchCollection(r,l):n.$observe(t,l)}})}}})};this.createDecorator=function(e,r,a){n[e]={mappings:r||{},rules:a||[]},n[t]||(t=e),i(e)},this.createDirective=o,this.createDirectives=function(e){angular.forEach(e,function(e,r){o(r,e)})},this.directive=function(e){return e=e||t,n[e]},this.addMapping=function(e,r,t){n[e]&&(n[e].mappings[r]=t)},this.$get=function(){return{directive:function(e){return n[e]},defaultDecorator:t}},i("sfDecorator")}]),angular.module("schemaForm").provider("sfErrorMessage",function(){var e={"default":"Field does not validate",0:"Invalid type, expected {{schema.type}})",1:"No enum match for: {{value}}",10:'Data does not match any schemas from "anyOf"',11:'Data does not match any schemas from "oneOf"',12:'Data is valid against more than one schema from "oneOf"',13:'Data matches schema from "not"',100:"Value {{value}} is not a multiple of {{schema.multipleOf}}",101:"Value {{value}} is less than minimum {{schema.minimum}}",102:"Value {{value}} is equal to exclusive minimum {{schema.minimum}}",103:"Value {{value}} is greater than maximum {{schema.maximum}}",104:"Value {{value}} is equal to exclusive maximum {{schema.maximum}}",105:"Value {{value}} is not a valid number",200:"String is too short ({{value.length}} chars), minimum {{schema.minimum}}",201:"String is too long ({{value.length}} chars), maximum {{schema.maximum}}",202:"String does not match pattern: {{schema.pattern}}",300:"Too few properties defined, minimum {{schema.minimum}}",301:"Too many properties defined, maximum {{schema.maximum}}",302:"Required",303:"Additional properties not allowed",304:"Dependency failed - key must exist",400:"Array is too short ({{value.length}}), minimum {{schema.minimum}}",401:"Array is too long ({{value.length}}), maximum {{schema.maximum}}",402:"Array items are not unique",403:"Additional items not allowed",500:"Format validation failed",501:'Keyword failed: "{{title}}"',600:"Circular $refs",1e3:"Unknown property (not in schema)"};this.setDefaultMessages=function(r){e=r},this.getDefaultMessages=function(){return e},this.setDefaultMessage=function(r,t){e[r]=t},this.$get=["$interpolate",function(r){var t={};return t.defaultMessages=e,t.interpolate=function(t,n,a,i){i=i||{};var o=a.validationMessage||{};0===t.indexOf("tv4-")&&(t=t.substring(4));var l=o["default"]||i["default"]||"";[o,i,e].some(function(e){return angular.isString(e)||angular.isFunction(e)?(l=e,!0):e&&e[t]?(l=e[t],!0):void 0});var u={error:t,value:n,form:a,schema:a.schema,title:a.title||a.schema&&a.schema.title};return angular.isFunction(l)?l(u):r(l)(u)},t}]}),angular.module("schemaForm").provider("schemaForm",["sfPathProvider",function(e){var r=function(e){if(Array.isArray(e)&&2==e.length){if("null"===e[0])return e[1];if("null"===e[1])return e[0]}return e},t=function(e){var r=[];return e.forEach(function(e){r.push({name:e,value:e})}),r},n=function(e,r){if(!angular.isArray(e)){var t=[];return r?angular.forEach(r,function(r){t.push({name:e[r],value:r})}):angular.forEach(e,function(e,r){t.push({name:e,value:r})}),t}return e},a=function(e,t,n){var a=h[r(t.type)];if(a)for(var i,o=0;o<a.length;o++)if(i=a[o](e,t,n))return i.schema["x-schema-form"]&&angular.isObject(i.schema["x-schema-form"])&&(i=angular.extend(i,i.schema["x-schema-form"])),i},i=function(e,r,t){t=t||{};var a=t.global&&t.global.formDefaults?angular.copy(t.global.formDefaults):{};return a.title=t.global&&t.global.supressPropertyTitles===!0?r.title:r.title||e,r.description&&(a.description=r.description),(t.required===!0||r.required===!0)&&(a.required=!0),r.maxLength&&(a.maxlength=r.maxLength),r.minLength&&(a.minlength=r.maxLength),(r.readOnly||r.readonly)&&(a.readonly=!0),r.minimum&&(a.minimum=r.minimum+(r.exclusiveMinimum?1:0)),r.maximum&&(a.maximum=r.maximum-(r.exclusiveMaximum?1:0)),r.validationMessage&&(a.validationMessage=r.validationMessage),r.enumNames&&(a.titleMap=n(r.enumNames,r["enum"])),a.schema=r,a.ngModelOptions=a.ngModelOptions||{},a},o=function(t,n,a){if("string"===r(n.type)&&!n["enum"]){var o=i(t,n,a);return o.key=a.path,o.type="text",a.lookup[e.stringify(a.path)]=o,o}},l=function(t,n,a){if("number"===r(n.type)){var o=i(t,n,a);return o.key=a.path,o.type="number",a.lookup[e.stringify(a.path)]=o,o}},u=function(t,n,a){if("integer"===r(n.type)){var o=i(t,n,a);return o.key=a.path,o.type="number",a.lookup[e.stringify(a.path)]=o,o}},s=function(t,n,a){if("boolean"===r(n.type)){var o=i(t,n,a);return o.key=a.path,o.type="checkbox",a.lookup[e.stringify(a.path)]=o,o}},c=function(n,a,o){if("string"===r(a.type)&&a["enum"]){var l=i(n,a,o);return l.key=o.path,l.type="select",l.titleMap||(l.titleMap=t(a["enum"])),o.lookup[e.stringify(o.path)]=l,l}},f=function(n,a,o){if("array"===r(a.type)&&a.items&&a.items["enum"]){var l=i(n,a,o);return l.key=o.path,l.type="checkboxes",l.titleMap||(l.titleMap=t(a.items["enum"])),o.lookup[e.stringify(o.path)]=l,l}},m=function(t,n,o){if("object"===r(n.type)){var l=i(t,n,o);return l.type="fieldset",l.items=[],o.lookup[e.stringify(o.path)]=l,angular.forEach(n.properties,function(r,t){var i=o.path.slice();if(i.push(t),o.ignore[e.stringify(i)]!==!0){var u=n.required&&-1!==n.required.indexOf(t),s=a(t,r,{path:i,required:u||!1,lookup:o.lookup,ignore:o.ignore});s&&l.items.push(s)}}),l}},d=function(t,n,o){if("array"===r(n.type)){var l=i(t,n,o);l.type="array",l.key=o.path,o.lookup[e.stringify(o.path)]=l;var u=n.required&&-1!==n.required.indexOf(o.path[o.path.length-1]),s=o.path.slice();return s.push(""),l.items=[a(t,n.items,{path:s,required:u||!1,lookup:o.lookup,ignore:o.ignore,global:o.global})],l}},h={string:[c,o],object:[m],number:[l],integer:[u],"boolean":[s],array:[f,d]},p=function(e){return e};this.defaults=h,this.stdFormObj=i,this.defaultFormDefinition=a,this.postProcess=function(e){p=e},this.appendRule=function(e,r){h[e]||(h[e]=[]),h[e].push(r)},this.prependRule=function(e,r){h[e]||(h[e]=[]),h[e].unshift(r)},this.createStandardForm=i,this.$get=function(){var t={};return t.merge=function(r,a,i,o,l){a=a||["*"],o=o||{},l=l||r.readonly||r.readOnly;var u=t.defaults(r,i,o),s=a.indexOf("*");-1!==s&&(a=a.slice(0,s).concat(u.form).concat(a.slice(s+1)));var c=u.lookup;return p(a.map(function(a){if("string"==typeof a&&(a={key:a}),a.key&&"string"==typeof a.key&&(a.key=e.parse(a.key)),a.titleMap&&(a.titleMap=n(a.titleMap)),a.itemForm){a.items=[];var u=e.stringify(a.key),s=c[u];angular.forEach(s.items,function(e){var r=angular.copy(a.itemForm);r.key=e.key,a.items.push(r)})}if(a.key){var f=e.stringify(a.key);if(c[f]){var m=c[f];angular.forEach(m,function(e,r){void 0===a[r]&&(a[r]=m[r])})}}return l===!0&&(a.readonly=!0),a.items&&(a.items=t.merge(r,a.items,i,o,a.readonly)),a.tabs&&angular.forEach(a.tabs,function(e){e.items=t.merge(r,e.items,i,o,a.readonly)}),"checkbox"===a.type&&angular.isUndefined(a.schema["default"])&&(a.schema["default"]=!1),a}))},t.defaults=function(e,t,n){var i=[],o={};if(t=t||{},n=n||{},"object"!==r(e.type))throw new Error('Not implemented. Only type "object" allowed at root level of schema.');return angular.forEach(e.properties,function(r,l){if(t[l]!==!0){var u=e.required&&-1!==e.required.indexOf(l),s=a(l,r,{path:[l],lookup:o,ignore:t,required:u,global:n});s&&i.push(s)}}),{form:i,lookup:o}},t.traverseSchema=function(e,r,t,n){n=angular.isDefined(n)?n:!0,t=t||[];var a=function(e,r,t){if(r(e,t),angular.forEach(e.properties,function(e,n){var i=t.slice();i.push(n),a(e,r,i)}),!n&&e.items){var i=t.slice();i.push(""),a(e.items,r,i)}};a(e,r,t||[])},t.traverseForm=function(e,r){r(e),angular.forEach(e.items,function(e){t.traverseForm(e,r)}),e.tabs&&angular.forEach(e.tabs,function(e){angular.forEach(e.items,function(e){t.traverseForm(e,r)})})},t}}]),angular.module("schemaForm").factory("sfValidator",[function(){var e={};return e.validate=function(e,r){if(!e)return{valid:!0};var t=e.schema;if(!t)return{valid:!0};""===r&&(r=void 0),"number"===e.type&&null===r&&(r=void 0);var n={type:"object",properties:{}},a=e.key[e.key.length-1];n.properties[a]=t,e.required&&(n.required=[a]);var i={};return angular.isDefined(r)&&(i[a]=r),tv4.validateResult(i,n)},e}]),angular.module("schemaForm").directive("sfArray",["sfSelect","schemaForm","sfValidator","sfPath",function(e,r,t,n){var a=function(e){return function(r){r.key&&(r.key[r.key.indexOf("")]=e)}};return{restrict:"A",scope:!0,require:"?ngModel",link:function(i,o,l,u){var s={};u&&i.$emit("schemaFormPropagateNgModelController",u);var c=i.$watch(l.sfArray,function(o){var l=e(o.key,i.model);if(i.$watch("model"+n.normalize(o.key),function(){l=e(o.key,i.model),i.modelArray=l}),angular.isUndefined(l)&&(l=[],e(o.key,i.model,l)),i.modelArray=l,o.items){var f=o.items[0];o.items.length>1&&(f={type:"section",items:o.items.map(function(e){return e.ngModelOptions=o.ngModelOptions,angular.isUndefined(e.readonly)&&(e.readonly=o.readonly),e})})}if(i.copyWithIndex=function(e){if(!s[e]&&f){var t=angular.copy(f);t.arrayIndex=e,r.traverseForm(t,a(e)),s[e]=t}return s[e]},i.appendToArray=function(){var t=l.length,n=i.copyWithIndex(t);if(r.traverseForm(n,function(r){if(r.key){var t;angular.isDefined(r["default"])&&(t=r["default"]),angular.isDefined(r.schema)&&angular.isDefined(r.schema["default"])&&(t=r.schema["default"]),angular.isDefined(t)&&e(r.key,i.model,t)}}),t===l.length){var a,u=e("schema.items.type",o);"object"===u?a={}:"array"===u&&(a=[]),l.push(a)}return i.validateArray&&i.validateArray(),l},i.deleteFromArray=function(e){return l.splice(e,1),i.validateArray&&i.validateArray(),u&&u.$setDirty&&u.$setDirty(),l},o.titleMap||o.startEmpty===!0||0!==l.length||i.appendToArray(),o.titleMap&&o.titleMap.length>0){i.titleMapValues=[];var m=function(e){i.titleMapValues=[],e=e||[],o.titleMap.forEach(function(r){i.titleMapValues.push(-1!==e.indexOf(r.value))})};m(i.modelArray),i.$watchCollection("modelArray",m),i.$watchCollection("titleMapValues",function(e){if(e){for(var r=i.modelArray;r.length>0;)r.pop();o.titleMap.forEach(function(t,n){e[n]&&r.push(t.value)})}})}if(u){var d;i.validateArray=function(){var e=t.validate(o,i.modelArray.length>0?i.modelArray:void 0);Object.keys(u.$error).filter(function(e){return 0===e.indexOf("tv4-")}).forEach(function(e){u.$setValidity(e,!0)}),e.valid!==!1||!e.error||""!==e.error.dataPath&&e.error.dataPath!=="/"+o.key[o.key.length-1]||(u.$setViewValue(i.modelArray),d=e.error,u.$setValidity("tv4-"+e.error.code,!1))},i.$on("schemaFormValidate",i.validateArray),i.hasSuccess=function(){return u.$valid&&!u.$pristine},i.hasError=function(){return u.$invalid},i.schemaError=function(){return d}}c()})}}}]),angular.module("schemaForm").directive("sfChanged",function(){return{require:"ngModel",restrict:"AC",scope:!1,link:function(e,r,t,n){var a=e.$eval(t.sfChanged);a&&a.onChange&&n.$viewChangeListeners.push(function(){angular.isFunction(a.onChange)?a.onChange(n.$modelValue,a):e.evalExpr(a.onChange,{modelValue:n.$modelValue,form:a})})}}}),angular.module("schemaForm").directive("sfMessage",["$injector","sfErrorMessage",function(e,r){return{scope:!1,restrict:"EA",link:function(t,n,a){var i=e.has("$sanitize")?e.get("$sanitize"):function(e){return e},o="";a.sfMessage&&(o=t.$eval(a.sfMessage)||"",o=i(o));var l=function(e){if(e&&t.hasError())n.html(o);else{var a=Object.keys(t.ngModel&&t.ngModel.$error||{}),i=a[0];a.length>1&&(i=a.reduce(function(e,r){return e&&0===e.indexOf("tv4-")?e:r}),console.log("reduced",a,i)),n.html(i?r.interpolate(i,t.ngModel.$modelValue,t.form,t.options&&t.options.validationMessage):o)}};l(),t.$watchCollection("ngModel.$error",function(){t.ngModel&&l(t.ngModel.$valid)})}}}]),angular.module("schemaForm").directive("sfSchema",["$compile","schemaForm","schemaFormDecorators","sfSelect","sfPath",function(e,r,t,n,a){var i=/[A-Z]/g,o=function(e,r){return r=r||"_",e.replace(i,function(e,t){return(t?r:"")+e.toLowerCase()})};return{scope:{schema:"=sfSchema",initialForm:"=sfForm",model:"=sfModel",options:"=sfOptions"},controller:["$scope",function(e){this.evalInParentScope=function(r,t){return e.$parent.$eval(r,t)}}],replace:!1,restrict:"A",transclude:!0,require:"?form",link:function(i,l,u,s,c){i.formCtrl=s;var f={};c(i,function(e){if(e.addClass("schema-form-ignore"),l.prepend(e),l[0].querySelectorAll){var r=l[0].querySelectorAll("[ng-model]");if(r)for(var t=0;t<r.length;t++){var n=r[t].getAttribute("ng-model");f[n.substring(n.indexOf(".")+1)]=!0}}});var m,d={},h=function(s,c){var d=r.merge(s,c,f,i.options),h=document.createDocumentFragment();m&&m.$destroy(),m=i.$new(),m.schemaForm={form:d,schema:s},l.children(":not(.schema-form-ignore)").remove();for(var p={},g=l[0].querySelectorAll("*[sf-insert-field]"),v=0;v<g.length;v++)p[g[v].getAttribute("sf-insert-field")]=g[v];angular.forEach(d,function(e,r){var n=document.createElement(u.sfUseDecorator||o(t.defaultDecorator,"-"));if(n.setAttribute("form","schemaForm.form["+r+"]"),e.key){var i=p[a.stringify(e.key)];if(i){for(;i.firstChild;)i.removeChild(i.firstChild);return void i.appendChild(n)}}h.appendChild(n)}),l[0].appendChild(h),e(l.children())(m),r.traverseSchema(s,function(e,r){if(angular.isDefined(e["default"])){var t=n(r,i.model);angular.isUndefined(t)&&n(r,i.model,e["default"])}}),i.$emit("sf-render-finished",l)};i.$watch(function(){var e=i.schema,r=i.initialForm||["*"];r&&e&&e.type&&(d.form!==r||d.schema!==e)&&Object.keys(e.properties).length>0&&(d.schema=e,d.form=r,h(e,r))}),i.$on("schemaFormRedraw",function(){var e=i.schema,r=i.initialForm||["*"];e&&h(e,r)})}}}]),angular.module("schemaForm").directive("schemaValidate",["sfValidator","sfSelect",function(e,r){return{restrict:"A",scope:!1,priority:500,require:"ngModel",link:function(t,n,a,i){t.$emit("schemaFormPropagateNgModelController",i);var o=null,l=function(){return u||(u=t.$eval(a.schemaValidate)),u},u=l();u.copyValueTo&&i.$viewChangeListeners.push(function(){var e=u.copyValueTo;angular.forEach(e,function(e){r(e,t.model,i.$modelValue)})});var s=function(r){if(u=l(),!u)return r;var t=e.validate(u,r);return Object.keys(i.$error).filter(function(e){return 0===e.indexOf("tv4-")}).forEach(function(e){i.$setValidity(e,!0)}),t.valid?r:(i.$setValidity("tv4-"+t.error.code,!1),void(o=t.error))};"function"==typeof u.ngModel&&u.ngModel(i),["$parsers","$viewChangeListeners","$formatters"].forEach(function(e){u[e]&&i[e]&&u[e].forEach(function(r){i[e].push(r)})}),["$validators","$asyncValidators"].forEach(function(e){u[e]&&i[e]&&angular.forEach(u[e],function(r,t){i[e][t]=r})}),i.$parsers.push(s),t.$on("schemaFormValidate",function(){i.$setDirty?(i.$setDirty(),s(i.$modelValue)):i.$setViewValue(i.$viewValue)}),t.schemaError=function(){return o}}}}]);
!function(e,t){"function"==typeof define&&define.amd?define(["angular","ObjectPath","tv4"],t):"object"==typeof exports?module.exports=t(require("angular"),require("ObjectPath"),require("tv4")):e.schemaForm=t(e.angular,e.ObjectPath,e.tv4)}(this,function(e,t,r){var n=[];try{e.module("ngSanitize"),n.push("ngSanitize")}catch(i){}try{e.module("ui.sortable"),n.push("ui.sortable")}catch(i){}try{e.module("angularSpectrumColorpicker"),n.push("angularSpectrumColorpicker")}catch(i){}var o=e.module("schemaForm",n);return e.module("schemaForm").provider("sfPath",[function(){var r={parse:t.parse};r.stringify=1===e.version.major&&e.version.minor<3?function(e){return Array.isArray(e)?e.join("."):e.toString()}:t.stringify,r.normalize=function(e,t){return r.stringify(Array.isArray(e)?e:r.parse(e),t)},this.parse=r.parse,this.stringify=r.stringify,this.normalize=r.normalize,this.$get=function(){return r}}]),e.module("schemaForm").factory("sfSelect",["sfPath",function(e){var t=/^\d+$/;return function(r,n,i){n||(n=this);var o="string"==typeof r?e.parse(r):r;if("undefined"!=typeof i&&1===o.length)return n[o[0]]=i,n;"undefined"!=typeof i&&"undefined"==typeof n[o[0]]&&(n[o[0]]=o.length>2&&t.test(o[1])?[]:{});for(var a=n[o[0]],s=1;s<o.length;s++){if(""===o[s])return void 0;if("undefined"!=typeof i){if(s===o.length-1)return a[o[s]]=i,i;var l=a[o[s]];("undefined"==typeof l||null===l)&&(l=t.test(o[s+1])?[]:{},a[o[s]]=l),a=l}else a&&(a=a[o[s]])}return a}}]),e.module("schemaForm").provider("schemaFormDecorators",["$compileProvider","sfPathProvider",function(t,r){var n="",i={},o=function(e,t){"sfDecorator"===e&&(e=n);for(var r=i[e],o=r.rules,a=0;a<o.length;a++){var s=o[a](t);if(s)return s}return r.mappings[t.type]?r.mappings[t.type]:r.mappings["default"]},a=function(n){t.directive(n,["$parse","$compile","$http","$templateCache","$interpolate","$q","sfErrorMessage","sfPath",function(t,i,a,s,l,u,c,f){return{restrict:"AE",replace:!1,transclude:!1,scope:!0,require:"?^sfSchema",link:function(t,m,d,h){t.$on("schemaFormPropagateNgModelController",function(e,r){e.stopPropagation(),e.preventDefault(),t.ngModel=r}),t.showTitle=function(){return t.form&&t.form.notitle!==!0&&t.form.title},t.listToCheckboxValues=function(t){var r={};return e.forEach(t,function(e){r[e]=!0}),r},t.checkboxValuesToList=function(t){var r=[];return e.forEach(t,function(e,t){e&&r.push(t)}),r},t.buttonClick=function(r,n){e.isFunction(n.onClick)?n.onClick(r,n):e.isString(n.onClick)&&(h?h.evalInParentScope(n.onClick,{$event:r,form:n}):t.$eval(n.onClick,{$event:r,form:n}))},t.evalExpr=function(e,r){return h?h.evalInParentScope(e,r):t.$eval(e,r)},t.evalInScope=function(e,r){return e?t.$eval(e,r):void 0},t.interp=function(e,t){return e&&l(e)(t)},t.hasSuccess=function(){return t.ngModel?t.ngModel.$valid&&(!t.ngModel.$pristine||!t.ngModel.$isEmpty(t.ngModel.$modelValue)):!1},t.hasError=function(){return t.ngModel?t.ngModel.$invalid&&!t.ngModel.$pristine:!1},t.errorMessage=function(e){return c.interpolate(e&&e.code+""||"default",t.ngModel&&t.ngModel.$modelValue||"",t.ngModel&&t.ngModel.$viewValue||"",t.form,t.options&&t.options.validationMessage)};var p=t.$watch(d.form,function(l){if(l){l.ngModelOptions=l.ngModelOptions||{},t.form=l;var c;if("template"===l.type&&l.template)c=u.when(l.template);else{var d="template"===l.type?l.templateUrl:o(n,l);c=a.get(d,{cache:s}).then(function(e){return e.data})}c.then(function(n){if(l.key){var o=l.key?r.stringify(l.key).replace(/"/g,"&quot;"):"";n=n.replace(/\$\$value\$\$/g,"model"+("["!==o[0]?".":"")+o)}if(m.html(n),l.condition){var a='evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';l.key&&(a='evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model'+f.stringify(l.key)+"})"),e.forEach(m.children(),function(e){var t=e.getAttribute("ng-if");e.setAttribute("ng-if",t?"("+t+") || ("+a+")":a)})}i(m.contents())(t)}),l.key&&t.$on("schemaForm.error."+l.key.join("."),function(e,r,n,i){(n===!0||n===!1)&&(i=n,n=void 0),t.ngModel&&r&&(t.ngModel.$setDirty()?t.ngModel.$setDirty():(t.ngModel.$dirty=!0,t.ngModel.$pristine=!1),n&&(l.validationMessage||(l.validationMessage={}),l.validationMessage[r]=n),t.ngModel.$setValidity(r,i===!0),i===!0&&t.$broadcast("schemaFormValidate"))}),p()}})}}}])},s=function(r,n,i){i=e.isDefined(i)?i:!1,t.directive("sf"+e.uppercase(r[0])+r.substr(1),function(){return{restrict:"EAC",scope:!0,replace:!0,transclude:i,template:'<sf-decorator form="form"></sf-decorator>',link:function(t,n,i){var o={items:"c",titleMap:"c",schema:"c"},a={type:r},s=!0;e.forEach(i,function(r,n){if("$"!==n[0]&&0!==n.indexOf("ng")&&"sfField"!==n){var l=function(r){e.isDefined(r)&&r!==a[n]&&(a[n]=r,s&&a.type&&(a.key||e.isUndefined(i.key))&&(t.form=a,s=!1))};"model"===n?t.$watch(r,function(e){e&&t.model!==e&&(t.model=e)}):"c"===o[n]?t.$watchCollection(r,l):i.$observe(n,l)}})}}})};this.createDecorator=function(e,t,r){i[e]={mappings:t||{},rules:r||[]},i[n]||(n=e),a(e)},this.createDirective=s,this.createDirectives=function(t){e.forEach(t,function(e,t){s(t,e)})},this.directive=function(e){return e=e||n,i[e]},this.addMapping=function(e,t,r){i[e]&&(i[e].mappings[t]=r)},this.$get=function(){return{directive:function(e){return i[e]},defaultDecorator:n}},a("sfDecorator")}]),e.module("schemaForm").provider("sfErrorMessage",function(){var t={"default":"Field does not validate",0:"Invalid type, expected {{schema.type}}",1:"No enum match for: {{value}}",10:'Data does not match any schemas from "anyOf"',11:'Data does not match any schemas from "oneOf"',12:'Data is valid against more than one schema from "oneOf"',13:'Data matches schema from "not"',100:"Value is not a multiple of {{schema.divisibleBy}}",101:"{{viewValue}} is less than the allowed minimum of {{schema.minimum}}",102:"{{viewValue}} is equal to the exclusive minimum {{schema.minimum}}",103:"{{viewValue}} is greater than the allowed maximum of {{schema.maximum}}",104:"{{viewValue}} is equal to the exclusive maximum {{schema.maximum}}",105:"Value is not a valid number",200:"String is too short ({{viewValue.length}} chars), minimum {{schema.minLength}}",201:"String is too long ({{viewValue.length}} chars), maximum {{schema.maxLength}}",202:"String does not match pattern: {{schema.pattern}}",300:"Too few properties defined, minimum {{schema.minProperties}}",301:"Too many properties defined, maximum {{schema.maxProperties}}",302:"Required",303:"Additional properties not allowed",304:"Dependency failed - key must exist",400:"Array is too short ({{value.length}}), minimum {{schema.maxItems}}",401:"Array is too long ({{value.length}}), maximum {{schema.minItems}}",402:"Array items are not unique",403:"Additional items not allowed",500:"Format validation failed",501:'Keyword failed: "{{title}}"',600:"Circular $refs",1e3:"Unknown property (not in schema)"};t.number=t[105],t.required=t[302],t.min=t[101],t.max=t[103],t.maxlength=t[201],t.minlength=t[200],t.pattern=t[202],this.setDefaultMessages=function(e){t=e},this.getDefaultMessages=function(){return t},this.setDefaultMessage=function(e,r){t[e]=r},this.$get=["$interpolate",function(r){var n={};return n.defaultMessages=t,n.interpolate=function(n,i,o,a,s){s=s||{};var l=a.validationMessage||{};0===n.indexOf("tv4-")&&(n=n.substring(4));var u=l["default"]||s["default"]||"";[l,s,t].some(function(t){return e.isString(t)||e.isFunction(t)?(u=t,!0):t&&t[n]?(u=t[n],!0):void 0});var c={error:n,value:i,viewValue:o,form:a,schema:a.schema,title:a.title||a.schema&&a.schema.title};return e.isFunction(u)?u(c):r(u)(c)},n}]}),e.module("schemaForm").provider("schemaForm",["sfPathProvider",function(t){var r=function(e){if(Array.isArray(e)&&2==e.length){if("null"===e[0])return e[1];if("null"===e[1])return e[0]}return e},n=function(e){var t=[];return e.forEach(function(e){t.push({name:e,value:e})}),t},i=function(t,r){if(!e.isArray(t)){var n=[];return r?e.forEach(r,function(e){n.push({name:t[e],value:e})}):e.forEach(t,function(e,t){n.push({name:e,value:t})}),n}return t},o=function(t,n,i){var o=p[r(n.type)];if(o)for(var a,s=0;s<o.length;s++)if(a=o[s](t,n,i))return a.schema["x-schema-form"]&&e.isObject(a.schema["x-schema-form"])&&(a=e.extend(a,a.schema["x-schema-form"])),a},a=function(t,r,n){n=n||{};var o=n.global&&n.global.formDefaults?e.copy(n.global.formDefaults):{};return o.title=n.global&&n.global.supressPropertyTitles===!0?r.title:r.title||t,r.description&&(o.description=r.description),(n.required===!0||r.required===!0)&&(o.required=!0),r.maxLength&&(o.maxlength=r.maxLength),r.minLength&&(o.minlength=r.maxLength),(r.readOnly||r.readonly)&&(o.readonly=!0),r.minimum&&(o.minimum=r.minimum+(r.exclusiveMinimum?1:0)),r.maximum&&(o.maximum=r.maximum-(r.exclusiveMaximum?1:0)),r.validationMessage&&(o.validationMessage=r.validationMessage),r.enumNames&&(o.titleMap=i(r.enumNames,r["enum"])),o.schema=r,o.ngModelOptions=o.ngModelOptions||{},o},s=function(e,n,i){if("string"===r(n.type)&&!n["enum"]){var o=a(e,n,i);return o.key=i.path,o.type="text",i.lookup[t.stringify(i.path)]=o,o}},l=function(e,n,i){if("number"===r(n.type)){var o=a(e,n,i);return o.key=i.path,o.type="number",i.lookup[t.stringify(i.path)]=o,o}},u=function(e,n,i){if("integer"===r(n.type)){var o=a(e,n,i);return o.key=i.path,o.type="number",i.lookup[t.stringify(i.path)]=o,o}},c=function(e,n,i){if("boolean"===r(n.type)){var o=a(e,n,i);return o.key=i.path,o.type="checkbox",i.lookup[t.stringify(i.path)]=o,o}},f=function(e,i,o){if("string"===r(i.type)&&i["enum"]){var s=a(e,i,o);return s.key=o.path,s.type="select",s.titleMap||(s.titleMap=n(i["enum"])),o.lookup[t.stringify(o.path)]=s,s}},m=function(e,i,o){if("array"===r(i.type)&&i.items&&i.items["enum"]){var s=a(e,i,o);return s.key=o.path,s.type="checkboxes",s.titleMap||(s.titleMap=n(i.items["enum"])),o.lookup[t.stringify(o.path)]=s,s}},d=function(n,i,s){if("object"===r(i.type)){var l=a(n,i,s);return l.type="fieldset",l.items=[],s.lookup[t.stringify(s.path)]=l,e.forEach(i.properties,function(e,r){var n=s.path.slice();if(n.push(r),s.ignore[t.stringify(n)]!==!0){var a=i.required&&-1!==i.required.indexOf(r),u=o(r,e,{path:n,required:a||!1,lookup:s.lookup,ignore:s.ignore});u&&l.items.push(u)}}),l}},h=function(e,n,i){if("array"===r(n.type)){var s=a(e,n,i);s.type="array",s.key=i.path,i.lookup[t.stringify(i.path)]=s;var l=n.required&&-1!==n.required.indexOf(i.path[i.path.length-1]),u=i.path.slice();return u.push(""),s.items=[o(e,n.items,{path:u,required:l||!1,lookup:i.lookup,ignore:i.ignore,global:i.global})],s}},p={string:[f,s],object:[d],number:[l],integer:[u],"boolean":[c],array:[m,h]},v=function(e){return e};this.defaults=p,this.stdFormObj=a,this.defaultFormDefinition=o,this.postProcess=function(e){v=e},this.appendRule=function(e,t){p[e]||(p[e]=[]),p[e].push(t)},this.prependRule=function(e,t){p[e]||(p[e]=[]),p[e].unshift(t)},this.createStandardForm=a,this.$get=function(){var n={};return n.merge=function(r,o,a,s,l){o=o||["*"],s=s||{},l=l||r.readonly||r.readOnly;var u=n.defaults(r,a,s),c=o.indexOf("*");-1!==c&&(o=o.slice(0,c).concat(u.form).concat(o.slice(c+1)));var f=u.lookup;return v(o.map(function(o){if("string"==typeof o&&(o={key:o}),o.key&&"string"==typeof o.key&&(o.key=t.parse(o.key)),o.titleMap&&(o.titleMap=i(o.titleMap)),o.itemForm){o.items=[];var u=t.stringify(o.key),c=f[u];e.forEach(c.items,function(t){var r=e.copy(o.itemForm);r.key=t.key,o.items.push(r)})}if(o.key){var m=t.stringify(o.key);if(f[m]){var d=f[m];e.forEach(d,function(e,t){void 0===o[t]&&(o[t]=d[t])})}}return l===!0&&(o.readonly=!0),o.items&&(o.items=n.merge(r,o.items,a,s,o.readonly)),o.tabs&&e.forEach(o.tabs,function(e){e.items=n.merge(r,e.items,a,s,o.readonly)}),"checkbox"===o.type&&e.isUndefined(o.schema["default"])&&(o.schema["default"]=!1),o}))},n.defaults=function(t,n,i){var a=[],s={};if(n=n||{},i=i||{},"object"!==r(t.type))throw new Error('Not implemented. Only type "object" allowed at root level of schema.');return e.forEach(t.properties,function(e,r){if(n[r]!==!0){var l=t.required&&-1!==t.required.indexOf(r),u=o(r,e,{path:[r],lookup:s,ignore:n,required:l,global:i});u&&a.push(u)}}),{form:a,lookup:s}},n.traverseSchema=function(t,r,n,i){i=e.isDefined(i)?i:!0,n=n||[];var o=function(t,r,n){if(r(t,n),e.forEach(t.properties,function(e,t){var i=n.slice();i.push(t),o(e,r,i)}),!i&&t.items){var a=n.slice();a.push(""),o(t.items,r,a)}};o(t,r,n||[])},n.traverseForm=function(t,r){r(t),e.forEach(t.items,function(e){n.traverseForm(e,r)}),t.tabs&&e.forEach(t.tabs,function(t){e.forEach(t.items,function(e){n.traverseForm(e,r)})})},n}}]),e.module("schemaForm").factory("sfValidator",[function(){var t={};return t.validate=function(t,n){if(!t)return{valid:!0};var i=t.schema;if(!i)return{valid:!0};""===n&&(n=void 0),"number"===t.type&&null===n&&(n=void 0);var o={type:"object",properties:{}},a=t.key[t.key.length-1];o.properties[a]=i,t.required&&(o.required=[a]);var s={};return e.isDefined(n)&&(s[a]=n),r.validateResult(s,o)},t}]),e.module("schemaForm").directive("sfArray",["sfSelect","schemaForm","sfValidator","sfPath",function(t,r,n,i){var o=function(e){return function(t){t.key&&(t.key[t.key.indexOf("")]=e)}};return{restrict:"A",scope:!0,require:"?ngModel",link:function(a,s,l,u){var c={};u&&a.$emit("schemaFormPropagateNgModelController",u);var f=a.$watch(l.sfArray,function(s){var l=t(s.key,a.model);if(a.$watch("model"+i.normalize(s.key),function(){l=t(s.key,a.model),a.modelArray=l}),e.isUndefined(l)&&(l=[],t(s.key,a.model,l)),a.modelArray=l,s.items){var m=s.items[0];s.items.length>1&&(m={type:"section",items:s.items.map(function(t){return t.ngModelOptions=s.ngModelOptions,e.isUndefined(t.readonly)&&(t.readonly=s.readonly),t})})}if(a.copyWithIndex=function(t){if(!c[t]&&m){var n=e.copy(m);n.arrayIndex=t,r.traverseForm(n,o(t)),c[t]=n}return c[t]},a.appendToArray=function(){var n=l.length,i=a.copyWithIndex(n);if(r.traverseForm(i,function(r){if(r.key){var n;e.isDefined(r["default"])&&(n=r["default"]),e.isDefined(r.schema)&&e.isDefined(r.schema["default"])&&(n=r.schema["default"]),e.isDefined(n)&&t(r.key,a.model,n)}}),n===l.length){var o,u=t("schema.items.type",s);"object"===u?o={}:"array"===u&&(o=[]),l.push(o)}return a.validateArray&&a.validateArray(),l},a.deleteFromArray=function(e){return l.splice(e,1),a.validateArray&&a.validateArray(),u&&u.$setDirty&&u.$setDirty(),l},s.titleMap||s.startEmpty===!0||0!==l.length||a.appendToArray(),s.titleMap&&s.titleMap.length>0){a.titleMapValues=[];var d=function(e){a.titleMapValues=[],e=e||[],s.titleMap.forEach(function(t){a.titleMapValues.push(-1!==e.indexOf(t.value))})};d(a.modelArray),a.$watchCollection("modelArray",d),a.$watchCollection("titleMapValues",function(e){if(e){for(var t=a.modelArray;t.length>0;)t.pop();s.titleMap.forEach(function(r,n){e[n]&&t.push(r.value)})}})}if(u){var h;a.validateArray=function(){var e=n.validate(s,a.modelArray.length>0?a.modelArray:void 0);Object.keys(u.$error).filter(function(e){return 0===e.indexOf("tv4-")}).forEach(function(e){u.$setValidity(e,!0)}),e.valid!==!1||!e.error||""!==e.error.dataPath&&e.error.dataPath!=="/"+s.key[s.key.length-1]||(u.$setViewValue(a.modelArray),h=e.error,u.$setValidity("tv4-"+e.error.code,!1))},a.$on("schemaFormValidate",a.validateArray),a.hasSuccess=function(){return u.$valid&&!u.$pristine},a.hasError=function(){return u.$invalid},a.schemaError=function(){return h}}f()})}}}]),e.module("schemaForm").directive("sfChanged",function(){return{require:"ngModel",restrict:"AC",scope:!1,link:function(t,r,n,i){var o=t.$eval(n.sfChanged);o&&o.onChange&&i.$viewChangeListeners.push(function(){e.isFunction(o.onChange)?o.onChange(i.$modelValue,o):t.evalExpr(o.onChange,{modelValue:i.$modelValue,form:o})})}}}),e.module("schemaForm").directive("sfMessage",["$injector","sfErrorMessage",function(e,t){return{scope:!1,restrict:"EA",link:function(r,n,i){var o=e.has("$sanitize")?e.get("$sanitize"):function(e){return e},a="";i.sfMessage&&(a=r.$eval(i.sfMessage)||"",a=o(a));var s=function(e){if(e&&!r.hasError())n.html(a);else{var i=Object.keys(r.ngModel&&r.ngModel.$error||{}),o=i[0];n.html(o?t.interpolate(o,r.ngModel.$modelValue,r.ngModel.$viewValue,r.form,r.options&&r.options.validationMessage):a)}};s(),r.$watchCollection("ngModel.$error",function(){r.ngModel&&s(r.ngModel.$valid)})}}}]),e.module("schemaForm").directive("sfSchema",["$compile","schemaForm","schemaFormDecorators","sfSelect","sfPath",function(t,r,n,i,o){var a=/[A-Z]/g,s=function(e,t){return t=t||"_",e.replace(a,function(e,r){return(r?t:"")+e.toLowerCase()})};return{scope:{schema:"=sfSchema",initialForm:"=sfForm",model:"=sfModel",options:"=sfOptions"},controller:["$scope",function(e){this.evalInParentScope=function(t,r){return e.$parent.$eval(t,r)}}],replace:!1,restrict:"A",transclude:!0,require:"?form",link:function(a,l,u,c,f){a.formCtrl=c;var m={};f(a,function(e){if(e.addClass("schema-form-ignore"),l.prepend(e),l[0].querySelectorAll){var t=l[0].querySelectorAll("[ng-model]");if(t)for(var r=0;r<t.length;r++){var n=t[r].getAttribute("ng-model");m[n.substring(n.indexOf(".")+1)]=!0}}});var d,h={},p=function(c,f){var h=r.merge(c,f,m,a.options),p=document.createDocumentFragment();d&&d.$destroy(),d=a.$new(),d.schemaForm={form:h,schema:c},l.children(":not(.schema-form-ignore)").remove();for(var v={},y=l[0].querySelectorAll("*[sf-insert-field]"),g=0;g<y.length;g++)v[y[g].getAttribute("sf-insert-field")]=y[g];e.forEach(h,function(e,t){var r=document.createElement(u.sfUseDecorator||s(n.defaultDecorator,"-"));if(r.setAttribute("form","schemaForm.form["+t+"]"),e.key){var i=v[o.stringify(e.key)];if(i){for(;i.firstChild;)i.removeChild(i.firstChild);return void i.appendChild(r)}}p.appendChild(r)}),l[0].appendChild(p),t(l.children())(d),r.traverseSchema(c,function(t,r){if(e.isDefined(t["default"])){var n=i(r,a.model);e.isUndefined(n)&&i(r,a.model,t["default"])}}),a.$emit("sf-render-finished",l)};a.$watch(function(){var e=a.schema,t=a.initialForm||["*"];t&&e&&e.type&&(h.form!==t||h.schema!==e)&&Object.keys(e.properties).length>0&&(h.schema=e,h.form=t,p(e,t))}),a.$on("schemaFormRedraw",function(){var e=a.schema,t=a.initialForm||["*"];e&&p(e,t)})}}}]),e.module("schemaForm").directive("schemaValidate",["sfValidator","sfSelect",function(t,r){return{restrict:"A",scope:!1,priority:500,require:"ngModel",link:function(n,i,o,a){n.$emit("schemaFormPropagateNgModelController",a);var s=null,l=function(){return u||(u=n.$eval(o.schemaValidate)),u},u=l();u.copyValueTo&&a.$viewChangeListeners.push(function(){var t=u.copyValueTo;e.forEach(t,function(e){r(e,n.model,a.$modelValue)})});var c=function(e){if(u=l(),!u)return e;if(n.options&&n.options.tv4Validation===!1)return e;var r=t.validate(u,e);return Object.keys(a.$error).filter(function(e){return 0===e.indexOf("tv4-")}).forEach(function(e){a.$setValidity(e,!0)}),r.valid?e:(a.$setValidity("tv4-"+r.error.code,!1),void(s=r.error))};"function"==typeof u.ngModel&&u.ngModel(a),["$parsers","$viewChangeListeners","$formatters"].forEach(function(e){u[e]&&a[e]&&u[e].forEach(function(t){a[e].push(t)})}),["$validators","$asyncValidators"].forEach(function(t){u[t]&&a[t]&&e.forEach(u[t],function(e,r){a[t][r]=e})}),a.$parsers.push(c),n.$on("schemaFormValidate",function(){a.$setDirty?(a.$setDirty(),c(a.$modelValue)):a.$setViewValue(a.$viewValue)}),n.schemaError=function(){return s}}}}]),o});

@@ -252,4 +252,4 @@ Documentation

### Message Interpolation
Having a good validation message is hard, sometimes you need to reference the actual value, title
och constraint that you hit. Schema Form supports interpolation of error messages to make this a
Having a good validation message is hard, sometimes you need to reference the actual value, title,
or constraint that you hit. Schema Form supports interpolation of error messages to make this a
little bit easier.

@@ -264,2 +264,3 @@

| value | The model value |
| viewValue | The view value (probably the one you want) |
| form | form definition object for this field |

@@ -627,2 +628,4 @@ | schema | schema for this field |

feedback: false, // Inline feedback icons
disableSuccessState: false, // Set true to NOT apply 'has-success' class to a field that was validated successfully
disableErrorState: false, // Set true to NOT apply 'has-error' class to a field that failed validation
placeholder: "Input...", // placeholder on inputs and textarea

@@ -634,2 +637,3 @@ ngModelOptions: { ... }, // Passed along to ng-model-options

fieldHtmlClass: "street" // CSS Class(es) to be added to field input (or similar)
labelHtmlClass: "street" // CSS Class(es) to be added to the label of the field (or similar)
copyValueTo: ["address.street"], // Copy values to these schema keys.

@@ -733,5 +737,5 @@ condition: "person.age < 18" // Show or hide field depending on an angular expression

the field will be rendered into the DOM otherwise not. The expression is evaluated in the parent scope of
the `sf-schema` directive (the same as onClick on buttons) but with access to the current model
and current array index under the name `model` and `arrayIndex`. This is useful for hiding/showing
parts of a form depending on another form control.
the `sf-schema` directive (the same as onClick on buttons) but with access to the current model,
current model value and current array index under the name `model`, `modelValue` and `arrayIndex`.
This is useful for hiding/showing parts of a form depending on another form control.

@@ -766,4 +770,4 @@ ex. A checkbox that shows an input field for a code when checked

{
key: "code",
condition: "person.eligible", //or "model.eligable"
"key": "code",
"condition": "person.eligible", //or "model.eligible"
}

@@ -770,0 +774,0 @@ ]

var gulp = require('gulp'),
concat = require('gulp-concat'),
rename = require('gulp-rename'),
umd = require('gulp-umd'),
uglify = require('gulp-uglify');

@@ -14,2 +15,13 @@

.pipe(concat('schema-form.js'))
.pipe(umd({
dependencies: function() {
return [
{name: 'angular'},
{name: 'ObjectPath'},
{name: 'tv4'},
]
},
exports: function() {return 'schemaForm';},
namespace: function() {return 'schemaForm';}
}))
.pipe(gulp.dest('./dist/'))

@@ -16,0 +28,0 @@ .pipe(uglify())

{
"name": "angular-schema-form",
"version": "0.8.0",
"version": "0.8.2",
"description": "Create complex forms from a JSON schema with angular.",

@@ -14,5 +14,5 @@ "repository": "Textalk/angular-schema-form",

"David Jensen <david.lgj@gmail.com> (https://github.com/davidlgj)",
"Denis Dervisevic <denis@dervisevic.se> (https://github.com/Dervisevic)",
"Cameron Edwards (https://github.com/cameronprattedwards)",
"Mike Marcacci (https://github.com/mike-marcacci)",
"Denis Dervisevic <denis@dervisevic.se> (https://github.com/Dervisevic)"
"Mike Marcacci (https://github.com/mike-marcacci)"
],

@@ -42,4 +42,6 @@ "license": "MIT",

"gulp-minify-html": "^0.1.1",
"gulp-protractor": "^1.0.0",
"gulp-rename": "^1.2.0",
"gulp-uglify": "^0.2.1",
"gulp-umd": "^0.1.3",
"karma": "^0.12.0",

@@ -54,2 +56,3 @@ "karma-chai-sinon": "^0.1.3",

"mocha-lcov-reporter": "0.0.1",
"protractor": "^2.0.0",
"sinon": "^1.9.0",

@@ -56,0 +59,0 @@ "sinon-chai": "^2.5.0",

@@ -1,2 +0,2 @@

Angular Schema Form [![alt text][1.1]][1]
Angular Schema Form
===================

@@ -11,11 +11,12 @@ [![Build Status](https://travis-ci.org/Textalk/angular-schema-form.svg?branch=master)](https://travis-ci.org/Textalk/angular-schema-form)

Web Page
Web Page / Twitter
--------
[schemaform.io](http://schemaform.io)
[schemaform.io](http://schemaform.io) / [@SchemaFormIO](http://twitter.com/SchemaFormIO)
Demo Time!
----------
[Try out the example page](http://textalk.github.io/angular-schema-form/examples/bootstrap-example.html).
Try editing the schema or form definition and see what comes out!
[Try out the example page](http://schemaform.io/examples/bootstrap-example.html). Try editing the schema or form definition and see what comes out!
Now you can save your code and share it!
What is it?

@@ -204,6 +205,1 @@ ----------

```
<!-- Please don't remove this: Grab your social icons from https://github.com/carlsednaoui/gitsocial -->
[1.1]: http://i.imgur.com/tXSoThF.png (twitter icon with padding)
[1]: http://www.twitter.com/ngSchemaForm
[1.2]: http://i.imgur.com/wWzX9uB.png (twitter icon without padding)

@@ -20,3 +20,3 @@ angular.module('schemaForm').directive('sfMessage',

var update = function(valid) {
if (valid && scope.hasError()) {
if (valid && !scope.hasError()) {
element.html(msg);

@@ -31,16 +31,4 @@ } else {

// TODO: Make that optional
// tv4- errors take precedence
var error = errors[0];
if (errors.length > 1) {
error = errors.reduce(function(prev, value) {
if (prev && prev.indexOf('tv4-') === 0) {
return prev;
}
return value;
});
console.log('reduced',errors, error)
}
if (error) {

@@ -50,2 +38,3 @@ element.html(sfErrorMessage.interpolate(

scope.ngModel.$modelValue,
scope.ngModel.$viewValue,
scope.form,

@@ -52,0 +41,0 @@ scope.options && scope.options.validationMessage

@@ -44,2 +44,7 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSelect', function(sfValidator, sfSelect) {

// Omit TV4 validation
if (scope.options && scope.options.tv4Validation === false) {
return viewValue;
}
var result = sfValidator.validate(form, viewValue);

@@ -46,0 +51,0 @@ // Since we might have different tv4 errors we must clear all

@@ -23,2 +23,2 @@ // Deps is sort of a problem for us, maybe in the future we will ask the user to depend

angular.module('schemaForm', deps);
var schemaForm = angular.module('schemaForm', deps);

@@ -34,4 +34,4 @@ angular.module('schemaForm').provider('schemaFormDecorators',

$compileProvider.directive(name,
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage',
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage) {
['$parse', '$compile', '$http', '$templateCache', '$interpolate', '$q', 'sfErrorMessage', 'sfPath',
function($parse, $compile, $http, $templateCache, $interpolate, $q, sfErrorMessage, sfPath) {

@@ -163,2 +163,3 @@ return {

(scope.ngModel && scope.ngModel.$modelValue) || '',
(scope.ngModel && scope.ngModel.$viewValue) || '',
scope.form,

@@ -208,2 +209,8 @@ scope.options && scope.options.validationMessage

if (form.condition) {
var evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex})';
if (form.key) {
evalExpr = 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex, "modelValue": model' + sfPath.stringify(form.key) + '})';
}
angular.forEach(element.children(), function(child) {

@@ -215,8 +222,7 @@ var ngIf = child.getAttribute('ng-if');

'(' + ngIf +
') || (evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex }))'
: 'evalExpr(form.condition,{ model: model, "arrayIndex": arrayIndex })'
') || (' + evalExpr +')'
: evalExpr
);
});
}
$compile(element.contents())(scope);

@@ -251,3 +257,2 @@ });

}
console.log('settings validationMessage', validationMessage)
form.validationMessage[error] = validationMessage;

@@ -258,5 +263,7 @@ }

// Setting or removing a validity can change the field to believe its valid
// but its not. So lets trigger its validation as well.
scope.$broadcast('schemaFormValidate');
if (validity === true) {
// Setting or removing a validity can change the field to believe its valid
// but its not. So lets trigger its validation as well.
scope.$broadcast('schemaFormValidate');
}
}

@@ -263,0 +270,0 @@ })

@@ -10,3 +10,3 @@ angular.module('schemaForm').provider('sfErrorMessage', function() {

'default': 'Field does not validate',
0: 'Invalid type, expected {{schema.type}})',
0: 'Invalid type, expected {{schema.type}}',
1: 'No enum match for: {{value}}',

@@ -18,15 +18,15 @@ 10: 'Data does not match any schemas from "anyOf"',

// Numeric errors
100: 'Value {{value}} is not a multiple of {{schema.multipleOf}}',
101: 'Value {{value}} is less than minimum {{schema.minimum}}',
102: 'Value {{value}} is equal to exclusive minimum {{schema.minimum}}',
103: 'Value {{value}} is greater than maximum {{schema.maximum}}',
104: 'Value {{value}} is equal to exclusive maximum {{schema.maximum}}',
105: 'Value {{value}} is not a valid number',
100: 'Value is not a multiple of {{schema.divisibleBy}}',
101: '{{viewValue}} is less than the allowed minimum of {{schema.minimum}}',
102: '{{viewValue}} is equal to the exclusive minimum {{schema.minimum}}',
103: '{{viewValue}} is greater than the allowed maximum of {{schema.maximum}}',
104: '{{viewValue}} is equal to the exclusive maximum {{schema.maximum}}',
105: 'Value is not a valid number',
// String errors
200: 'String is too short ({{value.length}} chars), minimum {{schema.minimum}}',
201: 'String is too long ({{value.length}} chars), maximum {{schema.maximum}}',
200: 'String is too short ({{viewValue.length}} chars), minimum {{schema.minLength}}',
201: 'String is too long ({{viewValue.length}} chars), maximum {{schema.maxLength}}',
202: 'String does not match pattern: {{schema.pattern}}',
// Object errors
300: 'Too few properties defined, minimum {{schema.minimum}}',
301: 'Too many properties defined, maximum {{schema.maximum}}',
300: 'Too few properties defined, minimum {{schema.minProperties}}',
301: 'Too many properties defined, maximum {{schema.maxProperties}}',
302: 'Required',

@@ -36,4 +36,4 @@ 303: 'Additional properties not allowed',

// Array errors
400: 'Array is too short ({{value.length}}), minimum {{schema.minimum}}',
401: 'Array is too long ({{value.length}}), maximum {{schema.maximum}}',
400: 'Array is too short ({{value.length}}), minimum {{schema.maxItems}}',
401: 'Array is too long ({{value.length}}), maximum {{schema.minItems}}',
402: 'Array items are not unique',

@@ -50,2 +50,11 @@ 403: 'Additional items not allowed',

// In some cases we get hit with an angular validation error
defaultMessages.number = defaultMessages[105];
defaultMessages.required = defaultMessages[302];
defaultMessages.min = defaultMessages[101];
defaultMessages.max = defaultMessages[103];
defaultMessages.maxlength = defaultMessages[201];
defaultMessages.minlength = defaultMessages[200];
defaultMessages.pattern = defaultMessages[202];
this.setDefaultMessages = function(messages) {

@@ -75,2 +84,3 @@ defaultMessages = messages;

* @param {Any} value the actual model value.
* @param {Any} viewValue the viewValue
* @param {Object} form a form definition object for this field

@@ -81,3 +91,3 @@ * @param {Object} global the global validation messages object (even though its called global

*/
service.interpolate = function(error, value, form, global) {
service.interpolate = function(error, value, viewValue, form, global) {
global = global || {};

@@ -108,2 +118,3 @@ var validationMessage = form.validationMessage || {};

value: value,
viewValue: viewValue,
form: form,

@@ -110,0 +121,0 @@ schema: form.schema,

@@ -1826,3 +1826,172 @@ chai.should();

//generate disableSuccessState, disableErrorState tests for each field
var fields = [
{
name: 'default',
property: {
type: 'string',
pattern: "^[a-zA-Z]+$"
},
form: {
key: ['field']
}
},
{
name: 'textarea',
property: {
type: 'string',
pattern: "^[a-zA-Z]+$"
},
form: {
key: ['field'],
type: 'textarea'
}
},
{
name: 'checkbox',
property: {
type: 'boolean'
},
form: {
key: ["field"]
}
},
{
name: 'radio buttons',
property: {
type: 'boolean',
},
form: {
key: ["field"],
type: "radiobuttons",
titleMap: [
{
"value": false,
"name": "No way"
},
{
"value": true,
"name": "OK"
}
]
}
},
{
name: 'radios inline',
property: {
type: 'boolean',
},
form: {
key: ["field"],
type: "radios-inline",
titleMap: [
{
"value": false,
"name": "No way"
},
{
"value": true,
"name": "OK"
}
]
}
},
{
name: 'radios',
property: {
type: 'boolean',
},
form: {
key: ["field"],
type: "radios",
titleMap: [
{
"value": false,
"name": "No way"
},
{
"value": true,
"name": "OK"
}
]
}
},
{
name: 'select',
property: {
type: 'boolean',
},
form: {
key: ["field"],
type: "select",
titleMap: [
{
"value": false,
"name": "No way"
},
{
"value": true,
"name": "OK"
}
]
}
}
];
});
fields.forEach(function (field) {
it('should not add "has-success" class to ' + field.name + " field if a correct value is entered, but disableSuccessState is set on form", function () {
inject(function($compile, $rootScope){
var scope = $rootScope.$new();
scope.model = {}
scope.schema = {
type: 'object',
properties: {
field: field.property
}
};
scope.form = [field.form];
var tmpl = angular.element('<form name="theForm" sf-schema="schema" sf-form="form" sf-model="model"></form>');
$compile(tmpl)(scope);
$rootScope.$apply();
var ngModelCtrl = scope.theForm['{{form.key.slice(-1)[0]}}'] || scope.theForm['{{form.key.join(\'.\')}}'];
ngModelCtrl.$valid = true;
ngModelCtrl.$pristine = false;
$rootScope.$apply();
tmpl.children().eq(0).children().eq(0).hasClass('has-success').should.be.true;
scope.form[0].disableSuccessState = true;
$rootScope.$apply();
tmpl.children().eq(0).children().eq(0).hasClass('has-success').should.be.false;
});
});
it('should not add "has-error" class to ' + field.name + " field if invalid value is entered, but disableErrorState is set on form", function () {
inject(function($compile, $rootScope){
var scope = $rootScope.$new();
scope.model = {
field: field.errorValue
}
scope.schema = {
type: 'object',
properties: {
field: field.property
}
};
scope.form = [field.form];
var tmpl = angular.element('<form name="theForm" sf-schema="schema" sf-form="form" sf-model="model"></form>');
$compile(tmpl)(scope);
$rootScope.$apply();
var ngModelCtrl = scope.theForm['{{form.key.slice(-1)[0]}}'] || scope.theForm['{{form.key.join(\'.\')}}'];
ngModelCtrl.$invalid = true;
ngModelCtrl.$pristine = false;
$rootScope.$apply();
tmpl.children().eq(0).children().eq(0).hasClass('has-error').should.be.true;
scope.form[0].disableErrorState = true;
$rootScope.$apply();
tmpl.children().eq(0).children().eq(0).hasClass('has-error').should.be.false;
});
});
});
});

@@ -13,2 +13,3 @@ chai.should();

'foobar', //value
'foobar', //view value
{schema: {title: 'Foo'}}, //form

@@ -29,2 +30,3 @@ {'default': 'Oh noes!'}

'foobar', //value
'foobar', //view value
{validationMessage: {'default': 'Oh yes!'}, schema: {title: 'Foo'}}, //form

@@ -45,2 +47,3 @@ {'default': 'Oh noes!'}

'foobar', //value
'foobar', //view value
{schema: {title: 'Foo'}}, //form

@@ -60,2 +63,3 @@ {'default': 'Oh noes!', 'foobar-error': 'Aw chucks!'}

'foobar', //value
'foobar', //view value
{schema: {title: 'Foo'}, validationMessage: {'foobar-error': 'Noooooo!'}}, //form

@@ -75,2 +79,3 @@ {'default': 'Oh noes!', 'foobar-error': 'Aw chucks!'}

'foobar', //value
'foobar', //view value
{

@@ -95,2 +100,3 @@ schema: {title: 'Foo'},

'foobar', //value
'foobar', //view value
{

@@ -110,2 +116,3 @@ schema: {title: 'Foo'},

'foobar', //value
'foobar', //view value
{

@@ -131,2 +138,3 @@ title: 'Bar',

'foobar', //value
'foobar', //view value
{

@@ -151,2 +159,3 @@ schema: {title: 'Foo'},

'foobar', //value
'foobar', //view value
{

@@ -166,2 +175,3 @@ schema: {title: 'Foo'},

value: 'foobar',
viewValue: 'foobar',
form: {

@@ -187,2 +197,3 @@ schema: {title: 'Foo'},

'foobar', //value
'foobar', //view value
{

@@ -200,2 +211,3 @@ schema: {title: 'Foo'},

value: 'foobar',
viewValue: 'foobar',
form: {

@@ -216,3 +228,4 @@ schema: {title: 'Foo'},

'tv4-302', //error
'foobar', //value
'foobar', //value
'foobar', //view value
{

@@ -219,0 +232,0 @@ schema: {title: 'Foo'},

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc