Skip to content

Instantly share code, notes, and snippets.

@deyceg
Last active April 17, 2017 13:58
Show Gist options
  • Save deyceg/6a3bfe870f258ef839b3aaf6b1c5a912 to your computer and use it in GitHub Desktop.
Save deyceg/6a3bfe870f258ef839b3aaf6b1c5a912 to your computer and use it in GitHub Desktop.
Schema Form + UI Bootstrap Accordion
'use strict';
angular
.module('schema-form-accordion')
.directive('sfAccordion', sfAccordion);
function sfAccordion($timeout) {
var ddo = {
restrict: 'A',
require: ['^ngModel', '^accordion', '^form'],
scope: false,
link: linker
};
return ddo;
//////////
function linker(scope, elem, attrs, ctrls) {
var obj = scope.$eval(attrs.sfAccordion);
var ngModelArray = ctrls[0];
var accordionCtrl = ctrls[1];
var accordionFormCtrl = ctrls[2];
scope.canAppend = canAppend;
scope.groups = accordionCtrl.groups;
scope.$watch('groups.length', function(newVal, oldVal){
if(newVal === oldVal) return;
if (newVal > oldVal) {
accordionCtrl.groups[newVal - 1].isOpen = true;
}
})
scope.$watch('modelArray.length', function(newVal, oldVal){
if(newVal === oldVal) {
return;
}
if(newVal > oldVal) {
//work out correct index
var idx = newVal - 1;
}
});
function canAppend() {
scope.$broadcast('schemaFormValidate');
//Close the other accordions
if(accordionFormCtrl.$valid) {
accordionCtrl.closeOthers();
}
return accordionFormCtrl.$valid;
};
}
}
'use strict';
angular
.module('schema-form-accordion')
.directive('sfAccordionGroup', sfAccordionGroup);
function sfAccordionGroup($timeout) {
var ddo = {
restrict: 'A',
require: ['^ngModel', '^accordion', '^form'],
scope: false,
link: linker
};
return ddo;
//////////
function linker(scope, elem, attrs, ctrls) {
var obj = scope.$eval(attrs.wwCollectionItem);
var ngModel = ctrls[0];
var accordionCtrl = ctrls[1];
var accordionForm = ctrls[2];
scope.hasError = function(){
return !accordionForm.$pristine && accordionForm.$invalid;
}
scope.hasSuccess = function(){
return !accordionForm.$pristine && accordionForm.$valid;
}
function validateOnCollapse(){
var accordionScope = accordionCtrl.groups[scope.$index];
//scope does not exist therefore do nothing.
if(!accordionScope) {
return;
}
accordionScope.$watch('isOpen', function(newVal, oldVal) {
if(newVal === false){ //closing
scope.$broadcast('schemaFormValidate');
}
if(accordionForm.$invalid) {
accordionScope.isOpen = true;
}
});
}
//Wait for the accordion to be rendered
$timeout(function() {
validateOnCollapse();
});
}
}
<div sf-array="form"
class="schema-form-array"
ng-model="$$value$$"
ng-model-options="::form.ngModelOptions">
<div ng-show="::form.title">{{ ::form.title }}</div>
<div ng-show="::form.description" ng-bind-html="::form.description"></div>
<accordion id="{{::form.join('.')}}" ng-model="modelArray" sf-accordion="{{::form}}" ng-form="{{::form.join('.')}}" close-others="true">
<accordion-group heading="{{::group.title}}"
ng-form="{{::form.key.slice(-1)[0]}}_{{$index}}"
ng-repeat="item in modelArray track by $index" sf-accordion-group="{{::form}}"
ng-class="{'has-error': hasError(), 'has-success': hasSuccess()}"
is-open="isOpen">
<accordion-heading>
<i ng-hide="$index + 1 <= form.schema.minItems"
ng-click="$event.preventDefault(); deleteFromArray($index)"></i>
{{::form.title}} {{$index + 1}}
</accordion-heading>
<sf-decorator ng-init="arrayIndex = $index" form="copyWithIndex($index)"></sf-decorator>
</accordion-group>
</accordion>
<div>
<button type="button"
ng-click="canAppend() && appendToArray()">
{{ ::form.add }}
</button>
</div>
</div>
@shaun-here
Copy link

Can you show an example for how to use this add-on with form-schema?

@Anthropic
Copy link

@deyceg what he said ^ :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment