Skip to content

Commit

Permalink
- Change signature of getOptions function to (text, path, input)
Browse files Browse the repository at this point in the history
- Remove node object from exposure.
- Improve startFrom option by returning the start position.
  • Loading branch information
ianido committed Jun 29, 2017
1 parent f71aa6c commit 088d7d6
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 46 deletions.
11 changes: 3 additions & 8 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,21 +157,16 @@ Constructs a new JSONEditor.

Indicate the KeyCodes for trigger confirm completion, by default those keys are: [39, 35, 9] which are the code for [right, end, tab]

- `{Object} applyTo`

Indicate where the autocomplete is going to be activated, under field in json node or/and under value in a json node, default is: ['field','value']

- `{Function} getOptions (autocomplete, node, text, elementType)`

This function will return your possible options for create the autocomplete selection, you can control dynamically which options you want to display according to the current active editing node.
You can return a promise (for async) as well the options array (sync).
*Parameters:*
- autocomplete : The instance of the autocomplete engine.
- node : The current active editing node. (node include field and value)
- text : The text in the current node part. (basically the text that the user is editing)
- elementType : Can be "field" or "value" depending if the user is editing a field name or a value of a node.
- text : The text in the current node part. (basically the text that the user is editing)
- path : The document json object that is being edited.
- input : Can be "field" or "value" depending if the user is editing a field name or a value of a node.

### Methods
Expand Down
9 changes: 3 additions & 6 deletions examples/12_autocomplete_dynamic.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,14 @@
modes: ['text', 'tree'],
autocomplete: {
applyTo:['value'],
getOptions: function (autocomplete, node, text) {
getOptions: function (text, path) {
return new Promise(function (resolve, reject) {
var data = node.editor.get();
var options = extractUniqueWords(data);
var options = extractUniqueWords(path);
if (options.length > 0) resolve(options); else reject();
});
}
}
};


};

// ...

Expand Down
21 changes: 10 additions & 11 deletions examples/13_autocomplete_advanced.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
<script src="../dist/jsoneditor.js"></script>
<script src="jsonpath.min.js"></script>


<style type="text/css">
Expand Down Expand Up @@ -38,26 +39,24 @@
modes: ['text', 'tree'],
autocomplete: {
confirmKeys: [39, 35, 9, 190], // Confirm Autocomplete Keys: [right, end, tab, '.'] // By default are only [right, end, tab]
applyTo:['value'],
getOptions: function (autocomplete, node, text) {
if (!text.startsWith(activationChar)) return [];

getOptions: function (text, path, input) {
if (!text.startsWith(activationChar) || input != 'value') return [];
var data = {};
autocomplete.startFrom = 0;
var startFrom = 0;
var lastPoint = text.lastIndexOf('.');
if ((lastPoint > 0) && (text.length > 1)) {
var fnode = node.editor.node.findNode('.' + text.substring(activationChar.length, lastPoint));
if (fnode && typeof fnode.getValue() == 'object') {
data = fnode.getValue();
data = jsonpath.query(path, '$.' + text.substring(activationChar.length, lastPoint));
if (data.length > 0) data = data[0]; else data = {};
// Indicate that autocompletion should start after the . (ignoring the first part)
autocomplete.startFrom = text.lastIndexOf('.') + 1;
}
startFrom = text.lastIndexOf('.') + 1;
}
else
data = node.editor.get();
data = path;

var optionsStr = YaskON.stringify(data, null, activationChar);
var options = optionsStr.split("\n");
return options;
return { startFrom: startFrom, options: options };
}
}
};
Expand Down
20 changes: 20 additions & 0 deletions examples/jsonpath.min.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/js/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ function completely(config) {
elementHint: null,
elementStyle: null,
wrapper: wrapper, // Only to allow easy access to the HTML elements to the final user (possibly for minor customizations)
show: function (element, options) {
show: function (element, startPos, options) {
this.startFrom = startPos;
this.wrapper.remove();
if (this.elementHint) {
this.elementHint.remove();
Expand Down
43 changes: 23 additions & 20 deletions src/js/treemode.js
Original file line number Diff line number Diff line change
Expand Up @@ -1111,28 +1111,31 @@ treemode._onKeyDown = function (event) {
if (event.target.className.indexOf("jsoneditor-value") >= 0) jsonElementType = "value";
if (event.target.className.indexOf("jsoneditor-field") >= 0) jsonElementType = "field";

if ((this.options.autocomplete.applyTo.indexOf('value') >= 0 && jsonElementType == "value") ||
(this.options.autocomplete.applyTo.indexOf('field') >= 0 && jsonElementType == "field")) {
var node = Node.getNodeFromTarget(event.target);
// Activate autocomplete
setTimeout(function (hnode, element) {
if (element.innerText.length > 0) {
var result = this.options.autocomplete.getOptions(this.autocomplete, hnode, element.innerText, jsonElementType);
if (typeof result.then === 'function') {
// probably a promise
if (result.then(function (options) {
this.autocomplete.show(element, options);
}.bind(this)));
} else {
// definitely not a promise
this.autocomplete.show(element, result);
}
var node = Node.getNodeFromTarget(event.target);
// Activate autocomplete
setTimeout(function (hnode, element) {
if (element.innerText.length > 0) {
var result = this.options.autocomplete.getOptions(element.innerText, editor.get(), jsonElementType);
if (typeof result.then === 'function') {
// probably a promise
if (result.then(function (obj) {
if (obj.options)
this.autocomplete.show(element, obj.startFrom, obj.options);
else
this.autocomplete.show(element, 0, obj);
}.bind(this)));
} else {
// definitely not a promise
if (result.options)
this.autocomplete.show(element, result.startFrom, result.options);
else
this.autocomplete.show(element, 0, result);
}
else
this.autocomplete.hideDropDown();
}
else
this.autocomplete.hideDropDown();

}.bind(this, node, event.target), 50);
}
}.bind(this, node, event.target), 50);
}
}

Expand Down

0 comments on commit 088d7d6

Please sign in to comment.