detect sentence based on cursor [duplicate] - javascript

This question already has an answer here:
contentEditable cursor's parent element
(1 answer)
Closed 4 years ago.
$("#paragraph").html("<span>The Faculty Development Programme would enable identification and preparation of relevant course transaction resources.</span><span> These resources include Reference Books, Films, PPTs, Case Lets and Case Studies Work Education, Experiential Learning and its various aspects, Village Project Work and Field Work and Preparation of Village Social and Resource Maps.</span>");
function detectSentence(){
//console.log("Iam here");
if (window.getSelection && (sel = window.getSelection()).modify) {
selection = window.getSelection();
selection.extend (selection.focusNode.parentNode, 0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div contenteditable="true" id="paragraph">
</div>
<br><br>
<button type="button" onclick="detectSentence()" id="btn">
Detect Sentence
</button>
I have a div which contains a paragraph, this paragraph can have more than 1 sentence. I am enclosing these sentences in a span tag, so that each sentence is separated. So sentence boundaries are already identified in the text. Now when the focus is anywhere in this div, is there a way to detect the sentence where the cursor belongs to.
I had tried using window.getSelection();, but couldn't attain a solution of how to use this method. My question is there a way to move the selection to the nearest opening and closing span tag surrounding the cursor so that the corresponding sentence will be highlighted where the cursor is present.
Using this snippet I am able to select text up to starting sentence tag but the ending sentence tag is not being highlighted. To test the snippet click anywhere in the div and click on the button Detect Sentence.

This code gives you the element cursor is on or element with selected content.
$("#paragraph").html("<span>The Faculty Development Programme would enable identification and preparation of relevant course transaction resources.</span><span> These resources include Reference Books, Films, PPTs, Case Lets and Case Studies Work Education, Experiential Learning and its various aspects, Village Project Work and Field Work and Preparation of Village Social and Resource Maps.</span>");
detectSentence = function(){
var node = document.getSelection().anchorNode;
sentenceElem = node.nodeType == 3 ? node.parentNode : node;
console.log(sentenceElem)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div contenteditable="true" id="paragraph">
</div>
<br><br>
<button type="button" onclick="detectSentence()" id="btn">
Detect Sentence
</button>

Related

Specific Webpage Word-Counter Needed with a Logical Semantic Twist and an exact placeholder

Context
The following question has NOT already an answer in Stack Overflow.
Based on many broad unspecific undetailed and ambiguous questions and many broader answers like here I have created a very specific and very precisely formulated question that, unlike the other broader questions on this site, have no space for ambiguity.
Problem
This question narrows down the quest for a logical word-count in a semantically different way and differs thus from other questions as well as it allows for precise and useful answer with a practical implemenatation anywhere on the page where one wants to count and or to show the counter after a preset delay, that relieves the code from causing any overhead while the words are still being fetched.
You are free to fork into the link above or the many many other works already wandering around elsewhere, and tweak it for your specific answer of this question.
You are free to use jQuery library 3.6.0 if you wish so make one with zero-dependencies on jQuery.
Starting point
Given the following HTML syntax, I would like to count the number of useful words in the <article> html element.
These could be a word starting from two characters up. The meaning of the English word a or o is nullified and not counted as a meaningful word! Only words from two characters up, need to be counted to reflect substance and valuable contents.
Include words in normal html tags like <p> <h1> <h2> <h3> <em> <i> <strong> <mark> or <td>.
Only elements that are <article> and inside a <section> or a <hgroup> should be counted. All else should be skipped.
Dashed-words can count as one word: the space around the words is the defining factor.
<article>
<hgroup>
<hr>word word word word word</h1>
</hgroup>
<something>Ignored Ignored</something>
<section>
<h2>word word word word word</h2>
<p>word word</p>
<p><em>Word Word word</em></p>
<p><i>Word Word word</i></p>
<p>word word</p>
<p><strong>Word Word word</strong></p>
<p><mark>Word Word word</mark></p>
<p>word word</p>
</section>
<something>Ignored Ignored</something>
<section>
<h3>word word word word word</h3>
<ul>
<li>word word word word</li>
<li>word word word word</li>
<li>word word word word</li>
</ul>
<p>word word</p>
<p>word word</p>
<table>...<td>Maandag</td><td>Dinsdag</td>...
</table>
<p>a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a</p>
</section>
</article>
Placement
The numer of words should then be written inside a prechosen html element, say for example <wordcount>...</wordcount>.
In the example above, the correct word count should be: ???
(15 for the three headings, 10 in unstyled paragraphs, 12 in styled elements and 12 in list items and 2 in table data.)
<wordcount>51</wordcount>

click event on each button of a class (chess viewer)

First time writing here. I am new to programming and here I am learning a lot of things!
Now, I want write this: for each clicked element of a class create a var with nextSibling's text and show it somewhere. The following code is for sure full of error, but it is what i thought:
//wants to create an accessible variable (even out the function)
//from a sibling element's text.
$(".games").click(function(){
myVar = this.next("p").html;})
the HTML situation is this:
<button class="games">GAME ONE</button><p> THESE ARE THE DETAILS OF THE GAME 1</p>
<button class="games">GAME TWO</button><p> THESE ARE THE DETAILS OF THE GAME 2</p>
<div id="show"> I will show the content of paragraphs here if one of the two buttons is clicked</div>
I thank everybody because - I repeat - I am learning a lot here.
EDIT
Thanks everybody for the answers. I am trying something related to your suggestions, but i think the problem should be another because actually I am working with chessJS and chessboardJS to make a page where show the moves of a chess game in a chessboard. But, when I try to say that myVar (where there is the moves list to pass to the chessJS function load_pgn) is the content of one id like this:
<p id="theGame">1. e4 e5</p>
// myVar contains the moves list
var myVar = $("#theGame").html();
Chess().load_pgn(myVar);
all works fine, but I cannot make it work by saying that: for each clicked element (of a class, maybe) myVar is the html value of the clicked element. Furthermore in the console I receive an error that says that pgn_replace is not a function.
<p class="someGames">1. e4 d5 2 Nf3 Nc6</p>
<p class="someGames">1.d4 e5</p>
Maybe I explained the fact a bit bad. this is it. Thank you again for the answers.
FINAL EDIT
Thanks to your answers and other discussions on the site I managed to find a solution to take the text of one element of a class and store in a var with the following code:
$('.class').click(function(){
this.textContent = $(this).html();
var myVar = $(this).html();})`
Thank you!
function buttonClick(button){
document.getElementById("show").innerHTML=button.innerHTML
}
<button class="games" onclick="buttonClick(this)">GAME ONE</button><p> THESE ARE THE DETAILS OF THE GAME 1</p>
<button class="games" onclick="buttonClick(this)">GAME TWO</button><p> THESE ARE THE DETAILS OF THE GAME 2</p>
<div id="show"> I will show the content of paragraphs here if one of the two buttons is clicked</div>
const button = document.querySelector(".games")
button.addEventListener('click', () => {
myText = document.querySelector('p').innerHTML = 'your text : I will show the content of paragraphs here if one of the two buttons is clicked '
)
<button class="games">GAME ONE</button><p> THESE ARE THE DETAILS OF THE GAME 1</p>
<button class="games">GAME TWO</button><p> THESE ARE THE DETAILS OF THE GAME 2</p>
<div id="show"> <p> I will show the content of paragraphs here if one of the two buttons is clicked </p></div>

Highlighting words across dom nodes

I have some messy html due to OCR that I need to highlight. Words are sometimes split between dom nodes. I need to search for any user input text and add a highlight span around wherever that text appears in the html.
Example
<div id="content">
<span>my birthday par<span>ty is today</span></span>
</div>
The search term here would be "birthday party". I have tried to regex but am unable to capture the right group.
(regex noob) new RegExp(`([${searchTerm}]+)!?<[^>]*>`, 'gi') which is producing ["y birthday pa<span>", "day</span>"]
I would need to capture something like my Birthday par<span>ty or the index of that so I can wrap it in another element to highlight.
Ideal outcome would be
<div id='content'>
<span>my<mark class='highlight'>birthday par<span>ty</mark> is today</span><span>
</div>
Thanks in advance!

how to get a word inside a text html and underline it? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a text inside an HTML tag <p>text</p>, then I have a <form> and a <input type="text"> inside and a submit.
The goal of the exercise: when I write characters in the input then I click on button (submit), or any other word, or not a complete word, or (,.!!),it has to be underlined with the red color in the text the space has not to be underlined .here s my code below :example I write "Anyone" then I submit, I mean the first word in the text , all the words "anyone" have to be underlined in red.
var x = document.getElementById('text').innerHTML;
var splt = x.split(/\W+/);
console.log(splt);
var inpt=document.getElementById('input').value;
console.log(inpt);
var lent = splt.length;
console.log(lent);
var myArray =[" "];
for( i = 0; i < splt.length ; i++ ){
myArray.push(splt[i]);
}
console.log(myArray);
for(var j=0;i<myArray.length;i++){
for(var k=0;k<myArray[i].length;k++){
if((myArray[j]==splt)){
}
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid">
<div class="row">
<div class="col-5">
<form class="form-group" action="index.html" method="post">
<input type="text" name="" value="" id ="input" onkeyup="find()" placeholder="cerca">
<button class ="Btn btn-danger" type="button" name="button">search</button>
</form>
<h1>hello</h1>
<p class="text-justify" id = "text">Anyone who reads Old and Middle English literary texts will be familiar with the mid-brown volumes of the EETS, with the symbol of Alfred's jewel embossed on the front cover. Most of the works attributed to King Alfred or to Aelfric, along with some of those by bishop Wulfstan and much anonymous prose and verse from the pre-Conquest period, are to be found within the Society's three series; all of the surviving medieval drama, most of the Middle English romances, much religious and secular prose and verse including the English works of John Gower, Thomas Hoccleve and most of Caxton's prints all find their place in the publications. Without EETS editions, study of medieval English texts would hardly be possible.</p>
<p class="text-justify" id = "text">As its name states, EETS was begun as a 'club', and it retains certain features of that even now. It has no physical location, or even office, no paid staff or editors, but books in the Original Series are published in the first place to satisfy subscriptions paid by individuals or institutions. This means that there is need for a regular sequence of new editions, normally one or two per year; achieving that sequence can pose problems for the Editorial Secretary, who may have too few or too many texts ready for publication at any one time. Details on a separate sheet explain how individual (but not institutional) members can choose to take certain back volumes in place of the newly published volumes against their subscriptions. On the same sheet are given details about the very advantageous discount available to individual members on all back numbers. In 1970 a Supplementary Series was begun, a series which only appears occasionally (it currently has 24 volumes within it); some of these are new editions of texts earlier appearing in the main series. Again these volumes are available at publication and later at a substantial discount to members. All these advantages can only be obtained through the Membership Secretary (the books are sent by post); they are not available through bookshops, and such bookstores as carry EETS books have only a very limited selection of the many published.</p>
</div>
</div>
</div>
function highLightText(){
var characters = $('#text');
var pageText = characters.text().replace("<span>","").replace("</span>");
var searchedText = $('#input').val();
var theRegEx = new RegExp("("+searchedText+")", "igm");
var newText = pageText.replace(theRegEx ,"<span>$1</span>");
characters.html(newText);
}
#text span
{
text-decoration: underline;
text-decoration-color: red;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SEARCH</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-5">
<input type="text" name="" value="" id ="input" onkeyup="find()" placeholder="cerca">
<button class ="Btn btn-danger" type="button" name="button" onclick="highLightText()">search</button>
<h1>hello</h1>
<p class="text-justify" id = "text">
Anyone who reads Old and Middle English literary texts will be familiar with the mid-brown volumes of the EETS, with the symbol of Alfred's jewel embossed on the front cover. Most of the works attributed to King Alfred or to Aelfric, along with some of those by bishop Wulfstan and much anonymous prose and verse from the pre-Conquest period, are to be found within the Society's three series; all of the surviving medieval drama, most of the Middle English romances, much religious and secular prose and verse including the English works of John Gower, Thomas Hoccleve and most of Caxton's prints all find their place in the publications. Without EETS editions, study of medieval English texts would hardly be possible.
As its name states, EETS was begun as a 'club', and it retains certain features of that even now. It has no physical location, or even office, no paid staff or editors, but books in the Original Series are published in the first place to satisfy subscriptions paid by individuals or institutions. This means that there is need for a regular sequence of new editions, normally one or two per year; achieving that sequence can pose problems for the Editorial Secretary, who may have too few or too many texts ready for publication at any one time. Details on a separate sheet explain how individual (but not institutional) members can choose to take certain back volumes in place of the newly published volumes against their subscriptions. On the same sheet are given details about the very advantageous discount available to individual members on all back numbers. In 1970 a Supplementary Series was begun, a series which only appears occasionally (it currently has 24 volumes within it); some of these are new editions of texts earlier appearing in the main series. Again these volumes are available at publication and later at a substantial discount to members. All these advantages can only be obtained through the Membership Secretary (the books are sent by post); they are not available through bookshops, and such bookstores as carry EETS books have only a very limited selection of the many published.
</p>
</p>
</div>
</div>
</div>
</body>
</html>
Reference
Alright! I tried in Vanilla JS. Have a look https://codepen.io/navdeepsingh/pen/bLjqyy``
const search = document.querySelector('#search');
const wrapper = document.querySelector('#wrapper');
const wrapperText = wrapper.innerHTML;
let newText = '';
search.addEventListener('keyup', function() {
const regex = new RegExp(this.value, 'g');
if (this.value.length > 3) {
if (wrapperText.includes(this.value)) {
newText = wrapperText.replace(regex, `<span class="hl">${this.value}</span>`);
wrapper.innerHTML = newText;
}
} else {
const hlElems = document.querySelectorAll(".hl");
hlElems.forEach(el => {
el.classList.remove('hl');
});
}
});
.hl {
background-color: gold;
}
<input type="text" placeholder="Search.." id="search" name="search" autofocus>
<div id="wrapper">
<p> It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
</p>
<p>There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.</p>
</div>

How to captured Selected Text Range in iOS after text selection expansion

I'm working on a web app that allows a user to select some text, click a button, and save the highlighted text. This works great in desktop browsers, (chrome for this example), but in iOS I'm having issues with the native text selection, where the user can change the selected text.
Here is the JsFiddle showing the issue (issue only exists in iOS): http://jsfiddle.net/JasonMore/gWZfb/
User starts text selection
User expands their text selection, and clicks "Show the selected text above"
Only the first selected word "The" shows up, even though I want "The Path of the righteous man"
1 Begin
2 Select Text and hit button
3 Only "The"
Here is the JS I am using:
$(function() {
$('#actionButton').click(function() {
$('#result').text(selectedRange.toString());
});
$('#slipsum').on('mouseup touchend','p', function() {
getSelectedRange();
});
});
var selectedRange = null;
var getSelectedRange = function() {
if (window.getSelection) {
selectedRange = window.getSelection().getRangeAt(0);
} else {
selectedRange = document.getSelection().getRangeAt(0);
}
};​
HTML:
<h3>Selected Text:</h3>
<p id="result">
</p>
<br/>
<p>
<input type="button" id="actionButton" value="Show the selected text above" />
</p>
<!-- start slipsum code -->
<div id="slipsum">
<h1>Is she dead, yes or no?</h1>
<p>Do you see any Teletubbies in here? Do you see a slender plastic tag clipped to my shirt with my name printed on it? Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it? No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb. </p>
<h1>So, you cold?</h1>
<p>The path of the righteous man is beset on all sides by the iniquities of the selfish and the tyranny of evil men. Blessed is he who, in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children. And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy My brothers. And you will know My name is the Lord when I lay My vengeance upon thee. </p>
<h1>I'm serious as a heart attack</h1>
<p>Do you see any Teletubbies in here? Do you see a slender plastic tag clipped to my shirt with my name printed on it? Do you see a little Asian child with a blank expression on his face sitting outside on a mechanical helicopter that shakes when you put quarters in it? No? Well, that's what you see at a toy store. And you must think you're in a toy store, because you're here shopping for an infant named Jeb. </p>
<h1>Is she dead, yes or no?</h1>
<p>Like you, I used to think the world was this great place where everybody lived by the same standards I did, then some kid with a nail showed me I was living in his world, a world where chaos rules not order, a world where righteousness is not rewarded. That's Cesar's world, and if you're not willing to play by his rules, then you're gonna have to pay the price. </p>
<h1>Is she dead, yes or no?</h1>
<p>Your bones don't break, mine do. That's clear. Your cells react to bacteria and viruses differently than mine. You don't get sick, I do. That's also clear. But for some reason, you and I react the exact same way to water. We swallow it too fast, we choke. We get some in our lungs, we drown. However unreal it may seem, we are connected, you and I. We're on the same curve, just on opposite ends. </p>
</div>
<!-- please do not remove this line -->
<div style="display:none;">
lorem ipsum</div>
<!-- end slipsum code -->
​
To anyone who stumbles upon this issue in the future, here is the resolution:
http://jsfiddle.net/JasonMore/gWZfb/
$(function() {
$('#actionButton').click(function() {
if (selectedRange) {
$('#result').text(selectedRange.toString());
clearInterval(timer);
}
});
timer = setInterval(getSelectedRange, 150);
});
var timer = null;
var selectedRange = null;
var getSelectedRange = function() {
try {
if (window.getSelection) {
selectedRange = window.getSelection().getRangeAt(0);
} else {
selectedRange = document.getSelection().getRangeAt(0);
}
} catch (err) {
}
};​

Categories

Resources