Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only add expandable class for Objects and Arrays that have data to ex… #63

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 33 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
# Angular JSON Tree
# Angular JaSON Tree

This plugin was forked from angular-json-tree, which was created by awendland. But, he didn't respond to my pull request to fix a minor issue where tree nodes that were objects always had an expansion arrow even if the objects were empty. No hard feelings here as I'm sure he's very busy. We just thought the unnecessary drop down arrow just cluttered up our UI, so a fork, a couple changes, a quick publish to npm, and here we are. And, my name just happens to be Jason. :D

**The rest of this documentation is copied from awendland's repo with minor changes to reflect the difference in naming**

This plugin was created to address a common development issue: how to easily visualize JSON/JS Object trees. From a development standpoint, when querying API endpoints and wishing to easily visualize the response object—or from a design standpoint, when looking for an easy way to display a complex object—this plugin provides an easy to use directive for displaying the Object tree response.

This is nice and easy because all you should have to do is include the directive in your app, and then pass a reference to the directive of which object on the scope you want it to display.

A live implementation of this directive can be found at [http://blog.alexwendland.com/angular-json-tree/](http://blog.alexwendland.com/angular-json-tree/) and the source for that project can be found on the [gh-pages branch](https://github.com/awendland/angular-json-tree/tree/gh-pages).
A live implementation of this directive can be found at the original authors page (without the drop down arrow changes included here) [http://blog.alexwendland.com/angular-json-tree/](http://blog.alexwendland.com/angular-json-tree/) and the source for the original project can be found on the [gh-pages branch](https://github.com/awendland/angular-json-tree/tree/gh-pages).

Source code for this project, with it's small change can be found at [https://github.com/logicalsoftware/angular-JaSON-tree](https://github.com/logicalsoftware/angular-JaSON-tree/).


**Requirements:** AngularJS 1.2+

**File Size:** v1.0.1
**File Size:** v1.0.2

* **JS**: 8.3Kb raw, 2.3Kb minified, 982b gzipped
* **JS + CSS**: 9.6Kb raw, 3.3Kb minified, 1.42Kb gzipped

## Usage:

1. Include `angular-json-tree` as a dependency for your app
1. Include `angular-jason-tree` as a dependency for your app
```javascript
angular.module('myApp', ['angular-json-tree'])
angular.module('myApp', ['angular-jason-tree'])
```
2. Include the supplied CSS file (or create your own).
3. Setup the directive and reference an object on your scope
Expand All @@ -37,12 +44,12 @@ $scope.someobj = {
HTML:

```html
<json-tree object="someobj"></json-tree>
<jason-tree object="someobj"></jason-tree>
```

### via bower:
```
$ bower install angular-json-tree
$ bower install angular-jason-tree
```

## Why I created this:
Expand All @@ -61,38 +68,38 @@ These attributes are available for configuration on the directive:
The object property takes the name of an object on the $scope. This object will be displayed as an expandable tree.

```html
<json-tree object="someobj"></json-tree>
<jason-tree object="someobj"></jason-tree>
```

### start-expanded [optional, default=false]

This is an optional attribute that designates if the tree's root should display as expanded initially. This is useful when you are only showing one json-tree, but would probably be set to false if json-trees were being created with an ng-repeat loop.
This is an optional attribute that designates if the tree's root should display as expanded initially. This is useful when you are only showing one jason-tree, but would probably be set to false if json-trees were being created with an ng-repeat loop.

```html
<json-tree object="someobj" start-expanded="true"></json-tree>
<jason-tree object="someobj" start-expanded="true"></jason-tree>
```

### root-name [optional, default='Object']

This is an optional attribute that sets the title displayed at the root node. This is useful when you are showing sub-portions of an object or want the object root node to have a different string than 'Object'.

```html
<json-tree object="someobj" root-name="'Name'"></json-tree>
<jason-tree object="someobj" root-name="'Name'"></jason-tree>
```

## Styling

The default CSS is separated into two parts: structure and looks. The looks section can be easily modified in order to change font, color and toggle buttons. The structure section can also be modified, but some more care will be needed because it provides the framework from which this directive provides functionality. The looks framework will be covered here while the structure framework will only be touched on.

The json-tree is based on recursive nodes of two basic structures. The first structure is for nodes that have no subnodes themselves (a leaf), and the other is for nodes that have children (a branch). Here the simplified template structures for each, with appropriate, style-able, class names.
The jason-tree is based on recursive nodes of two basic structures. The first structure is for nodes that have no subnodes themselves (a leaf), and the other is for nodes that have children (a branch). Here the simplified template structures for each, with appropriate, style-able, class names.

### Leaf Nodes

```html
<json-node class="not-expandable">
<jason-node class="not-expandable">
<span class="key">{{key}}</span>
<span class="leaf-value">{{value}}</span>
</json-node>
</jason-node>
```
In the default CSS, all `.key` elements have the same style, a bold red color. There is some padding, and then the property's value follows. By default, no special styling is applied to `.leaf-value` elements.

Expand All @@ -101,47 +108,43 @@ In the default CSS, all `.key` elements have the same style, a bold red color. T
Branch nodes have two states: expanded or not-expanded. The not-expanded state is very similar to the leaf nodes and simply exchanges the `.leaf-value` class for `.branch-preview`.

```html
<json-node class="not-expandable">
<jason-node class="not-expandable">
<span class="key">{{key}}</span>
<span class="branch-preview">{{value}}</span>
</json-node>
</jason-node>
```
In the default CSS, `.branch-preview` elements are italicized, concatenated, hidden overflow, and reduced in opacity.

The expanded state is different and contains further subnodes that are generated with ng-repeat:

```html
<json-node class="expandable">
<jason-node class="expandable">
<span class="key">{{key}}</span>
<ul class="branch-value">
<li ng-repeat>
<json-node>{{subnode values}}</json-node>
<jason-node>{{subnode values}}</jason-node>
</li>
</ul>
</json-node>
</jason-node>
```
The `.expandable` class adds several features to the normal `json-node` element. Particularly, by the default looks CSS, a carrot-style toggle pseudo-element will be created. This `::before` element will rotate 90 deg downward when the element is expanded.
The `.expandable` class adds several features to the normal `jason-node` element. Particularly, by the default looks CSS, a carrot-style toggle pseudo-element will be created. This `::before` element will rotate 90 deg downward when the element is expanded.

Additionally, `json-node` elements receive a class corresponding to their object type. For example, the `.array` class or `.object` may be placed on a `json-node`. These classes can be used for special stylings.
Additionally, `jason-node` elements receive a class corresponding to their object type. For example, the `.array` class or `.object` may be placed on a `json-node`. These classes can be used for special stylings.

## Further Explanation:

An example implementation of this project can be found at the [gh-pages branch](https://github.com/awendland/angular-json-tree/tree/gh-pages) of this repository.

## Changelog

#### v1.0.0
* Update *npm* dev dependencies to latest (as of 2016-05-24) and remove unnecessary ones
* Update *angular* dependency to accept all 1.x versions
* Set `main` in bower.json and package.json properly so that this package can easily be included in *bower* and *npm* managed projects ([Issue #7](https://github.com/awendland/angular-json-tree/issues/7), [PR #1](https://github.com/awendland/angular-json-tree/pull/1))
* Allow setting the name of the root node ([Issue #5](https://github.com/awendland/angular-json-tree/issues/5))
* This can be done setting the `root-name` attribute on the directive. An evaluatable expression must be provided, such as `root-name="'My name'"`.

#### v0.0.1
* Initial release
#### v1.0.2
* Forked from angular-json-tree
* changed drop down arrow behavior to not be shown when objects do not have any data.

## Credits:

Thank you to [Alex Wendland](https://blog.alexwendland.com/) for creating angular-json-tree in the first place.

Thank you to [Mark Lagendijk](https://stackoverflow.com/users/665825/mark-lagendijk) from StackOverflow for providing a service than assists in recursive directives. That post can be found [here](http://stackoverflow.com/questions/14430655/recursion-in-angular-directives).

Also, thank you to [chieffancypants](https://github.com/chieffancypants/) for his [angular-loading-bar](https://github.com/chieffancypants/angular-loading-bar) project from which I used the README.md as inspiration for this (poor) one.
Expand Down
12 changes: 7 additions & 5 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
{
"name": "angular-json-tree",
"name": "angular-jason-tree",
"version": "1.0.1",
"description": "Angular directive for displaying a JSON object in an expandable tree structure",
"main": [
"dist/angular-json-tree.js",
"dist/angular-json-tree.css"
"dist/angular-jason-tree.js",
"dist/angular-jason-tree.css"
],
"authors": [
"Jason Sherman <[email protected]>",
"Alex Wendland <[email protected]>"
],
"license": "CC-BY-4.0",
"keywords": [
"angular",
"json"
"json",
"jason"
],
"homepage": "https://github.com/awendland/angular-json-tree",
"homepage": "https://github.com/logicalsoftware/angular-JaSON-tree",
"ignore": [
"**/.*",
"node_modules",
Expand Down
4 changes: 2 additions & 2 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ gulp.task('build:styles', function () {
'src/**/*.less'
])
.pipe($.plumber())
.pipe($.concat('angular-json-tree.css'))
.pipe($.concat('angular-jason-tree.css'))
.pipe($.less())
.pipe($.autoprefixer({ browsers: ['> 1%'] }))
.pipe($.size({ title: 'CSS:' }))
Expand All @@ -43,7 +43,7 @@ gulp.task('build:scripts', function () {
return gulp.src('src/**/*.js')
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
.pipe($.concat('angular-json-tree.js'))
.pipe($.concat('angular-jason-tree.js'))
.pipe($.size({ title: 'JS:' }))
.pipe(gulp.dest('dist'));
});
Expand Down
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "angular-json-tree",
"version": "1.0.1",
"name": "angular-jason-tree",
"version": "1.0.2",
"description": "Angular directive for displaying a JSON object in an expandable tree structure",
"main": "dist/angular-json-tree.js",
"main": "dist/angular-jason-tree.js",
"directories": {
"test": "test"
},
Expand Down Expand Up @@ -38,16 +38,17 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/awendland/angular-json-tree.git"
"url": "git+https://github.com/logicalsoftware/angular-JaSON-tree.git"
},
"keywords": [
"angular",
"json"
"json",
"jason"
],
"author": "Alex Wendland <[email protected]>",
"license": "CC-BY-4.0",
"bugs": {
"url": "https://github.com/awendland/angular-json-tree/issues"
"url": "https://github.com/logicalsoftware/angular-JaSON-tree/issues"
},
"homepage": "https://github.com/awendland/angular-json-tree#readme"
"homepage": "https://github.com/logicalsoftware/angular-JaSON-tree#readme"
}
38 changes: 21 additions & 17 deletions src/json-tree.js → src/jason-tree.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/*global angular */

/** Created by: Alex Wendland ([email protected]), 2014-08-06
/** Forked by: Jason Sherman ([email protected]), 2017-sometime in Nov/Dec
*
* angular-json-tree
* Created by: Alex Wendland ([email protected]), 2014-08-06
*
* angular-jason-tree
*
* Directive for creating a tree-view out of a JS Object. Only loads
* sub-nodes on demand in order to improve performance of rendering large
Expand All @@ -19,13 +21,13 @@
* array: [1,1,2,3,5,8]
* };
* // In the html
* <json-tree object="someObject"></json-tree>
* <jason-tree object="someObject"></jason-tree>
*
* Dependencies:
* - utils (json-tree.js)
* - ajsRecursiveDirectiveHelper (json-tree.js)
* - utils (jason-tree.js)
* - ajsRecursiveDirectiveHelper (jason-tree.js)
*
* Test: json-tree-test.js
* Test: jason-tree-test.js
*/
(function() {
'use strict';
Expand Down Expand Up @@ -73,49 +75,51 @@ var utils = {
}
};

angular.module('angular-json-tree', ['ajs.RecursiveDirectiveHelper'])
.directive('jsonTree', [function jsonTreeDirective() {
angular.module('angular-jason-tree', ['ajs.RecursiveDirectiveHelper'])
.directive('jasonTree', [function jasonTreeDirective() {
return {
restrict: 'E',
scope: {
object: '=',
startExpanded: '&?',
rootName: '&?',
},
template: '<json-node key="rootName() || \'Object\'" value="object" start-expanded="startExpanded()"></json-node>'
template: '<jason-node key="rootName() || \'Object\'" value="object" start-expanded="startExpanded()"></jason-node>'
};
}])
.directive('jsonNode', ['ajsRecursiveDirectiveHelper', function jsonNodeDirective(ajsRecursiveDirectiveHelper) {
.directive('jasonNode', ['ajsRecursiveDirectiveHelper', function jasonNodeDirective(ajsRecursiveDirectiveHelper) {
return {
restrict: 'E',
scope: {
key: '=',
value: '=',
startExpanded: '&?'
},
compile: function jsonNodeDirectiveCompile(elem) {
compile: function jasonNodeDirectiveCompile(elem) {
return ajsRecursiveDirectiveHelper.compile(elem, this);
},
template: ' <span class="key" ng-click="toggleExpanded()">{{key}}</span>' +
' <span class="leaf-value" ng-if="!isExpandable">{{value}}</span>' +
' <span class="branch-preview" ng-if="isExpandable" ng-show="!isExpanded" ng-click="toggleExpanded()">{{preview}}</span>' +
' <ul class="branch-value" ng-if="isExpandable && shouldRender" ng-show="isExpanded">' +
' <li ng-repeat="(subkey,subval) in value">' +
' <json-node key="subkey" value="subval"></json-node>' +
' <jason-node key="subkey" value="subval"></jason-node>' +
' </li>' +
' </ul>',
pre: function jsonNodeDirectiveLink(scope, elem, attrs) {
pre: function jasonNodeDirectiveLink(scope, elem, attrs) {
// Set value's type as Class for CSS styling
elem.addClass(utils.whatClass(scope.value).toLowerCase());
// If the value is an Array or Object, use expandable view type
if (utils.is(scope.value, 'Object') || utils.is(scope.value, 'Array')) {
scope.isExpandable = true;
// Add expandable class for CSS usage
elem.addClass('expandable');
// Add expandable class for CSS usage, but only if there's something to expand
if ((utils.is(scope.value, 'Object') && Object.keys(scope.value).length > 0) || (utils.is(scope.value, 'Array') && scope.value.length > 0)) {
elem.addClass('expandable');
}
// Setup preview text
var isArray = utils.is(scope.value, 'Array');
scope.preview = isArray ? '[ ' : '{ ';
utils.forKeys(scope.value, function jsonNodeDirectiveLinkForKeys(key, value) {
utils.forKeys(scope.value, function jasonNodeDirectiveLinkForKeys(key, value) {
if (isArray) {
scope.preview += value + ', ';
} else {
Expand All @@ -130,7 +134,7 @@ angular.module('angular-json-tree', ['ajs.RecursiveDirectiveHelper'])
}
// Setup isExpanded state handling
scope.isExpanded = scope.startExpanded ? scope.startExpanded() : false;
scope.toggleExpanded = function jsonNodeDirectiveToggleExpanded() {
scope.toggleExpanded = function jasonNodeDirectiveToggleExpanded() {
scope.isExpanded = !scope.isExpanded;
if (scope.isExpanded) {
elem.addClass('expanded');
Expand Down
6 changes: 3 additions & 3 deletions src/json-tree.less → src/jason-tree.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Structure */
json-tree {
jason-tree {
box-sizing: border-box;
*, *:before, *:after {
box-sizing: border-box;
Expand All @@ -23,7 +23,7 @@ json-tree {
}

/* Looks */
json-tree {
jason-tree {
ul {
padding-left: 20px;
}
Expand All @@ -40,7 +40,7 @@ json-tree {
content: ':';
}
}
json-node.expandable {
jason-node.expandable {
&::before {
content: '\25b6';
position: absolute;
Expand Down
8 changes: 4 additions & 4 deletions test/unit/json-tree-test.js → test/unit/jason-tree-test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
describe('The json-tree directive', function () {
describe('The jason-tree directive', function () {
'use strict';

var scope, compile;

beforeEach(function () {
module('angular-json-tree');
module('angular-jason-tree');
inject(function ($compile, $rootScope) {
scope = $rootScope.$new();
compile = $compile;
Expand All @@ -19,8 +19,8 @@ describe('The json-tree directive', function () {
};
});

var unexpandedHtml = '<json-tree object="someObject"><json-tree>';
var expandedHtml = '<json-tree object="someObject" start-expanded="true"><json-tree>';
var unexpandedHtml = '<jason-tree object="someObject"><jason-tree>';
var expandedHtml = '<jason-tree object="someObject" start-expanded="true"><jason-tree>';

it('should generate an un-expanded tree', function () {
var html = unexpandedHtml;
Expand Down