@@ -17,15 +17,16 @@ var JSONViewer = (function(document) {
17
17
* @param {Object|Array } json Input value
18
18
* @param {Number } [inputMaxLvl] Process only to max level, where 0..n, -1 unlimited
19
19
* @param {Number } [inputColAt] Collapse at level, where 0..n, -1 unlimited
20
+ * @param {Object } [inputState] Expand or collapse according to given state.
20
21
*/
21
- JSONViewer . prototype . showJSON = function ( jsonValue , inputMaxLvl , inputColAt ) {
22
+ JSONViewer . prototype . showJSON = function ( jsonValue , inputMaxLvl , inputColAt , inputState ) {
22
23
// Process only to maxLvl, where 0..n, -1 unlimited
23
24
var maxLvl = typeof inputMaxLvl === "number" ? inputMaxLvl : - 1 ; // max level
24
25
// Collapse at level colAt, where 0..n, -1 unlimited
25
26
var colAt = typeof inputColAt === "number" ? inputColAt : - 1 ; // collapse at
26
27
27
28
this . _dom_container . innerHTML = "" ;
28
- walkJSONTree ( this . _dom_container , jsonValue , maxLvl , colAt , 0 ) ;
29
+ walkJSONTree ( this . _dom_container , jsonValue , maxLvl , colAt , 0 , 'root' , inputState ) ;
29
30
} ;
30
31
31
32
/**
@@ -37,6 +38,18 @@ var JSONViewer = (function(document) {
37
38
return this . _dom_container ;
38
39
} ;
39
40
41
+ /**
42
+ * Get current expand/collapse state - this can be passed to showJSON to set initial state.
43
+ * For each key, true == expanded and false == collapsed. For missing keys, colAt will apply.
44
+ */
45
+ JSONViewer . prototype . getState = function ( ) {
46
+ var state = { } ;
47
+ this . _dom_container . querySelectorAll ( 'a' ) . forEach ( function ( a ) {
48
+ state [ a . getAttribute ( 'data-key' ) ] = ! a . classList . contains ( 'collapsed' )
49
+ } )
50
+ return state ;
51
+ } ;
52
+
40
53
/**
41
54
* Recursive walk for input value.
42
55
*
@@ -46,12 +59,15 @@ var JSONViewer = (function(document) {
46
59
* @param {Number } colAt Collapse at level, where 0..n, -1 unlimited
47
60
* @param {Number } lvl Current level
48
61
*/
49
- function walkJSONTree ( outputParent , value , maxLvl , colAt , lvl ) {
62
+ function walkJSONTree ( outputParent , value , maxLvl , colAt , lvl , path , state ) {
50
63
var isDate = Object_prototype_toString . call ( value ) === DatePrototypeAsString ;
51
64
var realValue = ! isDate && typeof value === "object" && value !== null && "toJSON" in value ? value . toJSON ( ) : value ;
52
65
if ( typeof realValue === "object" && realValue !== null && ! isDate ) {
53
66
var isMaxLvl = maxLvl >= 0 && lvl >= maxLvl ;
54
67
var isCollapse = colAt >= 0 && lvl >= colAt ;
68
+ if ( state && state . hasOwnProperty ( path ) ) {
69
+ isCollapse = ! state [ path ] ;
70
+ }
55
71
56
72
var isArray = Array . isArray ( realValue ) ;
57
73
var items = isArray ? realValue : Object . keys ( realValue ) ;
@@ -60,7 +76,7 @@ var JSONViewer = (function(document) {
60
76
// root level
61
77
var rootCount = _createItemsCount ( items . length ) ;
62
78
// hide/show
63
- var rootLink = _createLink ( isArray ? "[" : "{" ) ;
79
+ var rootLink = _createLink ( isArray ? "[" : "{" , path ) ;
64
80
65
81
if ( items . length ) {
66
82
rootLink . addEventListener ( "click" , function ( ) {
@@ -94,6 +110,7 @@ var JSONViewer = (function(document) {
94
110
95
111
items . forEach ( function ( key , ind ) {
96
112
var item = isArray ? key : value [ key ] ;
113
+ var itemPath = path + "." + ( isArray ? ind : key ) ;
97
114
var li = document . createElement ( "li" ) ;
98
115
99
116
if ( typeof item === "object" ) {
@@ -114,7 +131,7 @@ var JSONViewer = (function(document) {
114
131
else {
115
132
// 1+ items
116
133
var itemTitle = ( typeof key === "string" ? key + ": " : "" ) + ( itemIsArray ? "[" : "{" ) ;
117
- var itemLink = _createLink ( itemTitle ) ;
134
+ var itemLink = _createLink ( itemTitle , itemPath ) ;
118
135
var itemsCount = _createItemsCount ( itemLen ) ;
119
136
120
137
// maxLvl - only text, no link
@@ -126,7 +143,7 @@ var JSONViewer = (function(document) {
126
143
li . appendChild ( itemLink ) ;
127
144
}
128
145
129
- walkJSONTree ( li , item , maxLvl , colAt , lvl + 1 ) ;
146
+ walkJSONTree ( li , item , maxLvl , colAt , lvl + 1 , itemPath , state ) ;
130
147
li . appendChild ( document . createTextNode ( itemIsArray ? "]" : "}" ) ) ;
131
148
132
149
var list = li . querySelector ( "ul" ) ;
@@ -140,8 +157,14 @@ var JSONViewer = (function(document) {
140
157
itemLink . addEventListener ( "click" , itemLinkCb ) ;
141
158
142
159
// collapse lower level
143
- if ( colAt >= 0 && lvl + 1 >= colAt ) {
144
- itemLinkCb ( ) ;
160
+ if ( state && state . hasOwnProperty ( itemPath ) ) {
161
+ if ( ! state [ itemPath ] ) {
162
+ itemLinkCb ( ) ;
163
+ }
164
+ } else {
165
+ if ( colAt >= 0 && lvl + 1 >= colAt ) {
166
+ itemLinkCb ( ) ;
167
+ }
145
168
}
146
169
}
147
170
}
@@ -154,7 +177,7 @@ var JSONViewer = (function(document) {
154
177
}
155
178
156
179
// recursive
157
- walkJSONTree ( li , item , maxLvl , colAt , lvl + 1 ) ;
180
+ walkJSONTree ( li , item , maxLvl , colAt , lvl + 1 , itemPath , state ) ;
158
181
}
159
182
160
183
// add comma to the end
@@ -244,11 +267,12 @@ var JSONViewer = (function(document) {
244
267
* @param {String } title Link title
245
268
* @return {Element }
246
269
*/
247
- function _createLink ( title ) {
270
+ function _createLink ( title , path ) {
248
271
var linkEl = document . createElement ( "a" ) ;
249
272
linkEl . classList . add ( "list-link" ) ;
250
273
linkEl . href = "javascript:void(0)" ;
251
274
linkEl . innerHTML = title || "" ;
275
+ linkEl . setAttribute ( "data-key" , path ) ;
252
276
253
277
return linkEl ;
254
278
} ;
0 commit comments