I'm creating autocomplete feature for my own low level program executor.I need to get the autocomplete values near the alphabet typed like in VScode and other IDEs. But I have a problem with resizing it. I need to get the box once I type in the word in textarea for each and every word near it.
Here is my html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<style>
.ui-autocomplete {
width:140px !important;
top: 50px !important;
}
</style>
<script>
$(function () {
console.log("hi");
var availableTags = ["SET","ADD","MUL","SUB","DIV","MOD","LOOP","ENDLOOP","IF","ENDIF","ELSE","ENDELSE","END"];
function split( val ) {
return val.split( / \s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" ).bind( "keydown", function( event ) {
//can also use this to track when user presses SPACE
if(event.which===32)
$('#characterSpan').html($(this).val());
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "autocomplete" ).menu.active ) {
event.preventDefault();
}
}),
$( "#tags" ).autocomplete({
minLength: 1,
source: function( request, response ) {
response( $.ui.autocomplete.filter(
availableTags, extractLast( request.term ) ) );
},
focus: function() {
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( " " );
this.value = terms.join(" ");
//when item selected, add current value to span
//$('#characterSpan').html($(this).val());
return false;
},
open: function( event, ui ) {
$('.ui-autocomplete.ui-menu');
},
open: function() {
var position = window.getSelection().getRangeAt(0).startOffset;
var cursorPos= $("#tags").prop('selectionStart');
$("ul.ui-menu").width();
}
});
});
</script>
<title>Document</title>
</head>
<body>
<div id="menu-container" style="position:absolute; width: 500px;">
<label for="tags">Tag programming languages: </label>
<textarea id="tags" rows="20" cols="70"></textarea>
<span id="characterSpan" style="visibility: hidden;"></span>
</div>
</body>
</html>
CodePudding user response:
In these lines:
$(".ui-autocomplete").css("left", getCursorPos($("#tags")[0]) * 7.5 7.5 "px");
$(".ui-autocomplete").css("top", getLineNumber($("#tags")[0]) * 15 30 "px");
I'm assuming 7.5px as starting horizontal position and 7.5px the width of each letter, vertically 30px as starting position and 15px the height of each letter. I also used two functions from this answer to get the cursor position.
function getLineNumber(tArea) {
return tArea.value.substr(0, tArea.selectionStart).split("\n").length;
}
function getCursorPos(me) {
var el = $(me).get(0);
var pos = 0;
if ("selectionStart" in el) {
pos = el.selectionStart;
} else if ("selection" in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart("character", -el.value.length);
pos = Sel.text.length - SelLength;
}
var ret = pos - prevLine(me);
return ret;
}
function prevLine(me) {
var lineArr = me.value.substr(0, me.selectionStart).split("\n");
var numChars = 0;
for (var i = 0; i < lineArr.length - 1; i ) {
numChars = lineArr[i].length 1;
}
return numChars;
}
$(function () {
console.log("hi");
var availableTags = [
"SET",
"ADD",
"MUL",
"SUB",
"DIV",
"MOD",
"LOOP",
"ENDLOOP",
"IF",
"ENDIF",
"ELSE",
"ENDELSE",
"END",
];
function split(val) {
return val.split(/ \s*/);
}
function extractLast(term) {
return split(term).pop();
}
$("#tags").bind("keydown", function (event) {
//can also use this to track when user presses SPACE
if (event.which === 32) $("#characterSpan").html($(this).val());
if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
event.preventDefault();
}
}),
$("#tags").autocomplete({
minLength: 1,
source: function (request, response) {
response($.ui.autocomplete.filter(availableTags, extractLast(request.term)));
$(".ui-autocomplete").css("left", getCursorPos($("#tags")[0]) * 7.5 7.5 "px");
$(".ui-autocomplete").css("top", getLineNumber($("#tags")[0]) * 15 30 "px");
},
focus: function () {
return false;
},
select: function (event, ui) {
/* var terms = split(this.value);
terms.pop();
terms.push(ui.item.value);
terms.push(" ");
this.value = terms.join(" "); */
this.value = this.value ui.item.value;
return false;
},
open: function (event, ui) {
$(".ui-autocomplete.ui-menu");
},
open: function () {
var position = window.getSelection().getRangeAt(0).startOffset;
var cursorPos = $("#tags").prop("selectionStart");
$("ul.ui-menu").width();
},
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<style>
.ui-autocomplete {
width: 140px !important;
/* top: 50px !important; */
}
</style>
<title>Document</title>
</head>
<body>
<div id="menu-container" style="position: absolute; width: 500px">
<label for="tags">Tag programming languages: </label>
<textarea id="tags" rows="20" cols="70"></textarea>
<span id="characterSpan" style="visibility: hidden"></span>
</div>
</body>
</html>