Autocomplete final refactory
This commit is contained in:
parent
131e8f106d
commit
1393b148db
|
@ -25,7 +25,7 @@
|
|||
*
|
||||
* @author Jos de Jong, <wjosdejong@gmail.com>
|
||||
* @version 5.6.0
|
||||
* @date 2017-04-15
|
||||
* @date 2017-05-16
|
||||
*/
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
|
@ -164,7 +164,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
// validate options
|
||||
if (options) {
|
||||
var VALID_OPTIONS = [
|
||||
'ace', 'theme',
|
||||
'ace', 'theme','autocomplete',
|
||||
'ajv', 'schema',
|
||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||
|
@ -485,6 +485,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
var ModeSwitcher = __webpack_require__(11);
|
||||
var util = __webpack_require__(4);
|
||||
|
||||
|
||||
// create a mixin with the functions for tree mode
|
||||
var treemode = {};
|
||||
|
||||
|
@ -583,7 +584,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
history: true,
|
||||
mode: 'tree',
|
||||
name: undefined, // field name of root node
|
||||
schema: null
|
||||
schema: null,
|
||||
autocomplete: null
|
||||
};
|
||||
|
||||
// copy all options
|
||||
|
@ -1527,7 +1529,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
*/
|
||||
treemode._onKeyDown = function (event) {
|
||||
var keynum = event.which || event.keyCode;
|
||||
var altKey = event.altKey;
|
||||
var ctrlKey = event.ctrlKey;
|
||||
var metaKey = event.metaKey;
|
||||
var shiftKey = event.shiftKey;
|
||||
var handled = false;
|
||||
|
||||
|
@ -1573,6 +1577,25 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
}
|
||||
}
|
||||
|
||||
if ((this.options.autocomplete) && (!handled)) {
|
||||
if (!ctrlKey && !altKey && !metaKey && (event.key.length == 1 || keynum == 8 || keynum == 46)) {
|
||||
handled = false;
|
||||
if ((this.options.autocomplete.ApplyTo.indexOf('values') >= 0 && event.target.className.indexOf("jsoneditor-value") >= 0) ||
|
||||
(this.options.autocomplete.ApplyTo.indexOf('name') >= 0 && event.target.className.indexOf("jsoneditor-field") >= 0)) {
|
||||
var node = Node.getNodeFromTarget(event.target);
|
||||
if (this.options.autocomplete.ActivationChar == null || event.target.innerText.startsWith(this.options.autocomplete.ActivationChar)) { // Activate autocomplete
|
||||
setTimeout(function (hnode, element) {
|
||||
if (element.innerText.length > 0)
|
||||
this.options.autocomplete.Show(hnode, element);
|
||||
else
|
||||
this.options.autocomplete.Hide();
|
||||
|
||||
}.bind(this, node, event.target), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -25,7 +25,7 @@
|
|||
*
|
||||
* @author Jos de Jong, <wjosdejong@gmail.com>
|
||||
* @version 5.6.0
|
||||
* @date 2017-04-15
|
||||
* @date 2017-05-16
|
||||
*/
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
|
@ -164,7 +164,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
// validate options
|
||||
if (options) {
|
||||
var VALID_OPTIONS = [
|
||||
'ace', 'theme',
|
||||
'ace', 'theme','autocomplete',
|
||||
'ajv', 'schema',
|
||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||
|
@ -8514,6 +8514,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
var ModeSwitcher = __webpack_require__(12);
|
||||
var util = __webpack_require__(5);
|
||||
|
||||
|
||||
// create a mixin with the functions for tree mode
|
||||
var treemode = {};
|
||||
|
||||
|
@ -8612,7 +8613,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
history: true,
|
||||
mode: 'tree',
|
||||
name: undefined, // field name of root node
|
||||
schema: null
|
||||
schema: null,
|
||||
autocomplete: null
|
||||
};
|
||||
|
||||
// copy all options
|
||||
|
@ -9556,7 +9558,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
*/
|
||||
treemode._onKeyDown = function (event) {
|
||||
var keynum = event.which || event.keyCode;
|
||||
var altKey = event.altKey;
|
||||
var ctrlKey = event.ctrlKey;
|
||||
var metaKey = event.metaKey;
|
||||
var shiftKey = event.shiftKey;
|
||||
var handled = false;
|
||||
|
||||
|
@ -9602,6 +9606,25 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
}
|
||||
}
|
||||
|
||||
if ((this.options.autocomplete) && (!handled)) {
|
||||
if (!ctrlKey && !altKey && !metaKey && (event.key.length == 1 || keynum == 8 || keynum == 46)) {
|
||||
handled = false;
|
||||
if ((this.options.autocomplete.ApplyTo.indexOf('values') >= 0 && event.target.className.indexOf("jsoneditor-value") >= 0) ||
|
||||
(this.options.autocomplete.ApplyTo.indexOf('name') >= 0 && event.target.className.indexOf("jsoneditor-field") >= 0)) {
|
||||
var node = Node.getNodeFromTarget(event.target);
|
||||
if (this.options.autocomplete.ActivationChar == null || event.target.innerText.startsWith(this.options.autocomplete.ActivationChar)) { // Activate autocomplete
|
||||
setTimeout(function (hnode, element) {
|
||||
if (element.innerText.length > 0)
|
||||
this.options.autocomplete.Show(hnode, element);
|
||||
else
|
||||
this.options.autocomplete.Hide();
|
||||
|
||||
}.bind(this, node, event.target), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,106 +1,41 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>JSONEditor | Custom styling</title>
|
||||
<title>JSONEditor | Custom styling</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<!--<link href="css/horsey.css" rel="stylesheet" type="text/css">-->
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
<!--<script src="horsey.js"></script>-->
|
||||
<script src="../src/js/autocomplete.js"></script>
|
||||
<style type="text/css">
|
||||
#jsoneditor {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
<style type="text/css">
|
||||
#jsoneditor {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
p {
|
||||
width: 500px;
|
||||
font-family: "DejaVu Sans", sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
p {
|
||||
width: 500px;
|
||||
font-family: "DejaVu Sans", sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="./css/darktheme.css" rel="stylesheet" type="text/css">
|
||||
<link href="./css/darktheme.css" rel="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
This example demonstrates how to customize the look of JSONEditor,
|
||||
the editor below has a dark theme. Note that the example isn't worked
|
||||
out for the mode <code>code</code>. To do that, you can load and configure
|
||||
a custom theme for the Ace editor.
|
||||
</p>
|
||||
<p>
|
||||
This example demonstrates how to customize the look of JSONEditor,
|
||||
the editor below has a dark theme. Note that the example isn't worked
|
||||
out for the mode <code>code</code>. To do that, you can load and configure
|
||||
a custom theme for the Ace editor.
|
||||
</p>
|
||||
|
||||
<div id="jsoneditor"></div>
|
||||
<div id="jsoneditor"></div>
|
||||
|
||||
<script>
|
||||
<script>
|
||||
// create the editor
|
||||
var container = document.getElementById('jsoneditor');
|
||||
var pv = completely({
|
||||
fontSize: '10pt',
|
||||
fontFamily: 'droid sans mono, consolas, monospace, courier new, courier, sans-serif'
|
||||
});
|
||||
var container = document.getElementById('jsoneditor');
|
||||
var options = {
|
||||
modes: ['text', 'tree'],
|
||||
autocomplete: {
|
||||
trigerOn: ['*'],
|
||||
GetOptions: function (node, element, key) {
|
||||
var YaskON = {
|
||||
stringify: function (o, prefix) {
|
||||
prefix = prefix || '';
|
||||
switch (typeof o) {
|
||||
case 'object':
|
||||
var output = "";
|
||||
if (Array.isArray(o)) {
|
||||
o.forEach(function (e, index) {
|
||||
output += prefix + '[' + index + ']' + '\n';
|
||||
if (typeof e == 'object') output += this.stringify(e, prefix + '[' + index + ']');
|
||||
}.bind(this));
|
||||
return output;
|
||||
}
|
||||
output = "";
|
||||
for (var k in o) {
|
||||
if (o.hasOwnProperty(k)) {
|
||||
if (prefix == "") output += this.stringify(o[k], k);
|
||||
//else output += this.stringify(o[k], prefix + '.' + k);
|
||||
}
|
||||
}
|
||||
if (prefix != "") output += prefix + '\n'
|
||||
return output;
|
||||
case 'function':
|
||||
return "";
|
||||
default:
|
||||
return prefix + '\n';
|
||||
}
|
||||
}
|
||||
};
|
||||
var data = {};
|
||||
pv.startFrom = 0;
|
||||
var text = element.innerText;//.substring(1);
|
||||
var lastPoint = text.lastIndexOf('.');
|
||||
if ((lastPoint > 0) && (text.length > 1)) {
|
||||
var fnode = node.editor.node.findNode('.' + text.substring(0, lastPoint));
|
||||
if (fnode && typeof fnode.getValue() == 'object') {
|
||||
data = fnode.getValue();
|
||||
pv.startFrom = text.lastIndexOf('.') + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
data = node.editor.get();
|
||||
|
||||
var optionsStr = YaskON.stringify(data);
|
||||
var options = optionsStr.split("\n");
|
||||
if (options.length > 0)
|
||||
pv.Show(element, options);
|
||||
|
||||
return options;
|
||||
},
|
||||
Hide: function () {
|
||||
pv.hideDropDown();
|
||||
}
|
||||
}
|
||||
modes: ['text', 'tree']
|
||||
};
|
||||
var json = {
|
||||
'array': [1, 2, 3],
|
||||
|
@ -111,6 +46,6 @@
|
|||
'string': 'Hello World'
|
||||
};
|
||||
var editor = new JSONEditor(container, options, json);
|
||||
</script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>JSONEditor | Auto Complete</title>
|
||||
|
||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
||||
<script src="../dist/jsoneditor.js"></script>
|
||||
<script src="autocomplete.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
#jsoneditor {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
p {
|
||||
width: 500px;
|
||||
font-family: "DejaVu Sans", sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="./css/darktheme.css" rel="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
This example demonstrates how to customize the look of JSONEditor,
|
||||
the editor below has a dark theme. Note that the example isn't worked
|
||||
out for the mode <code>code</code>. To do that, you can load and configure
|
||||
a custom theme for the Ace editor.
|
||||
</p>
|
||||
|
||||
<div id="jsoneditor"></div>
|
||||
|
||||
<script>
|
||||
// create the editor
|
||||
var container = document.getElementById('jsoneditor');
|
||||
var pv = autocomplete({
|
||||
fontSize: '10pt',
|
||||
fontFamily: 'droid sans mono, consolas, monospace, courier new, courier, sans-serif'
|
||||
});
|
||||
|
||||
var options = {
|
||||
modes: ['text', 'tree'],
|
||||
autocomplete: {
|
||||
ActivationChar: '',
|
||||
ApplyTo:['values'],
|
||||
Show: function (node, element) {
|
||||
var YaskON = {
|
||||
stringify: function (o, prefix, activationChar) {
|
||||
prefix = prefix || '';
|
||||
switch (typeof o) {
|
||||
case 'object':
|
||||
var output = "";
|
||||
if (Array.isArray(o)) {
|
||||
o.forEach(function (e, index) {
|
||||
output += activationChar + prefix + '[' + index + ']' + '\n';
|
||||
}.bind(this));
|
||||
return output;
|
||||
}
|
||||
output = "";
|
||||
for (var k in o) {
|
||||
if (o.hasOwnProperty(k)) {
|
||||
if (prefix == "") output += this.stringify(o[k], k, activationChar);
|
||||
}
|
||||
}
|
||||
if (prefix != "") output += activationChar + prefix + '\n'
|
||||
return output;
|
||||
case 'function':
|
||||
return "";
|
||||
default:
|
||||
return prefix + '\n';
|
||||
}
|
||||
}
|
||||
};
|
||||
var data = {};
|
||||
pv.startFrom = 0;
|
||||
var text = element.innerText;
|
||||
var lastPoint = text.lastIndexOf('.');
|
||||
if ((lastPoint > 0) && (text.length > 1)) {
|
||||
var fnode = node.editor.node.findNode('.' + text.substring(this.ActivationChar.length, lastPoint));
|
||||
if (fnode && typeof fnode.getValue() == 'object') {
|
||||
data = fnode.getValue();
|
||||
pv.startFrom = text.lastIndexOf('.') + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
data = node.editor.get();
|
||||
|
||||
var optionsStr = YaskON.stringify(data, null, this.ActivationChar);
|
||||
var options = optionsStr.split("\n");
|
||||
|
||||
if (options.length > 0)
|
||||
pv.Show(element, options);
|
||||
},
|
||||
Hide: function () {
|
||||
pv.hideDropDown();
|
||||
}
|
||||
}
|
||||
};
|
||||
var json = {
|
||||
'array': [{'field1':'v1', 'field2':'v2'}, 2, 3],
|
||||
'boolean': true,
|
||||
'null': null,
|
||||
'number': 123,
|
||||
'object': {'a': 'b', 'c': 'd'},
|
||||
'string': 'Hello World'
|
||||
};
|
||||
var editor = new JSONEditor(container, options, json);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
function completely(config) {
|
||||
function autocomplete(config) {
|
||||
config = config || {};
|
||||
config.fontSize = config.fontSize || '16px';
|
||||
config.fontFamily = config.fontFamily || 'sans-serif';
|
||||
|
@ -167,11 +167,10 @@ function completely(config) {
|
|||
}
|
||||
|
||||
var rs = {
|
||||
onArrowDown: function () { }, // defaults to no action.
|
||||
onArrowUp: function () { }, // defaults to no action.
|
||||
onEnter: function () { }, // defaults to no action.
|
||||
onTab: function () { }, // defaults to no action.
|
||||
onChange: function () { }, // defaults to repainting.
|
||||
onArrowDown: function () { }, // defaults to no action.
|
||||
onArrowUp: function () { }, // defaults to no action.
|
||||
onEnter: function () { }, // defaults to no action.
|
||||
onTab: function () { }, // defaults to no action.
|
||||
startFrom: 0,
|
||||
options: [],
|
||||
element: null,
|
||||
|
@ -213,11 +212,6 @@ function completely(config) {
|
|||
this.elementHint.style.color = config.hintColor;
|
||||
this.elementHint.onfocus = function () { this.element.focus(); }.bind(this);
|
||||
|
||||
/*
|
||||
registerOnTextChange(this.element, function (text) { // note the function needs to be wrapped as API-users will define their onChange
|
||||
rs.onChange(text);
|
||||
});*/
|
||||
|
||||
if (this.element.addEventListener) {
|
||||
this.element.removeEventListener("keydown", keyDownHandler);
|
||||
this.element.addEventListener("keydown", keyDownHandler, false);
|
||||
|
@ -243,12 +237,13 @@ function completely(config) {
|
|||
if (this.elementHint) {
|
||||
this.elementHint.remove();
|
||||
this.elementHint = null;
|
||||
dropDownController.hide();
|
||||
this.element.style.zIndex = this.elementStyle.zIndex;
|
||||
this.element.style.position = this.elementStyle.position;
|
||||
this.element.style.backgroundColor = this.elementStyle.backgroundColor;
|
||||
this.element.style.borderColor = this.elementStyle.borderColor;
|
||||
}
|
||||
dropDownController.hide();
|
||||
this.element.style.zIndex = this.elementStyle.zIndex;
|
||||
this.element.style.position = this.elementStyle.position;
|
||||
this.element.style.backgroundColor = this.elementStyle.backgroundColor;
|
||||
this.element.style.borderColor = this.elementStyle.borderColor;
|
||||
|
||||
},
|
||||
repaint: function (element) {
|
||||
var text = element.innerText;
|
||||
|
@ -270,7 +265,6 @@ function completely(config) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// moving the dropDown and refreshing it.
|
||||
dropDown.style.left = calculateWidthForText(leftSide) + 'px';
|
||||
dropDownController.refresh(token, this.options);
|
||||
|
@ -284,7 +278,7 @@ function completely(config) {
|
|||
var dropDownController = createDropDownController(dropDown, rs);
|
||||
|
||||
var keyDownHandler = function (e) {
|
||||
console.log("Keydown:" + e.keyCode);
|
||||
//console.log("Keydown:" + e.keyCode);
|
||||
e = e || window.event;
|
||||
var keyCode = e.keyCode;
|
||||
|
||||
|
@ -294,32 +288,28 @@ function completely(config) {
|
|||
if (keyCode == 34) { return; } // page down (do nothing);
|
||||
|
||||
if (keyCode == 27) { //escape
|
||||
dropDownController.hide();
|
||||
this.elementHint.innerText = this.element.innerText; // ensure that no hint is left.
|
||||
this.element.focus();
|
||||
rs.hideDropDown();
|
||||
rs.element.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyCode == 39 || keyCode == 35 || keyCode == 9) { // right, end, tab (autocomplete triggered)
|
||||
if (keyCode == 9) { // for tabs we need to ensure that we override the default behaviour: move to the next focusable HTML-element
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (keyCode == 39 || keyCode == 35 || keyCode == 9 || keyCode == 190) { // right, end, tab, '.' (autocomplete triggered)
|
||||
if (keyCode == 9) {
|
||||
if (this.elementHint.innerText.length == 0) {
|
||||
rs.onTab(); // tab was called with no action.
|
||||
// users might want to re-enable its default behaviour or handle the call somehow.
|
||||
rs.onTab();
|
||||
}
|
||||
}
|
||||
if (this.elementHint.innerText.length > 0) { // if there is a hint
|
||||
dropDownController.hide();
|
||||
if (this.element.innerText != this.elementHint.innerText) {
|
||||
this.element.innerText = this.elementHint.innerText;
|
||||
rs.hideDropDown();
|
||||
setEndOfContenteditable(this.element);
|
||||
var hasTextChanged = registerOnTextChangeOldValue != this.element.innerText
|
||||
registerOnTextChangeOldValue = this.element.innerText; // <-- to avoid dropDown to appear again.
|
||||
// for example imagine the array contains the following words: bee, beef, beetroot
|
||||
// user has hit enter to get 'bee' it would be prompted with the dropDown again (as beef and beetroot also match)
|
||||
if (hasTextChanged) {
|
||||
rs.onChange(this.element.innerText); // <-- forcing it.
|
||||
if (keyCode == 9) {
|
||||
rs.element.focus();
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,24 +324,17 @@ function completely(config) {
|
|||
dropDownController.hide();
|
||||
|
||||
if (wasDropDownHidden) {
|
||||
this.elementHint.innerText = this.element.innerText; // ensure that no hint is left.
|
||||
this.element.focus();
|
||||
rs.hideDropDown();
|
||||
rs.element.focus();
|
||||
rs.onEnter();
|
||||
return;
|
||||
}
|
||||
|
||||
this.element.innerText = this.elementHint.innerText;
|
||||
var hasTextChanged = registerOnTextChangeOldValue != this.element.innerText
|
||||
registerOnTextChangeOldValue = this.element.innerText; // <-- to avoid dropDown to appear again.
|
||||
// for example imagine the array contains the following words: bee, beef, beetroot
|
||||
// user has hit enter to get 'bee' it would be prompted with the dropDown again (as beef and beetroot also match)
|
||||
if (hasTextChanged) {
|
||||
rs.onChange(this.element.innerText); // <-- forcing it.
|
||||
}
|
||||
rs.hideDropDown();
|
||||
setEndOfContenteditable(this.element);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setEndOfContenteditable(this.element);
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -378,51 +361,18 @@ function completely(config) {
|
|||
|
||||
var onBlurHandler = function (e) {
|
||||
rs.hideDropDown();
|
||||
//console.log("Lost focus.");
|
||||
}.bind(rs);
|
||||
|
||||
dropDownController.onmouseselection = function (text, rs) {
|
||||
rs.element.innerText = rs.elementHint.innerText = leftSide + text;
|
||||
rs.hideDropDown();
|
||||
window.setTimeout(function () {
|
||||
rs.element.focus();
|
||||
setEndOfContenteditable(rs.element);
|
||||
}, 1);
|
||||
};
|
||||
|
||||
var registerOnTextChangeOldValue;
|
||||
|
||||
/**
|
||||
* Register a callback function to detect changes to the content of the input-type-text.
|
||||
* Those changes are typically followed by user's action: a key-stroke event but sometimes it might be a mouse click.
|
||||
**/
|
||||
var registerOnTextChange = function (txt, callback) {
|
||||
registerOnTextChangeOldValue = txt.value;
|
||||
var handler = function () {
|
||||
var value = txt.value;
|
||||
if (registerOnTextChangeOldValue !== value) {
|
||||
registerOnTextChangeOldValue = value;
|
||||
callback(value);
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// For user's actions, we listen to both input events and key up events
|
||||
// It appears that input events are not enough so we defensively listen to key up events too.
|
||||
// source: http://help.dottoro.com/ljhxklln.php
|
||||
//
|
||||
// The cost of listening to three sources should be negligible as the handler will invoke callback function
|
||||
// only if the text.value was effectively changed.
|
||||
//
|
||||
//
|
||||
if (txt.addEventListener) {
|
||||
txt.addEventListener("input", handler, false);
|
||||
txt.addEventListener('keyup', handler, false);
|
||||
txt.addEventListener('change', handler, false);
|
||||
} else { // is this a fair assumption: that attachEvent will exist ?
|
||||
txt.attachEvent('oninput', handler); // IE<9
|
||||
txt.attachEvent('onkeyup', handler); // IE<9
|
||||
txt.attachEvent('onchange', handler); // IE<9
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ var ContextMenu = require('./ContextMenu');
|
|||
var Node = require('./Node');
|
||||
var ModeSwitcher = require('./ModeSwitcher');
|
||||
var util = require('./util');
|
||||
var Autocomplete = require('./autocomplete');
|
||||
|
||||
|
||||
// create a mixin with the functions for tree mode
|
||||
var treemode = {};
|
||||
|
@ -1102,19 +1102,20 @@ treemode._onKeyDown = function (event) {
|
|||
}
|
||||
|
||||
if ((this.options.autocomplete) && (!handled)) {
|
||||
if (!ctrlKey && !altKey && !metaKey) {
|
||||
if (!ctrlKey && !altKey && !metaKey && (event.key.length == 1 || keynum == 8 || keynum == 46)) {
|
||||
handled = false;
|
||||
if (event.target.className.indexOf("jsoneditor-field") < 0) {
|
||||
if ((this.options.autocomplete.ApplyTo.indexOf('values') >= 0 && event.target.className.indexOf("jsoneditor-value") >= 0) ||
|
||||
(this.options.autocomplete.ApplyTo.indexOf('name') >= 0 && event.target.className.indexOf("jsoneditor-field") >= 0)) {
|
||||
var node = Node.getNodeFromTarget(event.target);
|
||||
//if (event.target.innerText.startsWith('*')) {
|
||||
if (this.options.autocomplete.ActivationChar == null || event.target.innerText.startsWith(this.options.autocomplete.ActivationChar)) { // Activate autocomplete
|
||||
setTimeout(function (hnode, element) {
|
||||
if (element.innerText.length > 0)
|
||||
this.options.autocomplete.GetOptions(hnode, element, keynum);
|
||||
this.options.autocomplete.Show(hnode, element);
|
||||
else
|
||||
this.options.autocomplete.Hide();
|
||||
|
||||
}.bind(this, node, event.target), 100);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue