I have one div with a temporal text, once other images are clicked I want to show a different text, for this I'm using the .text on javascript call, I can replace the text, my problem is that I can't create spaces or paragraph breaks. Can someone explain me how to implement it?
$("#memberTrigger").click(function() {
$("#memberDescriptionResponsive").text('This is the Large Description I want to appear within that text area defined previously. After this dot I would like to have a break of paragraph and continue in a secondary one, right now is showing on the same line as continuity');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 id="memberDescriptionResponsive">Some Information of the Team Member</h3>
<div id="memberTrigger"></div>
text is for:
Get the combined text contents of each element in the set of matched elements, including their descendants, or set the text contents of the matched elements.
http://api.jquery.com/text/
And you should use html
This method uses the browser's innerHTML property. Some browsers may not return HTML that exactly replicates the HTML source in an original document. For example, Internet Explorer sometimes leaves off the quotes around attribute values if they contain only alphanumeric characters http://api.jquery.com/html/
$("#memberDescriptionResponsive").html('<span style="background:red">This is the Large Description</span><br>I want to appear within that text area defined previously. After this dot I would like to have a break of paragraph and continue in a secondary one, right now is showing on the same line as continuity');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="memberDescriptionResponsive">hey</div>
The text method inserts text. Just text. Not elements. If you want an element, then you need to use something else.
First, you need to change the h3 to something different. No HTML heading element is allowed to contain a paragraph.
Then you can use empty to clear the existing content and append to add new elements.
var heading = $("<h3 />").text("This is the Large Description I want to appear within that text area defined previously.");
var paragraph = $("<p />").text("After this dot I would like to have a break of paragraph and continue in a secondary one, right now is showing on the same line as continuity");
$("#memberDescriptionResponsive").empty().append([heading, paragraph]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="memberDescriptionResponsive"><h3>Some Information of the Team Member</h3></div>
You can add <br> in between where you want to add the break. but instead of using text you got to use .html
$("#memberTrigger").click( function() {
$("#memberDescriptionResponsive").html('This is the Large Description<br> I want to appear within that text area defined previously.<br> After this dot I would like to have a break of paragraph and continue in a secondary one, <br>right now is showing on the same line as continuity')});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3 id="memberDescriptionResponsive">Some Information of the Team Member</h3>
<div id="memberTrigger">a</div>
Related
I have a contenteditable element with some text inside decorated with <b> and <i> tags. I am trying to find the best way to delete the last word from it without affecting the decoration.
I can't simply remove the last word in the last child node because one word can be contained in several <b> and <i> tags.
For example (the word "internet." must be removed):
<div>Build the best reference material for developer tools <i>on the inter<b>net</b></i>.</div>
Maybe there is some more or less elegant and native solution for this case.
Below is the sample code that will help you to achieve what you are looking for. Instead of using HTML, use text and that would solve the problem.
var text = $("#sometext").text();
text = text.split(" ");
text.pop(); //remove last element
$(".output").html(text.join(" "));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sometext">Build the best reference material for developer tools <i>on the inter<b>net</b></i>.</div>
<div class="output"></div>
What I am trying to do is to create a front-end editable tagbox (editable div). Whenever a user types a word into that box and presses , this box will change that word into a colorful label. The problem I am having is:
User types the first word in, presses the comma key.
The word is then wrapped in <a> tags.
User types the second word in, presses the comma key.
Now I have to leave the first wrapped word as it is and take only the second word into consideration to wrap it into an <a> tag as well. It's extremely tricky to me, I have no idea how to leave the first <a> tag alone and select "free" words for wrapping. This also means wrapping more than one word into a single <a> tag whenever the user decides to put a two-word tag. It has to work with any number of tags.
Could you please point me in the right direction? I am trying to solve this with jQuery. I don't necessarily need the code itself, because I know how to write it, I just need to come up with the right algorithm in my brain.
Alright, as requested :)
Depending on whether you keep the commas in the field after replacing or not, split the inner HTML of the editable content by comma and/or .
Try following
function wrapInLink(container){
var link_text = $(container).text().split(',').slice(-1).pop(); // finding the string for replacing with anghor tag
var html = $(container).html(); // getting the container html
html = html.replace(link_text, "<a href='link_to_be_given'>" + link_text + "</a>"); // replacing the link text with anchor tag
$(container).html(html); // replacing the container's html
}
I have the following code:
<body>
<form>
<textarea id="textfield"></textarea>
<input type="button" onclick="func1()" value="Post">
</form>
<p id="para"></p>
</body>
When I type in textarea all the special tags <a>,<br> etc are ignored when I display them inside a <p> also all what I typed is displayed on one line and it doesn't even matter that I pressed return or use <br>, textarea seems to be taking html tags and turn them into a simple text.
This is the function I use to display the text area in html:
function func1()
{
document.getElementById("para").innerHTML=document.getElementById("textfield").innerHTML;
}
How do I take text from textarea and display it on screen normally(not in one line).
How do I modify textarea for a user who doesn't know how to use tags? when pressing a simple return should be translated to <br
First of all, for textareas you should use value and not innerHTML. Like this...
document.getElementById("para").innerHTML=document.getElementById("textfield").value;
Now, for the single line issue. In textarea, new lines are separated by \n. In your divs \n do not work. So you'll have to replace them with <br> tags. So rewriting your code snippet...
document.getElementById("para").innerHTML=document.getElementById("textfield").value.replace(/\r\n|\r|\n/g,"<br />");
The text in the textarea isn't html. It is just text, containing regular line break "\n". To display them, you either need to enclose the text in a pre tag, or replace the "\n" with <br>.
I would do the latter, since pre doesn't break at all if there's no break in the text, so you'll have a single long line and a scrollbar.
<textarea> does not take HTML and interprets it. I think what you are looking for is a Rich Text Editors if you want your users to be able to modify text without knowing the tag names
i am using jquery replaceText plugin. with this plugin i can successfully replace text of an element like this:
<div>some text to be replaced here.</div>
<script type="text/javascript">
$(function(){
$("div").replaceText("some text to be replaced here", "a new text for replacement");
})
</script>
however when that div becomes something like this:
<div>some text to be replaced here.</div>
the replacement is not working.
how should i proceed here?
When operating on the HTML of the page, all the tags are in the HTML stream so you can't just do a direct replacement of only the text without allowing for intervening tags.
It isn't matching "some text to be replaced here" because that string of text doesn't exist as a single string of text in this HTML:
div>some text to be replaced here.</div>
You would have to replace individual pieces of text that actually exist as individual streams of text like "some text to be " and "replaced".
So you want to replace a subset of text with another subset of text and you want to work across nodes.
Looks like you want a Range.
So you just have to make a new Range using document.createRange(). Make it point to where you content starts.
So just find the start node and the start offset somehow then call range.setStart(node, offset). I would presume the node will be your container and the offset is just calculated.
Then call range.extractContents() to remove the original text from the DOM.
Then just range.insertNode(textNode) to insert the next text into the DOM.
I have website that converts Japanese Kanji into Romaji (roman letters):
and the output shows and hides with CSS what the user needs to see depending on their input criteria. For example:
<div id="output"><span class="roman">watashi</span> <span class="english">I</span></div>
The interface allows the user to flip between and output of watashi or I depending on what they want to see. The CSS hides one or the other using jQuery and a toggle button. (the hiding mechanism involves simple adding a class to the body and letting CSS do its thing).
The problem is that when users copy/paste the text into Word it copies everything. So I decided to use a system to copy paste the text using JavaScript and jQuery, but the problem repeats itself:
$('#output').text() outputs watashi I even if I is invisible on the page itself rather than watashi. Is there any way to get just the visible text?
the other solutions did not give me what I needed.
Short Answer
my answer is :
$('#output *:not(:has(*)):visible').text()
plunkr
TL;DR
The problem with marcgg's solution
You should not ask the text of all element under some root element..
why? - it will repeat output and ignore hidden flag
lets look at a simple example
<div id="output" class="my-root">
<div class="some-div">
<span class="first" style="display:none"> hidden text </span>
<span class="second" > visible text </span>
</div>
<div>
now if I do $('#output').children(":visible").text()
I will get .some-div and .second..
when in fact .some-div is of no concern to me..
when I ask for text() on those elements, .some-div will return the hidden text as well..
so technically marcgg's solution is wrong IMHO...
The reason for my answer
Now, in order to properly answer the question, we have to make an assumption. One that, for me, seems reasonable enough.
The assumption is that text only appears in leaf elements..
So we won't see something like this:
<div id="output" class="my-root">
<div class="some-div">
<span class="first" style="display:none"> hidden text </span>
<span class="second" > visible text </span>
</div>
some text here..
<div>
Why does this assumption seem reasonable to me? two reasons:
Because it is hard to maintain a page that is constructed this way - and with time people with experience learn that and avoid it.
It is easy to convert your html to such a structure. just wrap parents' text with spans. So even if this assumption does not exist right now, it is easy to get there.
With that assumption, what you want to do is request all leaf elements (elements without children) , filter out the visible, and ask for their text..
$('#output *:not(:has(*)):visible').text()
This should generate the correct result.
Gotta have text outside leaf element?
the comments suggest sometimes you just got to have text outside leaf element
<div> This is some <strong style="display:none"> text </strong> </div>
As you can see, you have <strong> as a leaf and it is common to have text outside it like in this example.
You could go around it with the workaround I suggest above.. but what if you can't?
You can clone the dom and then remove all hidden elements.
The problem here is that in order for :visible selector or :hidden selectors to work, I must have the dom element on the document (which means actually visible to the user).
And so, this method comes with some side effects, so be careful.
Here is an example
for this html
<div id="output" class="my-root">
<span>
some text <strong style="display:none">here.. </strong>
</span>
</div>
This javascript works
$(function(){
var outputClone = $('#output').clone();
$('#output :hidden').remove();
console.log($('#output').text()); // only visible text
$('#output').replaceWith(outputClone);
console.log($('#output').text()); // show original state achieved.
})
see plunker here
as mentioned - side effects may appear like a momentary flicker, or some initialization script that should run.. some may be avoided with some original thinking (div with size 1px/1px to contain the clone alongside original content?) depending on your scenario.
Use the :visible selector of jQuery
In your case I think you want to do:
$('#output').children(":visible").text()
Try this in modern browsers (here 'element' is a non-JQuery DOM object):
function getVisibleText(element) {
window.getSelection().removeAllRanges();
let range = document.createRange();
range.selectNode(element);
window.getSelection().addRange(range);
let visibleText = window.getSelection().toString().trim();
window.getSelection().removeAllRanges();
return visibleText;
}
then:
getVisibleText(document.getElementById('output'));
Guy has the correct answer.
However, I was dealing with a "this" object, so to get his answer to work you need to use the following syntax...
$('*:not(:has(*)):visible', this).text()
var lookup = function(element, text) {
//DFS Recursive way of finding text on each level
//Visible only works on elements that take up space(i.e. not fixed position elements)
var results = element.children(':visible');
//Look at the text at each level with the children removed
var newText = '';
results.each(function(index, value) {
newText += $(value).clone()
.children()
.remove()
.end()
.text();
});
var moreResultText = '';
results.each(function(index, value) {
moreResultText += lookup($(value), text);
})
if (results.length > 0) {
return text + newText + moreResultText;
} else {
return text;
}
};
lookup($('#output'), ''));
Most of the other functions fall apart when run on large sections of a page, this should be a more accurate way to determine what is actually displayed to the user, without corrupting the page, and without returning text that is not visible to the user.
Be careful of course, this does not preserve any sense of formatting, and the spacing of the output may not be correct between elements. Also, it probably does not correctly order the returned text, in these aspects its usages will be limited. Another consideration is the real definition of visible is a little hard to nail down, but for this example I accept that ":visible" works for most common cases.
I use it to check if a page contains visible text(just run it on the body element), but it would probably work for this example too.
Instead of hiding a span, remove the span element and keep a reference to it. When the user clicks on the toggle button, remove the other one and insert the one you kept a reference to. The user won't be able to select something that isn't in the DOM anymore.