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

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) {
}
};​

Related

Bold the selected text

I have an HTML5 file and I am trying to make an app like Google Docs using create-electron-app.
I have a textarea tag for the input, and I am trying to bold the text the user has selected. I have the getSelectedText() function working and It is returning a string like expected, but I need to bold that text inside of the textarea. If you have used Google Docs you should know what I mean.
Here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Make word documents!</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<textarea class="userInput"></textarea>
<input type="button"
value="Bold"
onmousedown="bold()">
<script>
function getSelectedText() {
if (window.getSelection) {
return "" + window.getSelection();
} else if (document.selection && document.selection.type == "Text") {
return document.selection.createRange().text;
}
return "";
}
function bold() {
var userInput = getSelectedText();
// userInput.style.fontWeight = "bold";
// print the type of the userinput variable
console.log(typeof userInput);
}
</script>
</body>
</html>
It isn't possible to bold text inside of a textarea, however, it is possible to bold text inside of a div.
A div can behave like a textarea by setting it to contentEditable -- <div contentEditable></div>.
Conveniently, Javascript has a built in function to bold selected text, document.execCommand("bold").
By using both editable divs and Javascript built in functions, it is possible to create an app like Google Docs that can bold selected text.
document.getElementById("bold_button").onclick = function() {
document.execCommand("bold");
}
<div contentEditable id="text">
The World Before the Flood is an oil-on-canvas painting by English artist William Etty, first exhibited in 1828. It depicts a scene from John Milton's Paradise Lost in which Adam sees a vision of the world immediately before the Great Flood. The painting illustrates the stages of courtship as described by Milton: a group of men select wives from a group of dancing women, take their chosen woman from the group, and settle down to married life. Behind them looms an oncoming storm, a symbol of the destruction which the dancers and lovers are about to bring upon themselves. When first exhibited at the 1828 Royal Academy Summer Exhibition, the painting attracted large crowds. Many critics praised it, but others condemned it as crude, tasteless and poorly executed. The painting, currently in the Southampton City Art Gallery, and a preliminary oil sketch for it, now in the York Art Gallery, were exhibited together in a major retrospective of Etty's work in 2011 and 2012
</div>
<button id="bold_button">Bold</button>

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>

Include Different letter tempates under ng-repeat

I am wanting to see if there is a way to bring in letter templates that have different text content on them inside my ng-repeat which only brings in the template title from my server. I want to see if I can get the content in without putting it along the other data on the server. Any suggestions?
Here is my controller where I am currently bringing in 1 template but that template is being repeated when I dont want it to be:
app.controller('letterTemplatesCtrl', function($scope, letterTemplatesSrv) {
$scope.getAllTemplates = letterTemplatesSrv.getAllTemplates().then(function(response) {
$scope.templates = response.data;
});
//Changes tempalte border to red when select button is clicked
$scope.activeTemplate = function(index) {
$scope.isSelected = index;
};
// Truncated letter template content
$scope.longText1 = "Dear (name), Ho Ho Ho! Merry Christmas! The Elves and I are busy making presents for all of the good boys and girls around the world. You have been such a good (boy/girl) this year, so I wanted to take a minute to write you a letter. I’ve made my Naughty and Nice list, and I’ve checked it twice. You are on my Nice List! I am so happy that you have been such a good (boy/girl) this year.I heard from my secret messenger that you want (What do they want for Christmas?) for Christmas this year. Because you have been so good, the Elves and I have prepared a special present for you to open on Christmas Morning. Can you do me a favor? I want you to try really hard to (insert something that the child needs to work on). If you can do that for me, then I will be very happy and might bring you an extra treat on Christmas Morning. By the time I get to your house in (location), I am going to be very hungry. Would you leave some cookies and milk out for me? Chocolate Chip cookies are my favorite, but I love all kinds of cookies! Well I need to get back to my workshop and help the Elves. Keep up the good work (Name) and have a Very Merry Christmas! Ho Ho Ho, Santa Claus";
});
Here is my HTML:
<div layout="row" layout-xs="column" layout-padding layout-margin layout-align="center center">
<div flex ng-repeat="template in templates">
<div class="template-chooser" ng-class="{'selected-template':isSelected === $index}">
<span class="template-title">{{template.template_name}}</span>
<p class="template-content" ng-text-truncate="longText1" ng-tt-chars-threshold="40"></p>
<md-button class="md-raised md-primary template-chooser-btn" ng-click="addProductToCart(product); activeTemplate($index)">Select</md-button>
</div>
</div>
</div>

use twitter api to tweet html element's content

I am trying to make a random quote generator then use a tweet button to tweet the current quote (the content of the element) but I can only get the twitter api to tweet the url, I have researched and read but am completely stuck any help would be wonderful!
Here is HTML with twitter button
<body>
<h1>J.R.R. Tolkien Quote Machine!</h1>
<div id ="stuff">
<img id="image" src="http://i1376.photobucket.com/albums/ah30/joecarlowittosi/images_zpsukywovht.jpg">
<h2 id = "quotetext">Press the button to discover the first quote.</h2>
<button id = "quotebutton" onclick = "randomQuote()">Get a new quote... </button>
</div>
<!--tweet the url-->
Tweet<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</body>
here is my javascript...
var myQuotes = [
"'Faithless is he that says farewell when the road darkens.'",
"'All we have to decide is what to do with the time that is given us.'",
"'If more of us valued food and cheer and song above hoarded gold, it would be a merrier world.'",
"'Never laugh at live dragons.'",
"'There is some good in this world, and it's worth fighting for.'",
"'Faithless is he that says farewell when the road darkens.'",
"'The world is indeed full of peril, and in it there are many dark places; but still there is much that is fair, and though in all lands love is now mingled with grief, it grows perhaps the greater.'",
"'Many that live deserve death. And some that die deserve life. Can you give it to them? Then do not be too eager to deal out death in judgement.'",
"'Not all those who wander are lost.'",
"'I will not say: do not weep; for not all tears are an evil.'",
"'Little by little, one travels far'",
"'Courage is found in unlikely places.'",
"'It's the job that's never started as takes longest to finish.'",
"'There is nothing like looking, if you want to find something. You certainly usually find something, if you look, but it is not always quite the something you were after.'",
"'The wide world is all about you: you can fence yourselves in, but you cannot forever fence it out.'",
"'It may be the part of a friend to rebuke a friend's folly.'",
]
var myImages = [
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/p0232nkj_zpsevgnb5vx.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/lord-of-the-rings-quiz-orig_zpsse5k5mrg.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/12d212546fbb50f1f278db8d3c893b05_zpsqzlpz91p.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/imgres1_zpsdsmi4elj.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/samwise-gamgee_zpsrhuv2u33.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/p0232nkj_zpsevgnb5vx.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/images2_zpsgyxpexod.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/gollum_zpsy583lrzv.png",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/images_zpsonmjtyty.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/imagesq_zpsfgguq2ha.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/imgres_zpsesxdolbh.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/images_zps9qwoibjr.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/imgresw_zpseizew5r4.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/The-Hobbit-An-Unexpected-Journey-2012-1_zpsjxz1lw9i.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/middleearthlargelargerstill_zpscp5xil1m.jpg",
"http://i1376.photobucket.com/albums/ah30/joecarlowittosi/lord_of_the_rings-_the_fellowship_of_the_ring_wallpaper_15_1024_zpssafzudw9.jpg"
]
function randomQuote() {
var randomNumber = Math.floor(Math.random() * (myQuotes.length));
document.getElementById("quotetext").innerHTML = myQuotes[randomNumber];
document.getElementById("image").src = myImages[randomNumber];
}

Jquery onload/text effect late reaction

In my rails app have this code:
window.onload = ->
$("#mycontainer").typewriter()
$("#div1").fadeIn("slow")
which acts on this:
<blockquote class="pull-left">
<p id="mycontainer">A mathematician, scientist, and engineer are each asked: "Suppose we define a horse's tail to be a leg. How many legs does a horse have?" The mathematician answers "5"; the scientist "1"; and the engineer says "But you can't do that! </p>
<small id="author">Emmanuel Mensah </small>
</blockquote>
Now, I can clearly see the window.onload function which I understand to let the jquery kick in right after the page loads. I realised that first, the page loads and then for a split second, I can see the (whole) text BEFORE the text effects comes in (effect is a typewriting which means text should not be visible but typed key after key...to the right). But I am wondering how to this so that when the page loads, I don't see the text at all but just after the jquery kicks in.
I tried to add this CSS style: display:none to the <p> tag but this changes nothing. Can someone help me here?
You need to hide them at first to see the showing effect.
window.onload = ->
$("#mycontainer").hide()
$("#div1").hide()
$("#mycontainer").typewriter()
$("#div1").fadeIn("slow")
Try body onload instead.
<body onload="myfunction()">
<blockquote class="pull-left">
<p id="mycontainer" style="display:none;">A mathematician, scientist, and engineer are each asked: "Suppose we define a horse's tail to be a leg. How many legs does a horse have?" The mathematician answers "5"; the scientist "1"; and the engineer says "But you can't do that! </p>
<small id="author">Emmanuel Mensah </small>
</blockquote>
</body>
function myfunction() {
$("#mycontainer").show();
$("#mycontainer").typewriter();
}

Categories

Resources