2019-12-12 00:09:47 +08:00
|
|
|
<!DOCTYPE HTML>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<title>JSONEditor | Custom query language</title>
|
|
|
|
<meta charset="utf-8" />
|
|
|
|
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
|
|
|
<script src="../dist/jsoneditor.js"></script>
|
|
|
|
<script src="https://unpkg.com/lodash@4.17.15/lodash.min.js"></script>
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
p {
|
|
|
|
max-width: 500px;
|
|
|
|
font-family: sans-serif;
|
|
|
|
font-size: 11pt;
|
|
|
|
}
|
|
|
|
|
|
|
|
code {
|
|
|
|
font-size: 11pt;
|
|
|
|
background: #e5e5e5;
|
|
|
|
}
|
|
|
|
|
|
|
|
#jsoneditor {
|
|
|
|
width: 500px;
|
|
|
|
height: 500px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.warning {
|
|
|
|
color: red;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<p>
|
|
|
|
This demo shows how to configure a custom query language.
|
|
|
|
Click on the "Transform" button and try it out.
|
|
|
|
</p>
|
|
|
|
<p>
|
2020-01-04 17:16:32 +08:00
|
|
|
This basic example uses lodash functions <code>filter</code>, <code>sort</code>, and <code>pick</code>,
|
|
|
|
but you can run any JavaScript code.
|
2019-12-12 00:09:47 +08:00
|
|
|
</p>
|
|
|
|
<p class="warning">
|
|
|
|
WARNING: this example uses <code>new Function()</code> which can be dangerous when executed with arbitrary code.
|
2020-01-04 17:16:32 +08:00
|
|
|
Don't use it in production.
|
2019-12-12 00:09:47 +08:00
|
|
|
</p>
|
|
|
|
<div id="jsoneditor"></div>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
const container = document.getElementById('jsoneditor')
|
|
|
|
const options = {
|
|
|
|
createQuery: function (json, queryOptions) {
|
|
|
|
console.log('createQuery', queryOptions)
|
|
|
|
|
|
|
|
const { filter, sort, projection } = queryOptions
|
|
|
|
let query = 'data'
|
|
|
|
|
|
|
|
if (filter) {
|
2020-01-04 18:41:11 +08:00
|
|
|
// Note that the comparisons embrace type coercion,
|
2020-01-04 17:46:21 +08:00
|
|
|
// so a filter value like '5' (text) will match numbers like 5 too.
|
2020-01-04 18:41:11 +08:00
|
|
|
const getActualValue = filter.field !== '@'
|
|
|
|
? `item => _.get(item, '${filter.field}')`
|
|
|
|
: `item => item`
|
|
|
|
query = `_.filter(${query}, ${getActualValue} ${filter.relation} '${filter.value}')`
|
2019-12-12 00:09:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (sort) {
|
2020-01-04 18:41:11 +08:00
|
|
|
// The '@' field name is a special case,
|
|
|
|
// which means that the field itself is selected.
|
|
|
|
// For example when we have an array containing numbers.
|
|
|
|
query = sort.field !== '@'
|
|
|
|
? `_.orderBy(${query}, '${sort.field}', '${sort.direction}')`
|
|
|
|
: `_.sortBy(${query}, '${sort.direction}')`
|
2019-12-12 00:09:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (projection) {
|
|
|
|
query = `_.map(${query}, item => _.pick(item, ${JSON.stringify(projection.fields)}))`
|
|
|
|
}
|
|
|
|
|
|
|
|
return query
|
|
|
|
},
|
|
|
|
executeQuery: function (json, query) {
|
|
|
|
console.log('executeQuery', query)
|
|
|
|
|
|
|
|
// WARNING: Using new Function() with arbitrary input can be dangerous! Be careful.
|
|
|
|
const execute = new Function('data', 'return ' + query)
|
|
|
|
|
|
|
|
return execute(json)
|
2020-01-04 17:39:34 +08:00
|
|
|
},
|
|
|
|
queryDescription: 'Enter a JavaScript query to filter, sort, or transform the JSON data.<br/>' +
|
|
|
|
'The <a href="https://lodash.com/" target="_blank">Lodash</a> library is available via <code>_</code> to facilitate this.'
|
2019-12-12 00:09:47 +08:00
|
|
|
}
|
|
|
|
const json = []
|
|
|
|
for (let i = 0; i < 100; i++) {
|
|
|
|
var longitude = 4 + i / 100
|
|
|
|
var latitude = 51 + i / 100
|
|
|
|
|
|
|
|
json.push({
|
|
|
|
name: 'Item ' + i,
|
|
|
|
id: String(i),
|
|
|
|
index: i,
|
|
|
|
time: new Date().toISOString(),
|
|
|
|
location: {
|
|
|
|
latitude: longitude,
|
|
|
|
longitude: latitude,
|
|
|
|
coordinates: [longitude, latitude]
|
|
|
|
},
|
|
|
|
random: Math.random()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
const editor = new JSONEditor(container, options, json)
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|