Jelajahi Sumber

updated wfs js panel

Piotr Labudda 8 tahun lalu
induk
melakukan
dc3823bcf4

+ 125 - 128
SE/se-lib/Route/WfsJsRequestPanel.php

@@ -14,6 +14,11 @@ class Route_WfsJsRequestPanel extends RouteBase {
 	public function defaultAction() {
 		UI::gora();
 		try {
+			$jsFunction = [];
+			$jsFunction['JS_FUNCTION_UPDATE_RESPONSE'] = 'updateWfsResponse';
+			$jsFunction['JS_FUNCTION_GET_SELECTED_FORMAT'] = 'getWfsResponseFormat';
+
+
 			$exampleProcesyFltr = [
 				"	<ogc:Filter>",
 				"		<ogc:Or>",
@@ -146,7 +151,7 @@ class Route_WfsJsRequestPanel extends RouteBase {
 					"<wfs:PropertyName>A_CLASSIFIED</wfs:PropertyName>",
 					"<wfs:PropertyName>A_STATUS</wfs:PropertyName>",
 					"<wfs:PropertyName>A_STATUS_INFO</wfs:PropertyName>",
-					"<wfs:PropertyName>BI_analiza_depth</wfs:PropertyName>",
+					"<wfs:PropertyName>BI_analiza_maxDepth</wfs:PropertyName>",
 					"<wfs:PropertyName>BI_analiza_reloadCache</wfs:PropertyName>",
 					"<wfs:PropertyName>FILE_STATUS</wfs:PropertyName>",
 					"<wfs:PropertyName>FILE_STATUS_info</wfs:PropertyName>",
@@ -165,7 +170,7 @@ class Route_WfsJsRequestPanel extends RouteBase {
 					"<wfs:PropertyName>A_CLASSIFIED</wfs:PropertyName>",
 					"<wfs:PropertyName>A_STATUS</wfs:PropertyName>",
 					"<wfs:PropertyName>A_STATUS_INFO</wfs:PropertyName>",
-					"<wfs:PropertyName>BI_analiza_depth</wfs:PropertyName>",
+					"<wfs:PropertyName>BI_analiza_maxDepth</wfs:PropertyName>",
 					"<wfs:PropertyName>BI_analiza_reloadCache</wfs:PropertyName>",
 					"<wfs:PropertyName>FILE_STATUS</wfs:PropertyName>",
 					"<wfs:PropertyName>FILE_STATUS_info</wfs:PropertyName>",
@@ -205,38 +210,77 @@ class Route_WfsJsRequestPanel extends RouteBase {
 			?	''
 			:	htmlspecialchars($examples['Procesy']['lvl1']['postBody']);
 			// 'wfsRequestFeatureTypeName' = 'default_db__x3A__CRM_PROCES:PROCES'
-			echo UI::h('table', [ 'style' => "width:100%; margin:0", 'class' => "table" ], [
-				UI::h('tr', [], [
-					UI::h('td', [ 'style' => "padding:0; border:none" ], [
-						UI::h('input', [ 'id' => 'wfsRequestFeatureTypeName', 'class' => "form-control", 'value' => $defaultTypeName, 'title' => "Feature name" ]),
+			echo UI::h('form', [ 'id' => "wfs_request" ], [
+				UI::h('div', [ 'style' => "margin-bottom:6px; padding:6px; background-color:#333; color:#fff" ], [
+					UI::h('table', [ 'style' => "width:100%; margin:0 0 6px 0", 'class' => "table" ], [
+						UI::h('tr', [], [
+							UI::h('td', [ 'style' => "width:5%; padding:0 10px 0 0; border:none; line-height:22px; font-size:14px; white-space:nowrap" ], "WFS Request"),
+							UI::h('td', [ 'style' => "padding:0; border:none" ], [
+								UI::h('input', [ 'name' => "type_name", 'id' => 'wfsRequestFeatureTypeName', 'class' => "form-control input-xs", 'value' => $defaultTypeName, 'title' => "Feature name" ]),
+							]),
+							UI::h('td', [ 'style' => "width:5%; padding:3px 0 0 6px; line-height:16px; border:none" ], [
+								UI::h('a', [
+									'id' => "typeNameStorageStructLink",
+									'href' => "index.php?_route=Storage_AclStruct&namespace={$defaultNamespace}",
+									'style' => "color:#68cbfd"
+								], "Struktura")
+							]),
+						])
 					]),
-					UI::h('td', [ 'style' => "width:5%; line-height:18px; border:none" ], [
-						UI::h('a', [
-							'id' => "typeNameStorageStructLink",
-							'href' => "index.php?_route=Storage_AclStruct&namespace={$defaultNamespace}",
-						], "Struktura")
+					UI::h('div', [], [
+						UI::h('label', [ 'style' => "font-weight:normal" ], [
+							" root ",
+							UI::h('input', [ 'name' => "root", 'type' => "checkbox", 'class' => "", 'value' => '1' ]),
+						]),
+						UI::h('label', [ 'style' => "margin-left:8px; font-weight:normal" ], [
+							" maxFeatures: ",
+							UI::h('input', [ 'name' => "maxFeatures", 'type' => "number", 'class' => "form-control input-xs", 'style' => "display:inline-block; width:100px", 'value' => '3' ]),
+						]),
+						UI::h('label', [ 'style' => "margin-left:8px; font-weight:normal" ], [
+							" resolveDepth: ",
+							UI::h('input', [ 'name' => "resolveDepth", 'type' => "number", 'class' => "form-control input-xs", 'style' => "display:inline-block; width:100px", 'value' => '' ]),
+						]),
+						UI::h('label', [ 'style' => "margin-left:8px; font-weight:normal" ], [
+							" primaryKey: ",
+							UI::h('input', [ 'name' => "primaryKey", 'type' => "text", 'class' => "form-control input-xs", 'style' => "display:inline-block; width:100px", 'value' => '' ]),
+						]),
 					]),
-				])
-			]);
-			echo UI::h('label', [], [
-				" root ",
-				UI::h('input', [ 'type' => "checkbox", 'id' => 'wfsRequestParam.root', 'class' => "", 'value' => '1' ]),
-			]);
-			echo UI::h('label', [ 'style' => "margin-left:8px" ], [
-				" maxFeatures: ",
-				UI::h('input', [ 'type' => "number", 'id' => 'wfsRequestParam.maxFeatures', 'class' => "", 'value' => '3' ]),
+					UI::h('details', [ 'style' => "padding:0; background-color:#333; color:#fff", 'open' => "open" ], [
+						UI::h('summary', [ 'style' => "padding:0 3px; margin-bottom:6px; outline:none; cursor:pointer" ], [
+							UI::h('span', [ 'style' => "margin-right:6px" ], "Request Body"),
+							UI::h('label', [ 'style' => "margin-right:6px; cursor:pointer; font-weight:normal", 'onclick' => "return onClickBodyType(event, this, 'ogc:Filter')" ], [
+								UI::h('input', [ 'type' => "radio", 'name' => "wfs_post_body_type", 'value' => "ogc:Filter", 'style' => "margin-right:6px", 'checked' => "checked" ]),
+								UI::h('span', [ 'style' => "margin-right:6px" ], "ogc:Filter"),
+							]),
+							UI::h('label', [ 'style' => "margin-right:6px; cursor:pointer; font-weight:normal", 'onclick' => "return onClickBodyType(event, this, 'graphql:query')" ], [
+								UI::h('input', [ 'type' => "radio", 'name' => "wfs_post_body_type", 'value' => "graphql:query", 'style' => "margin-right:6px" ]),
+								UI::h('span', [ 'style' => "margin-right:6px" ], "graphql:query"),
+							]),
+						]),
+						UI::h('textarea', [ 'id' => 'wfsRequestBody', 'style' => "width:100%; height:300px; color:#000" ], $defaultRequestBody),
+					]),
+				]),
 			]);
-			echo UI::h('label', [ 'style' => "margin-left:8px" ], [
-				" resolveDepth: ",
-				UI::h('input', [ 'type' => "number", 'id' => 'wfsRequestParam.resolveDepth', 'class' => "", 'value' => '' ]),
+
+			echo UI::h('div', [ 'style' => "margin-bottom:6px" ], [
+				UI::h('button', [ 'class' => "btn btn-primary", 'onClick' => "return sendWfsRequest(this)" ], "Wyslij"),
+				UI::h('div', [ 'style' => "display:inline", 'id' => "wfs-example-btns" ]),
 			]);
-			echo UI::h('textarea', [ 'id' => 'wfsRequestBody', 'style' => "width:100%; height:300px" ], $defaultRequestBody);
-			echo UI::h('button', [ 'class' => "btn btn-primary", 'onClick' => "return sendWfsRequest(this)" ], "Wyslij");
-			echo UI::h('div', [ 'style' => "display:inline", 'id' => "wfs-example-btns" ]);
+
 			echo UI::h('details', [ 'style' => "padding:6px; background-color:#333; color:#fff", 'open' => "open" ], [
 				UI::h('summary', [ 'style' => "padding:0 3px; outline:none; cursor:pointer" ], [
-					"WFS Response converted to JSON ",
-					UI::h('button', [ 'class' => "btn btn-xs btn-default", 'onClick' => "return wfsResponseToggleTreeView(this)" ], "toggle tree view"),
+					"WFS Response <i>(converted to JSON)</i> ",
+					UI::h('form', [ 'id' => "wfs_response_format", 'style' => "display:inline" ], [
+						UI::h('label', [ 'style' => "margin-right:6px; cursor:pointer; font-weight:normal", 'onclick' => "return onClickResponseFormat(event, this, 'text')" ], [
+							UI::h('input', [ 'type' => "radio", 'name' => "wfs_post_response_format", 'value' => "text", 'style' => "margin-right:6px", 'checked' => "checked" ]),
+							UI::h('span', [ 'style' => "margin-right:6px" ], "text"),
+						]),
+						UI::h('label', [ 'style' => "margin-right:6px; cursor:pointer; font-weight:normal", 'onclick' => "return onClickResponseFormat(event, this, 'json')" ], [
+							UI::h('input', [ 'type' => "radio", 'name' => "wfs_post_response_format", 'value' => "json", 'style' => "margin-right:6px" ]),
+							UI::h('span', [ 'style' => "margin-right:6px" ], "json tree"),
+						]),
+					]),
+					UI::h('button', [ 'class' => "btn btn-xs btn-default", 'onClick' => "return {$jsFunction['JS_FUNCTION_UPDATE_RESPONSE']}(this)" ], "toggle tree view"),
 				]),
 				UI::h('pre', [ 'id' => 'wfsResponse', 'style' => "margin:0; font-size:x-small; border-radius:0" ], 'loading...'),
 			]);
@@ -267,6 +311,34 @@ class Route_WfsJsRequestPanel extends RouteBase {
 				])),
 			]);
 			UI::endContainer();
+			UI::inlineJS(__FILE__ . '.updateResponseView.js', [
+				// 'NODE_ID_TREE_VIEW_FROM_TEXT' => "wfsResponseTreeView",
+				'NODE_ID_TREE_VIEW_FROM_JSON' => "jsonResponseTreeView",
+				'NODE_ID_WFS_RESPONSE' => "wfsResponse",
+				'JS_FUNCTION_UPDATE_RESPONSE' => $jsFunction['JS_FUNCTION_UPDATE_RESPONSE'],
+				'JS_FUNCTION_GET_SELECTED_FORMAT' => $jsFunction['JS_FUNCTION_GET_SELECTED_FORMAT'],
+			]);
+
+			echo UI::h('script', [], "
+				function onClickBodyType(event, n, setBodyType) {
+					if ('INPUT' === event.target.tagName) {
+						return true
+					}
+					n.form['wfs_post_body_type'].value = setBodyType
+					return false
+				}
+				function onClickResponseFormat(event, n, setFormat) {
+					if ('INPUT' === event.target.tagName) {
+						return true
+					}
+					n.form['wfs_post_response_format'].value = setFormat
+					{$jsFunction['JS_FUNCTION_UPDATE_RESPONSE']}()
+					return false
+				}
+				function {$jsFunction['JS_FUNCTION_GET_SELECTED_FORMAT']}() {
+					return document.getElementById('wfs_response_format')['wfs_post_response_format'].value
+				}
+			");
 			echo UI::h('script', [], "
 				var examples = " . json_encode($examples) . ";
 				console.log('examples', examples)
@@ -277,9 +349,11 @@ class Route_WfsJsRequestPanel extends RouteBase {
 					document.getElementById('wfsRequestFeatureTypeName').value = typeName
 					document.getElementById('typeNameStorageStructLink').href = 'index.php?_route=Storage_AclStruct&namespace=' + typeName.replace('__x3A__', '/').replace(':', '/')
 					document.getElementById('wfsRequestBody').value = example.postBody || ''
-					document.getElementById('wfsRequestParam.root').checked = (example.args && 'root' in example.args && 1 == example.args['root'])
-					document.getElementById('wfsRequestParam.maxFeatures').value = (example.args && 'maxFeatures' in example.args && example.args['maxFeatures'] > 0) ? example.args['maxFeatures'] : 3
-					document.getElementById('wfsRequestParam.resolveDepth').value = (example.args && 'resolveDepth' in example.args && example.args['resolveDepth'] > 0) ? example.args['resolveDepth'] : ''
+					var form = document.getElementById('wfs_request')
+					form['root'].checked = (example.args && 'root' in example.args && 1 == example.args['root'])
+					form['maxFeatures'].value = (example.args && 'maxFeatures' in example.args && example.args['maxFeatures'] > 0) ? example.args['maxFeatures'] : 3
+					form['resolveDepth'].value = (example.args && 'resolveDepth' in example.args && example.args['resolveDepth'] > 0) ? example.args['resolveDepth'] : ''
+					form['primaryKey'].value = (example.args && 'primaryKey' in example.args && example.args['primaryKey'].length > 0) ? example.args['primaryKey'] : ''
 					sendWfsRequest()
 				}
 				for (var groupName in examples) {
@@ -290,31 +364,32 @@ class Route_WfsJsRequestPanel extends RouteBase {
 			");
 			echo UI::h('script', [], "
 				function sendWfsRequest() {
-					var treeViewNode = document.getElementById('wfsResponseTreeView')
-					if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
-					document.getElementById('wfsResponse').style.display = 'block'
-
-					document.getElementById('wfsResponse').innerHTML = 'loading...'
-					var featureTypeName = document.getElementById('wfsRequestFeatureTypeName').value
+					{$jsFunction['JS_FUNCTION_UPDATE_RESPONSE']}('loading...')
 					var postBody = document.getElementById('wfsRequestBody').value.replace(/&lt;/g, '<').replace(/&gt;/g, '>')
-					var wfsParams = {
-						'maxFeatures': 3
-					}
-					if (document.getElementById('wfsRequestParam.root').checked) wfsParams['root'] = '1'
-					if (document.getElementById('wfsRequestParam.maxFeatures')) wfsParams['maxFeatures'] = parseInt(document.getElementById('wfsRequestParam.maxFeatures').value)
-					var resolveDepth = parseInt(document.getElementById('wfsRequestParam.resolveDepth').value)
-					if (resolveDepth > 0 && !isNaN(resolveDepth)) {
-						wfsParams['resolve'] = 'all'
-						wfsParams['resolveDepth'] = resolveDepth
-					}
-					if (postBody) wfsParams['ogc:Filter'] = postBody
+					var form = document.getElementById('wfs_request')
+					var featureTypeName = form['type_name'].value
+					var wfsParams = Object.assign({ maxFeatures: 3 },
+						(form['root'] && form['root'].checked && '1' === form['root'].value) ? { root: 1 } : {},
+						(postBody && form['wfs_post_body_type'] && 'ogc:Filter' === form['wfs_post_body_type'].value) ? {
+							'ogc:Filter': document.getElementById('wfsRequestBody').value.replace(/&lt;/g, '<').replace(/&gt;/g, '>')
+						} : {},
+						(postBody && form['wfs_post_body_type'] && 'graphql:query' === form['wfs_post_body_type'].value) ? {
+							'graphql:query': document.getElementById('wfsRequestBody').value
+						} : {},
+						(form['maxFeatures'] && form['maxFeatures'].value > 0) ? { maxFeatures: parseInt(form['maxFeatures'].value) } : {},
+						(form['resolveDepth'] && form['resolveDepth'].value > 0) ? {
+							resolve: 'all',
+							resolveDepth: ('*' === form['resolveDepth'].value) ? '*' : parseInt(form['resolveDepth'].value)
+						} : {},
+						(form['primaryKey'] && form['primaryKey'].value) ? { primaryKey: form['primaryKey'].value } : {}
+					)
 					console.log('p5WFS_GetFeature', featureTypeName, wfsParams)
 					p5WFS_GetFeature(featureTypeName, wfsParams).then(function (features) {
 						console.log('features', features)
-						document.getElementById('wfsResponse').innerHTML = JSON.stringify(features, null, 2)
+						{$jsFunction['JS_FUNCTION_UPDATE_RESPONSE']}(features)
 					}).catch(function (e) {
 						console.warn(e)
-						document.getElementById('wfsResponse').innerHTML = JSON.stringify(e, null, 2)
+						{$jsFunction['JS_FUNCTION_UPDATE_RESPONSE']}(''+e)
 						p5UI__notifyAjaxCallback({ type: 'error', msg: e })
 					})
 					return false
@@ -326,84 +401,6 @@ class Route_WfsJsRequestPanel extends RouteBase {
 					sendWfsRequest()
 				})()
 			");
-			echo UI::h('script', [], "
-				var DBG = 0;
-
-				function wfsResponseToggleTreeView(btnNode) {
-					btnNode.isTreeViewActive = ! btnNode.isTreeViewActive
-					if(DBG)console.log('btnNode.isTreeViewActive', btnNode.isTreeViewActive)
-
-					if (btnNode.isTreeViewActive) {
-						document.getElementById('wfsResponse').style.display = 'none'
-						if (!document.getElementById('wfsResponseTreeView')) {
-							var respTxtNode = document.getElementById('wfsResponse')
-							var treeViewNode = document.createElement('div')
-							treeViewNode.id = 'wfsResponseTreeView'
-							treeViewNode.style.margin = '0'
-							treeViewNode.style.padding = '9.5px'
-							treeViewNode.style.border = '1px solid #ccc'
-							treeViewNode.style.color = '#333'
-							treeViewNode.style.backgroundColor = '#f5f5f5'
-							treeViewNode.style.fontFamily = 'monospace'
-							treeViewNode.style.fontSize = 'x-small'
-							treeViewNode.style.lineHeight = '1.42857143'
-							treeViewNode.style.wordBreak = 'break-all'
-							treeViewNode.style.wordWrap = 'break-word'
-							treeViewNode.innerHTML = parseJsonTextToTreeView(respTxtNode.innerHTML)
-							respTxtNode.parentNode.insertBefore(treeViewNode, respTxtNode.nextSibling);
-						}
-						document.getElementById('wfsResponseTreeView').style.display = 'block'
-					} else {
-						var treeViewNode = document.getElementById('wfsResponseTreeView')
-						if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
-						document.getElementById('wfsResponse').style.display = 'block'
-					}
-				}
-
-				function parseJsonTextToTreeView(txtJson) {
-					var out = ''
-					var jsonLines = txtJson.split('\\n').map(function (line) {
-						var whiteSpacePrefix = line.match(/^\s*/)[0].length
-						return [ whiteSpacePrefix, line.substr(whiteSpacePrefix) ]
-					})
-					if(DBG)console.table(jsonLines)
-					jsonLines = jsonLines.map(function (jsonLine) {
-						if (jsonLine[1].length > 100) jsonLine[1] = jsonLine[1].substr(0, 100) + '...\"'
-						return jsonLine
-					})
-					return generateTreeView(jsonLines)
-				}
-				function generateTreeView(jsonLines) {
-					if (!jsonLines || !jsonLines.length) return ''
-					out = ''
-					if(DBG)console.log('----------------- group Childrens jsonLines:', jsonLines)
-					groupedChildrens = jsonLines.reduce(function (grouped, cur, idx) {
-						var last = grouped.pop()
-						if (!last) {
-							grouped.push({ deep: cur[0], label: cur[1], childrens: [] })
-							if(DBG)console.log('groupedChildrens::(!last)', ' cur:[ '+cur[0]+', \"'+cur[1]+'\" ]')
-						} else if (cur[0] > last.deep) {
-							last.childrens.push([ cur[0] - 2, cur[1] ])
-							grouped.push(last)
-							if(DBG)console.log('groupedChildrens::(deep > cur[0])', ' cur:[ '+cur[0]+', \"'+cur[1]+'\" ]')
-						} else if (cur[0] === last.deep) {
-							var isEndOfObject = ([ ']', '],', '}', '},' ].indexOf(cur[1]) > -1)
-							if (isEndOfObject && !last.childrens.length) last.label += ' ' + cur[1];
-							grouped.push(last)
-							if (!isEndOfObject) grouped.push({ deep: cur[0], label: cur[1], childrens: [] })
-							// if (!isEndOfObject) console.log('groupedChildrens::(deep === cur[0] && !isEndOfObject)', ' cur:[ '+cur[0]+', \"'+cur[1]+'\" ]')
-							if(DBG)console.log('groupedChildrens::(deep === cur[0])', ' cur:[ '+cur[0]+', \"'+cur[1]+'\" ]')
-						}
-						return grouped
-					}, [])
-					if(DBG)console.log('groupedChildrens', groupedChildrens)
-					return groupedChildrens.map(function (group) {
-						return (group.childrens.length > 0)
-						?	'<details><summary style=\"outline:none; cursor:pointer\">' + group.label + '</summary><div style=\"padding:0 0 0 20px\">' + generateTreeView(group.childrens) + '</div></details>'
-						:	'<div style=\"padding:0 0 0 11px\">' + group.label + '</div>'
-					}).join('\\n')
-				}
-			");
 		} catch (Exception $e) {
 			UI::alert('danger', $e);
 		}

+ 207 - 0
SE/se-lib/Route/WfsJsRequestPanel.php.updateResponseView.js

@@ -0,0 +1,207 @@
+var DBG = 0;
+var NODE_ID_TREE_VIEW_FROM_TEXT = NODE_ID_TREE_VIEW_FROM_TEXT || null // 'NODE_ID_TREE_VIEW_FROM_TEXT' => "wfsResponseTreeView",
+var NODE_ID_TREE_VIEW_FROM_JSON = NODE_ID_TREE_VIEW_FROM_JSON || null // 'NODE_ID_TREE_VIEW_FROM_JSON' => "jsonResponseTreeView",
+// 'NODE_ID_WFS_RESPONSE' => "wfsResponse",
+// 'JS_FUNCTION_UPDATE_RESPONSE' => "updateWfsResponse"
+// 'JS_FUNCTION_GET_SELECTED_FORMAT' => "getWfsResponseFormat"
+
+// Object.prototype.toString.call([]) // "[object Array]"
+// Object.prototype.toString.call('') // "[object String]"
+// Object.prototype.toString.call({}) // "[object Object]"
+// Object.prototype.toString.call(null) // "[object Null]"
+// Object.prototype.toString.call() // "[object Undefined]"
+function p5Utils_isString(arg) { return '[object String]' === Object.prototype.toString.call(arg); }
+function p5Utils_isArray(arg) { return '[object Array]' === Object.prototype.toString.call(arg); }
+function p5Utils_isObject(arg) { return '[object Object]' === Object.prototype.toString.call(arg); }
+
+// private var - global for this file
+var _RESPONSE_DATA = null
+
+function updateResponse(values) {
+	if ('undefined' !== typeof values) _RESPONSE_DATA = values
+	var responseFormat = global[JS_FUNCTION_GET_SELECTED_FORMAT]() // json, text
+	console.warn('format: '+responseFormat+', _RESPONSE_DATA: '+_RESPONSE_DATA)
+
+	document.getElementById(NODE_ID_WFS_RESPONSE).innerHTML = (p5Utils_isString(_RESPONSE_DATA)) ? _RESPONSE_DATA : JSON.stringify(_RESPONSE_DATA, null, 2)
+	if (NODE_ID_TREE_VIEW_FROM_JSON) {
+		var treeViewNode = document.getElementById(NODE_ID_TREE_VIEW_FROM_JSON)
+		if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
+	}
+	if (NODE_ID_TREE_VIEW_FROM_JSON) {
+		var treeViewNode = document.getElementById(NODE_ID_TREE_VIEW_FROM_JSON)
+		if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
+	}
+
+	if (NODE_ID_TREE_VIEW_FROM_JSON) {
+		if ('json' === responseFormat) {
+			document.getElementById(NODE_ID_WFS_RESPONSE).style.display = 'none'
+			if (!document.getElementById(NODE_ID_TREE_VIEW_FROM_JSON)) {
+				var respTxtNode = document.getElementById(NODE_ID_WFS_RESPONSE)
+				var treeViewNode = document.createElement('div')
+				treeViewNode.id = NODE_ID_TREE_VIEW_FROM_JSON
+				treeViewNode.style.margin = '0'
+				treeViewNode.style.padding = '9.5px'
+				treeViewNode.style.border = '1px solid #ccc'
+				treeViewNode.style.color = '#333'
+				treeViewNode.style.backgroundColor = '#f5f5f5'
+				treeViewNode.style.fontFamily = 'monospace'
+				treeViewNode.style.fontSize = 'x-small'
+				treeViewNode.style.lineHeight = '1.42857143'
+				treeViewNode.style.wordBreak = 'break-all'
+				treeViewNode.style.wordWrap = 'break-word'
+				respTxtNode.parentNode.insertBefore(treeViewNode, respTxtNode.nextSibling);
+
+				// var jsonResponse = document.getElementById(NODE_ID_WFS_RESPONSE).data_jsonResponse
+				// if (jsonResponse) {
+				// 	parseJsonToTreeViewRec(jsonResponse, treeViewNode)
+				// }
+				parseJsonToTreeViewRec( _RESPONSE_DATA ? _RESPONSE_DATA : 'TODO:xxx' , treeViewNode)
+			}
+			document.getElementById(NODE_ID_TREE_VIEW_FROM_JSON).style.display = 'block'
+		} else { // 'text' === responseFormat
+			var treeViewNode = document.getElementById(NODE_ID_TREE_VIEW_FROM_JSON)
+			if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
+			document.getElementById(NODE_ID_WFS_RESPONSE).style.display = 'block'
+		}
+	}
+
+	if (NODE_ID_TREE_VIEW_FROM_TEXT) {
+		if ('json' === responseFormat) {
+			document.getElementById(NODE_ID_WFS_RESPONSE).style.display = 'none'
+			if (!document.getElementById(NODE_ID_TREE_VIEW_FROM_TEXT)) {
+				var respTxtNode = document.getElementById(NODE_ID_WFS_RESPONSE)
+				var treeViewNode = document.createElement('div')
+				treeViewNode.id = NODE_ID_TREE_VIEW_FROM_TEXT
+				treeViewNode.style.margin = '0'
+				treeViewNode.style.padding = '9.5px'
+				treeViewNode.style.border = '1px solid #ccc'
+				treeViewNode.style.color = '#333'
+				treeViewNode.style.backgroundColor = '#f5f5f5'
+				treeViewNode.style.fontFamily = 'monospace'
+				treeViewNode.style.fontSize = 'x-small'
+				treeViewNode.style.lineHeight = '1.42857143'
+				treeViewNode.style.wordBreak = 'break-all'
+				treeViewNode.style.wordWrap = 'break-word'
+				treeViewNode.innerHTML = parseJsonTextToTreeView(respTxtNode.innerHTML)
+				respTxtNode.parentNode.insertBefore(treeViewNode, respTxtNode.nextSibling);
+			}
+			document.getElementById(NODE_ID_TREE_VIEW_FROM_TEXT).style.display = 'block'
+		} else { // 'text' === responseFormat
+			var treeViewNode = document.getElementById(NODE_ID_TREE_VIEW_FROM_TEXT)
+			if (treeViewNode) treeViewNode.parentNode.removeChild(treeViewNode)
+			document.getElementById(NODE_ID_WFS_RESPONSE).style.display = 'block'
+		}
+	}
+}
+
+function shortValue(str, limit) {
+	var limit = limit || 100;
+	return (str.length > limit) ? str.substr(0, limit)+'...' : str;
+}
+
+function parseJsonToTreeViewRec(json, node, xpath, name) {
+	var name = name || '';
+	var xpath = xpath || '/root';
+	if(DBG)console.warn('DBG::parseJsonToTreeViewRec(json, node, "'+xpath+'", "'+name+'")', { isString: p5Utils_isString(json), 'isArray': p5Utils_isArray(json), 'isObject': p5Utils_isObject(json), json: json, node: node });
+	if (p5Utils_isArray(json)) {
+		var details = document.createElement('details')
+		details.setAttribute('title', 'xpath: '+xpath)
+		if ('/root' === xpath) details.setAttribute('open', 'open')
+		node.appendChild(details)
+		var summary = document.createElement('summary');
+		details.appendChild(summary)
+		summary.style.outline = 'none'
+		summary.style.cursor = 'pointer'
+		summary.appendChild(document.createTextNode( ( name ? '"'+name+'": ' : '' ) + '['))
+		var div = document.createElement('div')
+		div.style.paddingLeft = '20px'
+		details.appendChild(div)
+		json.forEach(function (subJson, idx) {
+			parseJsonToTreeViewRec(subJson, div, xpath+'['+idx+']')
+		})
+	} else if (p5Utils_isObject(json)) {
+		var details = document.createElement('details')
+		details.setAttribute('title', 'xpath: '+xpath)
+		if ('/root' === xpath) details.setAttribute('open', 'open')
+		node.appendChild(details)
+		var summary = document.createElement('summary');
+		details.appendChild(summary)
+		summary.style.outline = 'none'
+		summary.style.cursor = 'pointer'
+		summary.appendChild(document.createTextNode( ( name ? '"'+name+'": ' : '' ) + '{'))
+		var div = document.createElement('div')
+		div.style.paddingLeft = '20px'
+		details.appendChild(div)
+		Object.keys(json).forEach(function (fieldName) {
+			parseJsonToTreeViewRec(json[fieldName], div, xpath+'/'+fieldName, fieldName)
+		})
+	} else if (p5Utils_isString(json)) {
+		var div = document.createElement('div')
+		div.style.paddingLeft = '11px'
+		div.setAttribute('title', 'xpath: '+xpath+( name ? '/'+name : '' ))
+		node.appendChild(div)
+		div.appendChild(document.createTextNode( name ? '"'+name+'": "'+shortValue(json, 100)+'",' : '"'+json+'",' ));
+	} else {
+		if(DBG)console.warn('TODO: Not implemented - parseJsonToTreeViewRec(json, node)', { isString: p5Utils_isString(json), 'isArray': p5Utils_isArray(json), 'isObject': p5Utils_isObject(json), json: json });
+	}
+}
+
+function p5WFS_ParseXlink(name) {
+	if (!name || !name.length) return false;
+	var splitName = name.split('#')
+	if (2 !== splitName.length) return false;
+	var splitFeatureID = splitName[1].split('.')
+	if (2 !== splitFeatureID.length) return false;
+	return {
+		namespace: splitName[0],
+		featureID: splitName[1],
+		featureName: splitFeatureID[0],
+		primaryKey: splitFeatureID[1],
+	}
+}
+
+function parseJsonTextToTreeView(txtJson) {
+	var out = ''
+	var jsonLines = txtJson.split('\n').map(function (line) {
+		var whiteSpacePrefix = line.match(/^\s*/)[0].length
+		return [ whiteSpacePrefix, line.substr(whiteSpacePrefix) ]
+	})
+	if(DBG)console.table(jsonLines)
+	jsonLines = jsonLines.map(function (jsonLine) {
+		if (jsonLine[1].length > 100) return [ jsonLine[0], jsonLine[1].substr(0, 100) + '..."' ]
+		return jsonLine
+	})
+	return generateTreeView(jsonLines)
+}
+function generateTreeView(jsonLines) {
+	if (!jsonLines || !jsonLines.length) return ''
+	out = ''
+	if(DBG)console.log('----------------- group Childrens jsonLines:', jsonLines)
+	groupedChildrens = jsonLines.reduce(function (grouped, cur, idx) {
+		var last = grouped.pop()
+		if (!last) {
+			grouped.push({ deep: cur[0], label: cur[1], childrens: [] })
+			if(DBG)console.log('groupedChildrens::(!last)', ' cur:[ '+cur[0]+', "'+cur[1]+'" ]')
+		} else if (cur[0] > last.deep) {
+			last.childrens.push([ cur[0] - 2, cur[1] ])
+			grouped.push(last)
+			if(DBG)console.log('groupedChildrens::(deep > cur[0])', ' cur:[ '+cur[0]+', "'+cur[1]+'" ]')
+		} else if (cur[0] === last.deep) {
+			var isEndOfObject = ([ ']', '],', '}', '},' ].indexOf(cur[1]) > -1)
+			if (isEndOfObject && !last.childrens.length) last.label += ' ' + cur[1];
+			grouped.push(last)
+			if (!isEndOfObject) grouped.push({ deep: cur[0], label: cur[1], childrens: [] })
+			// if (!isEndOfObject) console.log('groupedChildrens::(deep === cur[0] && !isEndOfObject)', ' cur:[ '+cur[0]+', "'+cur[1]+'" ]')
+			if(DBG)console.log('groupedChildrens::(deep === cur[0])', ' cur:[ '+cur[0]+', "'+cur[1]+'" ]')
+		}
+		return grouped
+	}, [])
+	if(DBG)console.log('groupedChildrens', groupedChildrens)
+	return groupedChildrens.map(function (group) {
+		return (group.childrens.length > 0)
+		?	'<details><summary style="outline:none; cursor:pointer">' + group.label + '</summary><div style="padding:0 0 0 20px">' + generateTreeView(group.childrens) + '</div></details>'
+		:	'<div style="padding:0 0 0 11px">' + group.label + '</div>'
+	}).join('\n')
+}
+
+global[JS_FUNCTION_UPDATE_RESPONSE] = updateResponse