I will try do describe the issue:
I'm using contenteditable to edit text in DIV. The standard for elements I need to have in that DIV is:
paragraph:
<p style="someStyles"><span style="someStyles">TEXT GOES HERE</span></p>
empty line:
<p style="someStyles"><span style="someStyles"><br></span></p>
Due to some user text manipulations like copy/paste standard is messed in that DIV like here (ex. of case):
<span style="someStyles">
<p style="someStyles">SOME TEXT HERE</p>
<p style="someStyles">SOME TEXT HERE</p>
</span>
Im looking for a solution that will take messed text elements and rearrange it to given standard I wrote about above, any suggestions ?
After rearranging elements it should look like this:
<p style="someStyles">
<span style="someStyles">SOME TEXT HERE</span>
<span style="someStyles">SOME TEXT HERE</span>
</p>
P.S - I want to make that rearrange function on keyup event while typing and only for whole p element that caret is on.
As I stated in my comment, I can't see a general solution to this, but your specific example could be solved like this. And you can easily make several other conversions based on this one.
The replace function is based on this answer.
// this converts an element to another tag
function replace(thisWith, that) {
$(thisWith).replaceWith(function() {
var i, replacement = $('<' + that + '>').html($(this).html());
for (i = 0; i < this.attributes.length; i++) {
replacement.attr(this.attributes[i].name, this.attributes[i].value);
}
return replacement;
});
}
function convert() {
// get SPANs that has Ps inside
var $spans = $("#content span").has("p");
$spans.each(function () {
// change children Ps into SPANs
replace($(this).children("p"), "span");
// change parent SPAN into P
replace(this, "p");
});
}
Here is a test jsfiddle.
Related
So what I'm trying to make is a paragraph in HTML and then when you click on it it would do a certain action, for example:
<p id='hello'>Hello</p>
<script>
hello.onclick = function() {
console.log("clicked!");
}
</script>
the only problem is that when I click next to the text, it still detects it as a click, I want the click ratio to be the length of the paragraph's text. What's the best way I could do this?
I would suggest you to use inline element instead of p like below -
<span id='hello'>Hello</span>
Because p is block element and no matter where your contents gets over in the line it will takes the space of whole line.
For more in details refer this link
I write an example, I think this helps you
you can see the link
<buttom onclick="clickMe()">click me please</buttom>
<div>
<p id="write"></p>
</div>
<script>
function clickMe() {
let getELementP = document.getElementById("write");
getELementP.innerHTML = "writeHere";
}
</script>
Im trying to remove some invalid tags/html with jquery, but I think because its invalid the selector cant find it. IE
<p>Here1 is Here is lots of text in page <a href="" class="tooltipster">REMOVE THIS more content</a> and its cool</p>
$("a").find("a").remove();
Nothing happens, however if I change the second a (invalid one) to a span the selector can find and remove it? Thanks
======================================================
Update, ive taken m69s regex and added it to jquery (elements not in DOM so I cant use getelementbyID)
$(.container p).each(function (index) {
var cont = $(this).html().match(/^(.*?<A[^>]+>.*?)<A[^>]+>.*?(<\/A>.*)$/i);
if (cont) $(this).html(cont[1] + cont[2]);
});
This removes the illegal A element, but it doesn't completely restore the legal A element, because the browser removes the second closing A tag. As a result, some text that was inside the link may now come after it. (If you want to avoid the link being empty, you could move the next word into it.)
var elem = document.getElementsByTagName("P");
for (i = 0; i < elem.length; i++) {
var cont = elem[i].innerHTML.match(/^(.*?<A[^>]+>.*?)<A[^>]+>.*?(<\/A>.*)$/i);
if (cont) elem[i].innerHTML = cont[1] + cont[2];
}
<p>A simple text paragraph.</p>
<p>A paragraph with a legal <a href="">ILLEGAL LINK link</a> and some more text.</p>
<p>A paragraph with a legal link and some more text.</p>
Save your file as xhtml, the browser should find the un-closed tags for you. I don't think there is a way that this could be done in javascript.
I'm doing a fancy comment list on my project, structured like this:
As you see, there's a comments list and at his bottom there's an input field (textarea) to submit a comment. Note that there's the current username attached to the right (let's call it a simple static appended text).
I just found this little JS to make an input field resize automatically by adapting it to the content.
function resizeInput() {
$(this).attr('size', $(this).val().length);
}
$('input[type="text"]').keyup(resizeInput).each(resizeInput);
But it's not enough. I need it for a textarea and I want it to behave correctly when a comment is long enough to wrap on another line. By definition, the input field is a box, and it obviously acts badly compared to what I want:
Instead, this should be the right behavior:
I looked everywhere and I can't think any way to implement this. Can somebody help me?
Here is a good plugin for textarea. But it using jQuery.
usage simple as always.
$(document).ready(function(){
$('textarea').autosize();
});
You could use the contenteditable attribute:
<span contenteditable="true">comment</span> by <span class="userName">someone</span>
It is supported in practically all browsers. Using the right CSS, you can underline the content and also limit the width.
I think you mean this
NOTE: No check for selection and bound to document. Exercise for the reader to bind to a specific field and swap it for a span
FiDDLE
$(document).keypress(function(e) {
var char = String.fromCharCode(e.which);
if (e.which==13) char = '<br/>'; // needs to handle backspace etc.
$("#textfield").append(char);
$("#hiddenfield").val($("#textfield").text()); // or .html if you want the BRs
e.preventDefault();
});
using
<span id="textfield"></span> - by My Username
If you make the field contenteditable you will get this in Chrome so some additional CSS may be needed
Use a <span> with contenteditable (supported in IE too). Here is a fiddle: http://jsfiddle.net/goabqjLn/2/
<span contenteditable>Insert a comment...</span> by My Username
Then, using JavaScript, attach an event listener that mirrors the inner text of the span into a hidden input field, so it gets submitted with your <form>.
Edit: I have updated the fiddle to also include the JS code. Here is the updated code:
<span class="editor" id="editor" contenteditable data-placeholder="Insert a comment...">Insert a comment...</span> by My Username
<!-- Hide this textarea in production: -->
<textarea type="text" id="comment"></textarea>
And the JS:
function mirror() {
var text = $('#editor').html().trim()
.replace(' ', ' ')
.replace(/<br(\s*)\/*>/ig, '\n') // replace single line-breaks
.replace(/<[p|div]\s/ig, '\n$0') // add a line break before all div and p tags
.replace(/(<([^>]+)>)/ig, ""); // remove any remaining tags
$('#comment').val(text);
}
$('#editor').focus(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text('');
}
}).blur(function () {
var editor = $(this);
if (editor.text() == editor.attr('data-placeholder')) {
editor.text(editor.attr('data-placeholder'));
}
}).blur(mirror).keyup(mirror);
My first SO question! Here's what I am trying to do:
I'm rewriting a tool that generates some code a user can paste directly into Craigslist and other classified ad posting websites. I have created a list of websites (they populate from a database with PHP) the user can choose from with a radio button, and I want their choice to populate as bare text (not a link) between some <p></p> elements in a textarea. I'm using jQuery for this.
Textarea before the user chooses:
<p id="thing"></p>
Textarea after the user chooses:
<p id="thing">www.somewebsite.com</p>
HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<textarea>
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
JS
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
alert(website);
$("#thing2").html(website);
});
});
JS Fiddle (With comments)
If you see the JS Fiddle, you can see that I put another p element on the page outside the textarea, and it updates just fine, but the one inside the textarea does not. I have read many other like questions on SO and I'm starting to think that I can't change an element that's between textarea tags, I can only change the entire textarea itself. Please, lead me to enlightenment!
You actually can fairly easily manipulate the text contents of the textarea like it is part of the DOM, by transforming its contents into a jQuery object.
Here is a jsFiddle demonstrating this solution: http://jsfiddle.net/YxtH4/2/
The relevant code, inside the input change event:
// Your normal code
var website = $(this).val();
$("#thing2").html(website);
// This turns the textarea's val into a jQuery object ...
// And inserts it into an empty div that is created
var textareaHtml = $('<div>' + $("#textarea").val() + '</div>');
// Here you can do your normal selectors
textareaHtml.find("#thing").html(website);
// And this sets the textarea's content to the empty div's content
$("#textarea").val(textareaHtml.html());
The empty div wrapping your HTML is so that you can easily retrieve it as a string later using jQuery's .html() method, and so the parse does not fail if additional text is entered around the p element inside the textarea.
The real magic is $($("#textarea").val()), which takes your textarea's text and parses it into an HTML node contained in a jQuery object.
It can't do it the way that you are thinking (i.e., manipulate it as if it were a DOM element), but it is still accessible as the value of the textarea, so you can retrieve it like that, use basic string manipulation to alter it, and then set the updated string as the new value of the textarea again.
Something like this . . . first give the <textarea> an id value:
<textarea id="taTarget">
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
Then alter your script like this:
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
var currentTAVal = $("#taTarget").val();
$("#taTarget").val(currentTAVal.replace(/(<p id="thing">)([^<]*)(<\/p>)/, "$1" + website + "$3"));
});
});
Unless you need the <p> element in there, you might consider using a more simple placeholder, since it won't actually act as an HTML element within the textarea. :)
EDIT : Fixed a typo in the .replace() regex.
I know that this answer is a little bit late, but here it goes =)
You can do exactly the way you want to do. But for that, you need to implement a small trick.
by having this HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com
<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<p id="thing2"></p>
<textarea id="textarea">
<p id="thing"></p>
</textarea>
you can edit textarea content, as a DOM by implementing something like the function changeInnerText
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val(); // Gets value of input
changeInnerText(website);
//$("#thing").html(website); // Changes
//$("#thing2").html(website); // Does not change
});
var changeInnerText = function(text) {
var v = $("#textarea").val();
var span = $("<span>");
span.html(v);
var obj = span.find("#thing")[0];
$(obj).html(text);
console.log(obj);
console.log(span.html());
$("#textarea").val(span.html());
}
});
As you can see, I just get the information from the textarea, I create a temporary variable span to place textarea's content. and then manipulate it as DOM.
Instead of attempting to insert the text into the <p> element, insert the text into <textarea> element and include the <p> tag. Something like this should do the trick:
Change:
$("#thing").html(website);
to:
$("textarea").html('<p id="thing">'+website+'</p>');
And here is a fiddle: http://jsfiddle.net/nR94s/
If I have
<div id='wrapper'>
<fieldset id='fldset'>
<legend>Title</legend>
Body text.
</fieldset>
</div>
How could I retrieve the "Body text" without retrieving the text inside of legend tag?
For instance, if I wanted to see if the text inside the fieldset contains the word "body" and change that word, while ignoring whatever might be in the legend? innerHTML retrieves all text from all children nodes.
Use of jQuery wouldn't be a problem.
$("#fldset").contents().eq(2).text();
Without a library --
var fldset = document.getElementById("fldset"),
txt = fldset.lastChild.textContent || fldset.lastChild.innerText;
alert(txt);
This will get all the text nodes of fldset leaving out any other element and it's content:
var fldsetContent = $('#fldset').contents();
var text = '';
$(fldsetContent).each( function(index, item) {
if( item.nodeType == 3 ) text += $.trim($(item).text());
});
alert( text );
Live example
$('#fldset').clone().find('legend').remove().end().text()
But you should also search around the SO
Using .text() to retrieve only text not nested in child tags
Clip content with jQuery
I can't think of a way other than
$("#result").html($("#wrapper").text().replace($("legend").text(),""));
but there should be a more elegant way. You can also create a new element as a copy of this one, remove all the children and get text. Hmm... That would be:
var newElement = $("#fldset").clone();
newElement.children().remove();
$("#result").html(newElement.text());
So doesn't matter how many and which type of children node has, this would work. Here: http://www.jsfiddle.net/wFV4c/
To turn all plain text nodes inside the field set red:
jQuery.each($('#fldset').contents(),function(index,value){
if(value.textContent == value.nodeValue){
$(this).wrap('<span style="color:red;" />')
}
});