-
Notifications
You must be signed in to change notification settings - Fork 349
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #137 from eneufeld/feat_masterdetail
MasterDetail Renderer
- Loading branch information
Showing
6 changed files
with
243 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
components/renderers/layouts/masterdetail/masterdetail-renderer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
///<reference path="../../../references.ts"/> | ||
|
||
class MasterDetailRenderer implements JSONForms.IRenderer { | ||
|
||
priority = 1; | ||
|
||
constructor(private renderService: JSONForms.IRenderService) { } | ||
|
||
render(element: IUISchemaElement, subSchema: SchemaElement, schemaPath: string, services: JSONForms.Services): JSONForms.IContainerRenderDescription { | ||
var control = JSONForms.RenderDescriptionFactory.createControlDescription(schemaPath, services, ""); | ||
var template = ` | ||
<div class="row"> | ||
<!-- Master --> | ||
<div class="col-sm-30"> | ||
<masterdetail-collection element="element" collection="element.schema.properties"></masterdetail-collection> | ||
</div> | ||
<!-- Detail --> | ||
<div class="col-sm-70"> | ||
<jsonforms schema="element.selectedSchema" data="element.selectedChild" ng-if="element.selectedChild"></jsonforms> | ||
</div> | ||
</div> | ||
`; | ||
control['template'] = template; | ||
control['schema']=subSchema; | ||
control['filter']=(properties) => { | ||
var result = {}; | ||
angular.forEach(properties, (value, key) => { | ||
if (value.type=='array' && value.items.type=='object') { | ||
result[key] = value; | ||
} | ||
}); | ||
return result; | ||
} | ||
return control; | ||
} | ||
|
||
isApplicable(uiElement: IUISchemaElement, jsonSchema: SchemaElement, schemaPath): boolean { | ||
return uiElement.type == "MasterDetailLayout" && jsonSchema !== undefined && jsonSchema.type == 'object'; | ||
} | ||
} | ||
|
||
angular.module('jsonforms.renderers.layouts.masterdetail').run(['RenderService', (RenderService) => { | ||
RenderService.register(new MasterDetailRenderer(RenderService)); | ||
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
///<reference path="../../../references.ts"/> | ||
|
||
angular.module('jsonforms.renderers.layouts.masterdetail', ['jsonforms.renderers.layouts']); | ||
angular.module('jsonforms.renderers.layouts.masterdetail') | ||
.directive('masterdetailCollection', ():ng.IDirective => { | ||
return { | ||
restrict: "E", | ||
replace: true, | ||
scope: { | ||
collection: '=', | ||
element:'=' | ||
}, | ||
template: | ||
` | ||
<div> | ||
<accordion close-others="false"> | ||
<accordion-group is-open="status_attribute.open" ng-repeat="(key, value) in element.filter(collection)"> | ||
<accordion-heading> | ||
{{key}} <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status_attribute.open, 'glyphicon-chevron-right': !status_attribute.open}"></i> | ||
</accordion-heading> | ||
<accordion close-others="false"> | ||
<accordion-group is-open="status_object.open" ng-repeat="child in element.instance[key]"> | ||
<accordion-heading> | ||
<span ng-click="element.selectedChild=child;element.selectedSchema=value.items;">{{child.name}}<!-- label provider needed --></span><i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status_object.open, 'glyphicon-chevron-right': !status_object.open}"></i> | ||
</accordion-heading> | ||
<masterdetail-member element="element" member="value.items"></masterdetail-member> | ||
</accordion-group> | ||
</accordion> | ||
</accordion-group> | ||
</accordion> | ||
</div> | ||
` | ||
} | ||
}) | ||
.directive('masterdetailMember', ($compile):ng.IDirective => { | ||
return { | ||
restrict: "E", | ||
replace: true, | ||
scope: { | ||
member: '=', | ||
element:'=' | ||
}, | ||
link: (scope, element, attrs) => { | ||
$compile('<masterdetail-collection collection="member.properties" element="element"></masterdetail-collection>') | ||
(scope, (cloned, scope) => { | ||
element.replaceWith(cloned); | ||
}); | ||
} | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/// <reference path="../references.ts"/> | ||
|
||
describe('MasterDetail', () => { | ||
|
||
// load all necessary modules and templates | ||
beforeEach(module('jsonforms.form')); | ||
beforeEach(module('jsonforms.renderers.layouts.masterdetail')); | ||
beforeEach(module('jsonforms.renderers.controls.string')); | ||
|
||
beforeEach(module('components/form/form.html')); | ||
beforeEach(module('components/renderers/layouts/layout.html')); | ||
beforeEach(module('components/renderers/controls/control.html')); | ||
|
||
it("should be rendered", inject(($rootScope, $compile) => { | ||
var scope = $rootScope.$new(); | ||
scope.schema = { | ||
"type": "object", | ||
"properties": { | ||
"a":{ | ||
"type": "array", | ||
"items": { | ||
"type":"object", | ||
"properties":{ | ||
"name": { | ||
"type": "string" | ||
}, | ||
} | ||
}, | ||
}, | ||
"c":{ | ||
"type": "array", | ||
"items": { | ||
"type":"object", | ||
"properties":{ | ||
"name": { | ||
"type": "string" | ||
}, | ||
} | ||
} | ||
}, | ||
} | ||
}; | ||
scope.uiSchema = { | ||
"type":"MasterDetailLayout", | ||
"scope": { | ||
"$ref": "#" | ||
}, | ||
}; | ||
scope.data = { | ||
"a": | ||
[ | ||
{"name":"x_1"}, | ||
{"name":"x_2"} | ||
], | ||
"c":[ | ||
{"name":"y_1"}, | ||
{"name":"y_2"} | ||
] | ||
}; | ||
var el = $compile('<jsonforms schema="schema" ui-schema="uiSchema" data="data"/>')(scope); | ||
scope.$digest(); | ||
expect(el.html()).toContain("<!-- Master -->"); //this is not resolved completly | ||
expect(el.html()).toContain("<!-- Detail -->"); //this is not resolved completly | ||
expect(el.html()).toContain('a'); | ||
expect(el.html()).toContain('x_1'); | ||
expect(el.html()).toContain('x_2'); | ||
expect(el.html()).toContain('c'); | ||
expect(el.html()).toContain('y_1'); | ||
expect(el.html()).toContain('y_2'); | ||
|
||
var nameInput_empty = el[0].querySelector("#\\#\\/properties\\/name"); | ||
expect(nameInput_empty).toBeNull(); | ||
|
||
var x1 = el[0].querySelector("accordion accordion accordion-heading span"); | ||
angular.element(x1).triggerHandler("click"); | ||
expect(el.html()).toContain("<label"); | ||
var nameInput = el[0].querySelector("#\\#\\/properties\\/name"); | ||
expect(nameInput).not.toBeNull(); | ||
})); | ||
}); |