How to detect clicked word in textarea with right click and show menu items from php sql database in in context menu in return of clicked word
We want to design roman transliteration with same pattern of google translation in this regard plz help us. We want two text boxes (Textareas) in one text box user write some text and click a button then the data will be transliterated in other box till this point its easy but we want user can change trnasliterated word with right click menu with various options. this is same like spell checker.

Dani AI

Generated

What you want is easier if the transliterated output is not a plain <textarea>. For a spell-check style UX, render the result as a contenteditable container where each token is wrapped in a span. Then you can right-click exactly the word you need, fetch alternatives from PHP/MySQL, and swap the text in place. It also lets you keep a stable link back to the original source token (@diafol hinted at this with the alt idea).

Minimal pattern:

<div id="out" contenteditable="true"></div>
<ul id="menu" hidden></ul>

<script>
function render(tokens){
  // tokens: [{id: 42, main:"Ch", src:"\u0416"}, ...]
  out.innerHTML = tokens.map(t => `<span class="tok" data-id="${t.id}" data-src="${t.src}">${t.main}</span>`).join(' ');
}

const out = document.getElementById('out');
const menu = document.getElementById('menu');

out.addEventListener('contextmenu', async (e) => {
  const tok = e.target.closest('.tok');
  if (!tok) return;
  e.preventDefault();
  const r = await fetch('/alts.php?src=' + encodeURIComponent(tok.dataset.src));
  const alts = await r.json(); // e.g. ["Zh","J","Z"]
  menu.innerHTML = alts.map(a => `<li data-val="${a}">${a}</li>`).join('');
  Object.assign(menu.style, {position:'fixed', left:e.clientX+'px', top:e.clientY+'px'});
  menu.hidden = false;

  const onPick = ev => {
    const li = ev.target.closest('li'); if (!li) return;
    tok.textContent = li.dataset.val; menu.hidden = true;
    document.removeEventListener('click', onOutside);
  };
  const onOutside = () => (menu.hidden = true, menu.onclick = null);
  menu.onclick = onPick; document.addEventListener('click', onOutside, {once:true});
});
</script>

If you must stay with a <textarea>, grab the word around the caret and build the same menu:

ta.addEventListener('contextmenu', (e) => {
  e.preventDefault();
  const i = ta.selectionStart, s = ta.value;
  const L = s.slice(0,i).search(/\S+$/); const R = s.slice(i).search(/\s/);
  const word = s.slice(L < 0 ? 0 : L, R < 0 ? s.length : i + R);
  // fetch('/alts.php?q=' + encodeURIComponent(word)) ...
});

Tip: store a token id with each output word so you can map user picks back to the original text reliably even when lengths differ.

Recommended Answers

All 2 Replies

Member Avatar for Member #120589

Show your code so far. Which alphabets/codes do you want to support? When you say transliteration, I'm assuming that you don't mean translation too - just something to transform â -> a etc.

Member Avatar for Member #120589

Here's a php script of mine I tried to port to js...

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Transliteration Service</title>
</head>

<body>
<form>
    <textarea id="source" onKeyUp="translit();" >АБВ</textarea>
    <textarea id="result" ></textarea>
</form>

<script>
var data =
    {
        "1040":{"char":"А", "main":"A"},
        "1041":{"char":"Б", "main":"B", "alt": ["W"]},
        "1042":{"char":"В", "main":"V"},
        "1043":{"char":"Г", "main":"G"},
        "1044":{"char":"Д", "main":"D"},
        "1045":{"char":"Е", "main":"E"},
        "1046":{"char":"Ж", "main":"Ch"},
        "1048":{"char":"И", "main":"I"},
        "1050":{"char":"К", "main":"K"},
        "1051":{"char":"Л", "main":"L"}
    };

    function translit()
    {
        var source = document.getElementById('source');
        var result = document.getElementById('result');
        var str = source.value;
        var len = str.length;
        var n = '';
        var val = '';
        for(i=0;i<len;i++)
        {
            var num = str.charCodeAt(i);
            val = (data[num] != undefined) ? data[num]['main'] : val = str.charAt(i);
            n += val;
        }
        result.value = n;   
    }

   document.getElementById('source').ondblclick = function () {
   var sel = (document.selection && document.selection.createRange().text) ||
             (window.getSelection && window.getSelection().toString());
   alert(sel);
};
</script>
</body>
</html>

References:
Double click event: http://stackoverflow.com/questions/2281426/how-to-get-selected-word-when-double-click-on-div-p-span

Without writing the whole thing, you can use the 'alt' array for the character if it exists for the list - however, this may be overkill if many characters have alts as the number of permutations could be large. In addition, doing this on the 'result' box is more of a challenge as it would need to reference back to the original 'source' - and due to the fact that you have 2 editable textboxes, there's no guaranteed way of "linking words"

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.