Autocomplete final refactory
This commit is contained in:
parent
131e8f106d
commit
1393b148db
|
@ -25,7 +25,7 @@
|
||||||
*
|
*
|
||||||
* @author Jos de Jong, <wjosdejong@gmail.com>
|
* @author Jos de Jong, <wjosdejong@gmail.com>
|
||||||
* @version 5.6.0
|
* @version 5.6.0
|
||||||
* @date 2017-04-15
|
* @date 2017-05-16
|
||||||
*/
|
*/
|
||||||
(function webpackUniversalModuleDefinition(root, factory) {
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
if(typeof exports === 'object' && typeof module === 'object')
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
@ -164,7 +164,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
// validate options
|
// validate options
|
||||||
if (options) {
|
if (options) {
|
||||||
var VALID_OPTIONS = [
|
var VALID_OPTIONS = [
|
||||||
'ace', 'theme',
|
'ace', 'theme','autocomplete',
|
||||||
'ajv', 'schema',
|
'ajv', 'schema',
|
||||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||||
|
@ -485,6 +485,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
var ModeSwitcher = __webpack_require__(11);
|
var ModeSwitcher = __webpack_require__(11);
|
||||||
var util = __webpack_require__(4);
|
var util = __webpack_require__(4);
|
||||||
|
|
||||||
|
|
||||||
// create a mixin with the functions for tree mode
|
// create a mixin with the functions for tree mode
|
||||||
var treemode = {};
|
var treemode = {};
|
||||||
|
|
||||||
|
@ -583,7 +584,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
history: true,
|
history: true,
|
||||||
mode: 'tree',
|
mode: 'tree',
|
||||||
name: undefined, // field name of root node
|
name: undefined, // field name of root node
|
||||||
schema: null
|
schema: null,
|
||||||
|
autocomplete: null
|
||||||
};
|
};
|
||||||
|
|
||||||
// copy all options
|
// copy all options
|
||||||
|
@ -1527,7 +1529,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
*/
|
*/
|
||||||
treemode._onKeyDown = function (event) {
|
treemode._onKeyDown = function (event) {
|
||||||
var keynum = event.which || event.keyCode;
|
var keynum = event.which || event.keyCode;
|
||||||
|
var altKey = event.altKey;
|
||||||
var ctrlKey = event.ctrlKey;
|
var ctrlKey = event.ctrlKey;
|
||||||
|
var metaKey = event.metaKey;
|
||||||
var shiftKey = event.shiftKey;
|
var shiftKey = event.shiftKey;
|
||||||
var handled = false;
|
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) {
|
if (handled) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
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>
|
* @author Jos de Jong, <wjosdejong@gmail.com>
|
||||||
* @version 5.6.0
|
* @version 5.6.0
|
||||||
* @date 2017-04-15
|
* @date 2017-05-16
|
||||||
*/
|
*/
|
||||||
(function webpackUniversalModuleDefinition(root, factory) {
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
if(typeof exports === 'object' && typeof module === 'object')
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
@ -164,7 +164,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
// validate options
|
// validate options
|
||||||
if (options) {
|
if (options) {
|
||||||
var VALID_OPTIONS = [
|
var VALID_OPTIONS = [
|
||||||
'ace', 'theme',
|
'ace', 'theme','autocomplete',
|
||||||
'ajv', 'schema',
|
'ajv', 'schema',
|
||||||
'onChange', 'onEditable', 'onError', 'onModeChange',
|
'onChange', 'onEditable', 'onError', 'onModeChange',
|
||||||
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
'escapeUnicode', 'history', 'search', 'mode', 'modes', 'name', 'indentation', 'sortObjectKeys'
|
||||||
|
@ -8514,6 +8514,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
var ModeSwitcher = __webpack_require__(12);
|
var ModeSwitcher = __webpack_require__(12);
|
||||||
var util = __webpack_require__(5);
|
var util = __webpack_require__(5);
|
||||||
|
|
||||||
|
|
||||||
// create a mixin with the functions for tree mode
|
// create a mixin with the functions for tree mode
|
||||||
var treemode = {};
|
var treemode = {};
|
||||||
|
|
||||||
|
@ -8612,7 +8613,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
history: true,
|
history: true,
|
||||||
mode: 'tree',
|
mode: 'tree',
|
||||||
name: undefined, // field name of root node
|
name: undefined, // field name of root node
|
||||||
schema: null
|
schema: null,
|
||||||
|
autocomplete: null
|
||||||
};
|
};
|
||||||
|
|
||||||
// copy all options
|
// copy all options
|
||||||
|
@ -9556,7 +9558,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
||||||
*/
|
*/
|
||||||
treemode._onKeyDown = function (event) {
|
treemode._onKeyDown = function (event) {
|
||||||
var keynum = event.which || event.keyCode;
|
var keynum = event.which || event.keyCode;
|
||||||
|
var altKey = event.altKey;
|
||||||
var ctrlKey = event.ctrlKey;
|
var ctrlKey = event.ctrlKey;
|
||||||
|
var metaKey = event.metaKey;
|
||||||
var shiftKey = event.shiftKey;
|
var shiftKey = event.shiftKey;
|
||||||
var handled = false;
|
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) {
|
if (handled) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3,12 +3,8 @@
|
||||||
<head>
|
<head>
|
||||||
<title>JSONEditor | Custom styling</title>
|
<title>JSONEditor | Custom styling</title>
|
||||||
|
|
||||||
|
|
||||||
<link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
|
<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="../dist/jsoneditor.js"></script>
|
||||||
<!--<script src="horsey.js"></script>-->
|
|
||||||
<script src="../src/js/autocomplete.js"></script>
|
|
||||||
|
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
#jsoneditor {
|
#jsoneditor {
|
||||||
|
@ -38,69 +34,8 @@
|
||||||
<script>
|
<script>
|
||||||
// create the editor
|
// create the editor
|
||||||
var container = document.getElementById('jsoneditor');
|
var container = document.getElementById('jsoneditor');
|
||||||
var pv = completely({
|
|
||||||
fontSize: '10pt',
|
|
||||||
fontFamily: 'droid sans mono, consolas, monospace, courier new, courier, sans-serif'
|
|
||||||
});
|
|
||||||
var options = {
|
var options = {
|
||||||
modes: ['text', 'tree'],
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
var json = {
|
var json = {
|
||||||
'array': [1, 2, 3],
|
'array': [1, 2, 3],
|
||||||
|
|
|
@ -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';
|
'use strict';
|
||||||
|
|
||||||
function completely(config) {
|
function autocomplete(config) {
|
||||||
config = config || {};
|
config = config || {};
|
||||||
config.fontSize = config.fontSize || '16px';
|
config.fontSize = config.fontSize || '16px';
|
||||||
config.fontFamily = config.fontFamily || 'sans-serif';
|
config.fontFamily = config.fontFamily || 'sans-serif';
|
||||||
|
@ -171,7 +171,6 @@ function completely(config) {
|
||||||
onArrowUp: function () { }, // defaults to no action.
|
onArrowUp: function () { }, // defaults to no action.
|
||||||
onEnter: function () { }, // defaults to no action.
|
onEnter: function () { }, // defaults to no action.
|
||||||
onTab: function () { }, // defaults to no action.
|
onTab: function () { }, // defaults to no action.
|
||||||
onChange: function () { }, // defaults to repainting.
|
|
||||||
startFrom: 0,
|
startFrom: 0,
|
||||||
options: [],
|
options: [],
|
||||||
element: null,
|
element: null,
|
||||||
|
@ -213,11 +212,6 @@ function completely(config) {
|
||||||
this.elementHint.style.color = config.hintColor;
|
this.elementHint.style.color = config.hintColor;
|
||||||
this.elementHint.onfocus = function () { this.element.focus(); }.bind(this);
|
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) {
|
if (this.element.addEventListener) {
|
||||||
this.element.removeEventListener("keydown", keyDownHandler);
|
this.element.removeEventListener("keydown", keyDownHandler);
|
||||||
this.element.addEventListener("keydown", keyDownHandler, false);
|
this.element.addEventListener("keydown", keyDownHandler, false);
|
||||||
|
@ -243,12 +237,13 @@ function completely(config) {
|
||||||
if (this.elementHint) {
|
if (this.elementHint) {
|
||||||
this.elementHint.remove();
|
this.elementHint.remove();
|
||||||
this.elementHint = null;
|
this.elementHint = null;
|
||||||
}
|
|
||||||
dropDownController.hide();
|
dropDownController.hide();
|
||||||
this.element.style.zIndex = this.elementStyle.zIndex;
|
this.element.style.zIndex = this.elementStyle.zIndex;
|
||||||
this.element.style.position = this.elementStyle.position;
|
this.element.style.position = this.elementStyle.position;
|
||||||
this.element.style.backgroundColor = this.elementStyle.backgroundColor;
|
this.element.style.backgroundColor = this.elementStyle.backgroundColor;
|
||||||
this.element.style.borderColor = this.elementStyle.borderColor;
|
this.element.style.borderColor = this.elementStyle.borderColor;
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
repaint: function (element) {
|
repaint: function (element) {
|
||||||
var text = element.innerText;
|
var text = element.innerText;
|
||||||
|
@ -270,7 +265,6 @@ function completely(config) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// moving the dropDown and refreshing it.
|
// moving the dropDown and refreshing it.
|
||||||
dropDown.style.left = calculateWidthForText(leftSide) + 'px';
|
dropDown.style.left = calculateWidthForText(leftSide) + 'px';
|
||||||
dropDownController.refresh(token, this.options);
|
dropDownController.refresh(token, this.options);
|
||||||
|
@ -284,7 +278,7 @@ function completely(config) {
|
||||||
var dropDownController = createDropDownController(dropDown, rs);
|
var dropDownController = createDropDownController(dropDown, rs);
|
||||||
|
|
||||||
var keyDownHandler = function (e) {
|
var keyDownHandler = function (e) {
|
||||||
console.log("Keydown:" + e.keyCode);
|
//console.log("Keydown:" + e.keyCode);
|
||||||
e = e || window.event;
|
e = e || window.event;
|
||||||
var keyCode = e.keyCode;
|
var keyCode = e.keyCode;
|
||||||
|
|
||||||
|
@ -294,32 +288,28 @@ function completely(config) {
|
||||||
if (keyCode == 34) { return; } // page down (do nothing);
|
if (keyCode == 34) { return; } // page down (do nothing);
|
||||||
|
|
||||||
if (keyCode == 27) { //escape
|
if (keyCode == 27) { //escape
|
||||||
dropDownController.hide();
|
rs.hideDropDown();
|
||||||
this.elementHint.innerText = this.element.innerText; // ensure that no hint is left.
|
rs.element.focus();
|
||||||
this.element.focus();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyCode == 39 || keyCode == 35 || keyCode == 9) { // right, end, tab (autocomplete triggered)
|
if (keyCode == 39 || keyCode == 35 || keyCode == 9 || keyCode == 190) { // 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
|
if (keyCode == 9) {
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
if (this.elementHint.innerText.length == 0) {
|
if (this.elementHint.innerText.length == 0) {
|
||||||
rs.onTab(); // tab was called with no action.
|
rs.onTab();
|
||||||
// users might want to re-enable its default behaviour or handle the call somehow.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.elementHint.innerText.length > 0) { // if there is a hint
|
if (this.elementHint.innerText.length > 0) { // if there is a hint
|
||||||
dropDownController.hide();
|
|
||||||
if (this.element.innerText != this.elementHint.innerText) {
|
if (this.element.innerText != this.elementHint.innerText) {
|
||||||
this.element.innerText = this.elementHint.innerText;
|
this.element.innerText = this.elementHint.innerText;
|
||||||
|
rs.hideDropDown();
|
||||||
setEndOfContenteditable(this.element);
|
setEndOfContenteditable(this.element);
|
||||||
var hasTextChanged = registerOnTextChangeOldValue != this.element.innerText
|
if (keyCode == 9) {
|
||||||
registerOnTextChangeOldValue = this.element.innerText; // <-- to avoid dropDown to appear again.
|
rs.element.focus();
|
||||||
// for example imagine the array contains the following words: bee, beef, beetroot
|
e.preventDefault();
|
||||||
// user has hit enter to get 'bee' it would be prompted with the dropDown again (as beef and beetroot also match)
|
e.stopPropagation();
|
||||||
if (hasTextChanged) {
|
|
||||||
rs.onChange(this.element.innerText); // <-- forcing it.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -334,24 +324,17 @@ function completely(config) {
|
||||||
dropDownController.hide();
|
dropDownController.hide();
|
||||||
|
|
||||||
if (wasDropDownHidden) {
|
if (wasDropDownHidden) {
|
||||||
this.elementHint.innerText = this.element.innerText; // ensure that no hint is left.
|
rs.hideDropDown();
|
||||||
this.element.focus();
|
rs.element.focus();
|
||||||
rs.onEnter();
|
rs.onEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.element.innerText = this.elementHint.innerText;
|
this.element.innerText = this.elementHint.innerText;
|
||||||
var hasTextChanged = registerOnTextChangeOldValue != this.element.innerText
|
rs.hideDropDown();
|
||||||
registerOnTextChangeOldValue = this.element.innerText; // <-- to avoid dropDown to appear again.
|
setEndOfContenteditable(this.element);
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setEndOfContenteditable(this.element);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -378,51 +361,18 @@ function completely(config) {
|
||||||
|
|
||||||
var onBlurHandler = function (e) {
|
var onBlurHandler = function (e) {
|
||||||
rs.hideDropDown();
|
rs.hideDropDown();
|
||||||
|
//console.log("Lost focus.");
|
||||||
}.bind(rs);
|
}.bind(rs);
|
||||||
|
|
||||||
dropDownController.onmouseselection = function (text, rs) {
|
dropDownController.onmouseselection = function (text, rs) {
|
||||||
rs.element.innerText = rs.elementHint.innerText = leftSide + text;
|
rs.element.innerText = rs.elementHint.innerText = leftSide + text;
|
||||||
rs.hideDropDown();
|
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;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ var ContextMenu = require('./ContextMenu');
|
||||||
var Node = require('./Node');
|
var Node = require('./Node');
|
||||||
var ModeSwitcher = require('./ModeSwitcher');
|
var ModeSwitcher = require('./ModeSwitcher');
|
||||||
var util = require('./util');
|
var util = require('./util');
|
||||||
var Autocomplete = require('./autocomplete');
|
|
||||||
|
|
||||||
// create a mixin with the functions for tree mode
|
// create a mixin with the functions for tree mode
|
||||||
var treemode = {};
|
var treemode = {};
|
||||||
|
@ -1102,19 +1102,20 @@ treemode._onKeyDown = function (event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.options.autocomplete) && (!handled)) {
|
if ((this.options.autocomplete) && (!handled)) {
|
||||||
if (!ctrlKey && !altKey && !metaKey) {
|
if (!ctrlKey && !altKey && !metaKey && (event.key.length == 1 || keynum == 8 || keynum == 46)) {
|
||||||
handled = false;
|
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);
|
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) {
|
setTimeout(function (hnode, element) {
|
||||||
if (element.innerText.length > 0)
|
if (element.innerText.length > 0)
|
||||||
this.options.autocomplete.GetOptions(hnode, element, keynum);
|
this.options.autocomplete.Show(hnode, element);
|
||||||
else
|
else
|
||||||
this.options.autocomplete.Hide();
|
this.options.autocomplete.Hide();
|
||||||
|
|
||||||
}.bind(this, node, event.target), 100);
|
}.bind(this, node, event.target), 100);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue