Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: hknmtt 18. 08. 2024, 13:07:29
-
Mam textareu do ktorej implementujem doplnanie uzivatelskych mien s automatickym doplnanim - ked uzivatel napise '@' tak sa mu zobrazi mini input a zoznam zhodnych mien, z ktorych si moze vybrat.
Problem ktory riesim je pozicia tohto popupu. Textarea totiz moze scrollovat, uzivatel moze byt na ktoromkolvek riadku a akejkolvek vzdialenosti od zaciatku riadku. Takze najst spravne koordinaty pre ten popup je dost problem.
Pozeral som rozne riesenia, ktore na pozadi vygeneruju tu textareu do skryteho divu a odtial nejak hladaju poziciu ale to sa mi moc nepozdava.
Potreboval by som skor nieco co vie zistit poziciu textarei na obrazovke, spravne urcit ktora cast je viditelna a ktora nie je podla rozmerov, v pripade scrollovania, na ktorom riadku je uzivatel a na ktorej pozicii v riadku je a takto spocitat nejake absolutne koordinaty. Proste idealne ak by slo zistit absolutnu poziciu kurzoru(nie mysi) na obrazovke.
Neriesili ste to niekto? Nechce sa mi s tym stracat privela casu ale je to dost dolezite z hladiska UX.
-
nehlidal bych scroll, ani pozice, ani velikosti, jen bych hlidal text uvnitr textfieldu.
nejjednodussi by bylo pri kazdem eventu vkladani/smazani pismene v textfieldu sledovat zmenu v textu, event musi byt zpracovan rychle, takze kontrola treba regexpem, zda ma smysl dohledavat. kdyz ne tak hned vyskocit z eventu, pokud text necemu vyhledanemu odpovida, tak jej doplnit.
-
to uz robim, sledujem ci nebol vlozeny '@' a vtedy otvorim popup. ale otazka sa tykala niecoho ineho, ze..
-
to uz robim, sledujem ci nebol vlozeny '@' a vtedy otvorim popup. ale otazka sa tykala niecoho ineho, ze..
proc neceho jineho? kdyz budes resit jen vnitrni text, tak muzes jen hlidat text, pripadne doplnovat do textu a hotovo. scrollovani, rozmery te nezajimaji, kdyz jen zanalyzujes vnitrni text, pripadne ho doplnis a zase ho cely vlozis do textarea, a nic jineho neresis. zadna popup nemusis vkladat kdyz pro dany text vyberes a vlozis jen nejdelsi odpovidajici vyhledany string.
-
kdyz napise karel a mam moznosti karel1@prvni.cz, karel@mistnisdruzenihasicu.cz, karel22@aaa.cz tak ja bych nedal zadny popup, ale vlozil bych nejdelsi string karel@mistnisdruzenihasicu.cz
-
nebo muzes mit i serverovou statistiku nejcastejsich uzivatelu a kombinovat vyhledavani se vzorem a nejcastejsi uzivatel.
-
Nemusíš z toho dělat úplně kontextovou nabídku/menu, ale zkusit něco jako Android klávesnice, která nejpravděpodobnější pokračování (slova) nabízí v řádku nad klávesnici.
-
Sorry, něco jsem přehlédl. (Dá se tu mazat?)
-
Zeptal jsem se AI a a ta navrhla následující řešení:
- vytvořit si skrytý div se stejnými vlastnostmi jako má textarea
- zkopírovat do něj text až ke znaku, který v daný moment spustil akci (@)
- vložit místo něj nebo za něj nějaký html element (např span) a zjistit si pozici tohoto vloženého elementu v rámci divu
- s touto zjištěnou pozicí se pak vrátit k původní textarea
navržený kód (netestovaný):
<textarea id="myTextarea" rows="10" cols="30"></textarea>
<div id="caret-helper" style="position: absolute; visibility: hidden; white-space: pre-wrap;"></div>
<script>
function getCaretCoordinates(textarea, position) {
const helper = document.getElementById('caret-helper');
// Zkopírujeme text do pomocného elementu
helper.style.width = textarea.offsetWidth + "px";
helper.style.font = window.getComputedStyle(textarea).font;
helper.style.lineHeight = window.getComputedStyle(textarea).lineHeight;
helper.style.padding = window.getComputedStyle(textarea).padding;
helper.style.border = window.getComputedStyle(textarea).border;
// Nahrazení textu až do kurzoru a přidání speciálního markeru
const text = textarea.value.substring(0, position);
helper.textContent = text;
// Přidáme speciální znak jako kurzor
const marker = document.createElement('span');
marker.textContent = "\u200b"; // Zero-width space character
helper.appendChild(marker);
const rect = marker.getBoundingClientRect();
const textareaRect = textarea.getBoundingClientRect();
// Vrátí souřadnice relativní k textarea + zahrnutí scrollování
return {
x: rect.left - textareaRect.left + textarea.scrollLeft,
y: rect.top - textareaRect.top + textarea.scrollTop
};
}
document.getElementById('myTextarea').addEventListener('input', function(event) {
const textarea = event.target;
const position = textarea.selectionStart;
const coordinates = getCaretCoordinates(textarea, position);
console.log('Caret coordinates:', coordinates.x, coordinates.y);
});
</script>
-
Tohle na mě působí jako prvek z wysiwyg. A jejich DIY implementace v JS jde použít jako učebnicový příklad "vždyť to bude jen malá blbost, to bude hned," a o měsíc později projekt pořád stojí a "malá blbost" stále nefunguje. (Z vlastní zkušenosti.)
Vykašlal bych se na vynalézání parníku, a použil hotové řešení, jako tinymce (https://www.tiny.cloud/blog/how-to-configure-the-autocompleter-api-card-menu-items/).
-
Zkuz pouzit JS komponentu typu Editor, ktera je pro tyto ucely delana.
Napr Quill a jeho metodu getBounds()
https://quilljs.com/docs/api#getbounds
-
Tak sa zda ze to stale nejde. Jedine tym hackom. Ratal som ze html uz trochu pokrocilo, od kedy som to tiez riesil pred par rokmi, ale ocividne nie.
Mozno keby sa namiesto textarei rovno pouzil div a contenteditable, tak vlastne ten hack by mohol byt priamo sucastou logiky. Niekedy v buducne to skusim, aktualne to nie je take dolezite.
Inak tie vase rady ze mam pouzit nejaky externy wysiwyg su naozaj zabavne. Tu chodit po programatorske rady je naozaj ako zajazd do lunaparku.
-
Inak tie vase rady ze mam pouzit nejaky externy wysiwyg su naozaj zabavne. Tu chodit po programatorske rady je naozaj ako zajazd do lunaparku.
a neni taky lunapark tvrdit, kaslu na knihovny, vsecko si napisu sam na zelene louce?! :-)
-
Inak tie vase rady ze mam pouzit nejaky externy wysiwyg su naozaj zabavne. Tu chodit po programatorske rady je naozaj ako zajazd do lunaparku.
Ehm? Dostal jsi tip na knihovnu, která má to, co chceš, naimplementované, abys nemusel strávit léto něčím, co velmi pravděpodobně nemá jednoduché párřádkové řešení tak, jak sis ho představoval. To je zcela validní odpověď.
Ale pokud se ti to zdá příliš povrchní a koláčo-pojídačské a očekáváš jako řešení pár set řádků javascriptu, tak se omlouvám. Zřejmě ten web taky provozuješ na websereru, který sis napsal sám ve strojovém kódu. Protože přece bys nepoužil nějaký externí server jako Apache nebo nginx, nebo externí jazyk jako C či Java.
-
Jsi ošklivý mlékaři Dane. ;D
On už to má celé hotové, funkční, jen tam chtěl přidat jednu drobnou nedůležitou funkci, která by trochu zpříjemnila používání a ty mu do toho házíš vidle návrhem na implementaci VYSIWYG editoru s funkcí autocomplete.
-
Předpokládejme že textarea je v objektu el.
Pomocí metod el.selectionStart a el.selectionEnd získáš pozici kurzoru v indexech znaků.
Pomocí el.scrollTop a el.scrollLeft získáš v pixelech nascrollování obsahu v rámci textarei.
Pomocí window.getComputedStyle(el).fontSize získáš velikost písma obsahu. (Možná ještě padding, a další věci?)
Následně si můžeš spočítat, že pozice 300 je na 25 řádku (počet \n). Krát velikost písma. Mínus el.scrollLeft.
Asi by to šlo. Jak moc je to patlárna a zda tam není nějaký podraz, co mi unikl, netuším.
-
Zalamování se neděje jen na \n
Může být použit font s proporcionální šířkou znaků
-
Zalamování se neděje jen na \n
Může být použit font s proporcionální šířkou znaků
Je to tak. Proto se tu navrhoval způsob s tím neviditelným divem.
Vzhledem k tomu, že tazatel neměl zájem k hotovému řešení, tak jsem nastínil zábavu.