jQuery empty textarea that contains data - javascript

Curious problem. I need to empty a <textarea> then replace it with other content. The tests in the JSFiddle will work if nothing is manually typed, but as soon as anything is entered in the textarea by hand, the methods will cease to work.
http://jsfiddle.net/ecFjH/
I understand that I can simply just .val('New stuff here'), however I need HTML entities such as > and < to appear as < and >, which .val() will not accomplish.

It sounds like your real problem is that you want to decode HTML entities to render them in a text area. You could use the following to do this:
var content = 'text > HTML';
$('#myText').val($('<div/>').html(content).text());
However, you should only do this with trusted content. If the content for the textarea is not created by you, it could contain malicious HTML, which you would unsafely be creating on the page.
For a more thorough example, see this answer to essentially the same question; note that the accepted answer repeats the above, but the linked answer is safer.

Your text area has no html. use just $('#myText').val('Button 2 was pressed'); that will remove the previous content and put the text "Button 2 was pressed".
Check here (updated with < and >)

Related

My ID's have been changed, how can i stop it?

I've been trying to do something simple, i think, let me explain:
I have an BPMS software where a send an e-mail at the end of the process, this e-mail is an HTML page that i created, inside the HTML page we have some identifying codes that get a field value from an previously form, some strings. The problem is, when i transfer that value to the HTML page, obviously the "Enter" key doesn't work like the "br" tag, so i made a simple javascript to replace the "enter" for the "br". It worked, but when i send the e-mail my ID is changed and they put an "x_" prefix, so there goes my question.
Can i stop it or there is some other way to do it?
The code is below:
<p id="informacoes">
TEST
TEST
</p>
<script>
var strMessege = document.getElementById('informacoes');
strMessege.innerHTML = strMessege.innerHTML.replace(/(?:\r\n|\r|\n)/g, '<br />');
</script>
It seems like your end goal here is to retain original line breaks present in the source code. I think your best bet would be to address this using CSS.
Take a look at the CSS property white-space, MDN: white-space property
By default, CSS collapses white space (e.g. multiple non-breaking ("regular") spaces, tabs, and newlines) into, effectively, a single regular space. In your example, the line breaks that you see in the source code are being collapsed and so they will not be rendered by the browser or email client.
Try using CSS to set a different white-space property, like
#informacoes {
white-space: pre-line;
/* depending on your use case,
a different value might work better */
}
Property values other than white-space: normal (which is the default) will change whether and how white space, including new lines, are collapsed when rendering from the source code to the screen.

JavaScript Library/Function to find Unclosed HTML Tags

I am currently looking for a solution to find and list out any unclosed HTML tags from an arbitrary slice of raw HTML. I don't feel like this should be an awful problem, but I cannot seem to find something that does it in JS. Unfortunately, this needs to be client-side since it is being used for rendering annotations to HTML pages. Obviously, annotations are somewhat nasty business, since they select or apply formatting that may apply to only part of an HTML element (i.e., a markup overlaid onto an existing HTML markup).
One simple use-case is where you might want to only render part of an HTML page, but then inject the rest later. For example, imagine a hypothetical segment:
<p>This is my text <StartDelayedInject/> with a comment I added. </p>
<p> But it doesn't exist until now. </p> <StopDelayedInject/>
I'll be doing some pre-processing to rebuild the HTML so that I wrap partial elements into span-type elements that apply the appropriate formatting. Initially this would be parsed in the form:
<p><span>This is my text</span></p>
After some user action, it would then be modified to a form such as:
<p><span>This is my text</span><span>with a comment I added.</span></p>
<p>But it doesn't exist until now.</p>
This is a very simplified example case (obviously things like ul elements and tables get hairier), but gives the general principle. However, to do this effectively, I need to be able to check a segment of HTML and figure out there are tags that have opened (but not closed). If I know that information, I can wrap the last unterminated text data into a span, close the unclosed tag, and know to return to that point to inject the remainder of the content when needed. However, I need to know the tags that were still open, so that when I inject or modify another segment of content, I can make sure to put it in the right place (e.g., get "with a comment I added." in the first paragraph).
From my understanding of context-free grammars, this should be a relatively trivial task. Each time you open/enter or close/exit a tag, you could just keep a stack of the tags opened but not yet closed. With that said, I'd much rather use a library that's a bit more of a mature solution than make naive parser for that purpose. I'd assume there's some JS HTML parser around that would do this, right? Plenty of them know how to close tags, so so clearly at some point they calculated this.
The problem is that JavaScript only has access to the html in two ways:
In a sense that each element is an object with properties and methods created by the browser on page load.
In a sense that it is a string of text.
Using the first method of interfacing with html, there is no way to detect unclosed tags as you only have access to the objects that the browser creates for you after it parses the html.
Using the second method, you would have to run the entire string of html through an html parser. Some people might assume you could do it simply with regexp, however, this is not feasible. I refer you to this fantastic stackoverflow question.
Even if you found a really robust html parser to use, you would still run into the problem created by the fact that, before your JavaScript even touches it, the browser will have attempted to parse the potentially broken html and there could be errors everywhere.
Edit:
If you like the parser idea, John Resig created this example one you might want to reference.
Not perfect but here's my quick method for checking for mismatch between open/close tags:
function find_unclosed_tags(str) {
str = str.toLowerCase();
var tags = ["a", "span", "div", "ul", "li", "h1", "h2", "h3", "h4", "h5", "h6", "p", "table", "tr", "td", "b", "i", "u"];
var mismatches = [];
tags.forEach(function(tag) {
var pattern_open = '<'+tag+'( |>)';
var pattern_close = '</'+tag+'>';
var diff_count = (str.match(new RegExp(pattern_open,'g')) || []).length - (str.match(new RegExp(pattern_close,'g')) || []).length;
if(diff_count != 0) {
mismatches.push("Open/close mismatch for tag " + tag + ".");
}
});
return mismatches;
}

JavaScript setAttribute on another element

I have a problem to set an attribute on another element.
I'm using PHP code with JS and HTML and it looks like:
<textarea name='$id' id='$id' class='regular-text' cols='60' rows='1' tabindex='2'"
. "onkeypress =\"javascript:document.getElementById('content').setAttribute('onkeypress', document.getElementById('so_observer_heading_count').innerHTML = document.getElementById('content').value.length)\">$value</textarea>
You must know I have 2 elements. The first('content') one I use for writing a text and in the other one('so_observer_heading_count') there shall be updated the number of signs from the first element.
So my question is, how can I set an attribute on another element.
I have already checked that the name is correct and when i change the content of the textarea on the 2. element I get the right amount from the first element. But I want only to change content in the first element to refresh the amount.
And I don't want to change the code of the first element! And don't be confused by the textarea, in future this shall be a label or something else.
First of all:
Don't use the inline-eventbindings. Always use "real" javascript, (this way you also prevent the problem of escaping your quotes) this is far more cleaner and more maintanable.
Also you code has another problem: You have an eventhandler "keypress" on the textarea, which binds on every "keypress" another attribute to your content-element. This is not very performant and most likey won't work properly. This code should be everything you need:
document.getElementById('content').addEventListener("keyup",function(){
var obs = document.getElementById('so_observer_heading_count');
obs.innerHTML = this.value.length;
});​
Here is a demo for you.
Edit: I changed the event from keypress to keyup to 1) count properly 2) take charakter deletion into account.
I'd say "setAttribute" won't work on a method. Try instead :
document.getElementById('content').onkeypress = function() { document.getElementById('so_observer_heading_count').innerHTML = document.getElementById('content').value.length };
Well, there are certainly more.. efficient ways of doing this, but the thing you forgot to do was escape your single quotes, so the js treats your event as a string, instead of parsing the end result:
<textarea name='$id' id='$id' class='regular-text' cols='60' rows='1' tabindex='2'"
. "onkeypress =\"document.getElementById('content').setAttribute('onkeypress', 'document.getElementById(\'so_observer_heading_count\').innerHTML = document.getElementById(\'content\').value.length;')\">$value</textarea>
Elsewise.. I would personally do this through an included js file that executes the above line on document load/ready, versus every time a key is pressed.
Update: slight edit so anything I removed from your above code was added back, incase you want to just straight-copy it in.

replace text function not working in explorer

I have a js replace function to replace text next to two radio buttons on a pre set form.
Script is as follows.
document.body.innerHTML=document.body.innerHTML.replace("Payment by <b>Moneybookers</b>
e-wallet<br>","");
document.body.innerHTML=document.body.innerHTML.replace("Maestro, Visa and other credit/debit cards by <b>Moneybookers</b>","Pago con Diners Club, Mastercard o Visa");}onload=x;
The script works fine in Chrome and Firefox, however, the script is not actioned in Explorer.
I believe it has something to do with there being , / - within the text I am replacing? When I use the function to replace text with no , / - in the text - it works fine in explorer, however, for example when I try to replace text.. - "Maestro, Visa and other credit/debit cards by Moneybookers" this does not work in explorer.. I'm assuming because of the coma and forward slash. Honestly I've tried everything but just can not get this to work. Any help would be greatly appreciated!!
Not sure whether it's related (I'm a Mac user without IE) but you shouldn't use multiline strings. Use \n instead.
What is returned by innerHTML varies from one browser to an other, because there is no standard about it (the content will be the same, but the way it's displayed can be different). Doing replace like that is likely to fail on some browser. You should just take an other approach to do your replace.
A better approach would be to wrap the text you want to replace with a span, this way you can more easily target the content you want to replace.
<span id="thatFirstThing">Payment by <b>Moneybookers</b>e-wallet<br></span>
An after you can do
document.getElementById("thatFirstThing").innerHTML = "";
P.S.: Doing innerHTML replace on the body also has a huge side-effect. Since you are replacing the content of your hole page. All the event handler that where bind on your page will disappear.
Edit: If you can't modify the HTML page, it's a little bit more tricky, because the DOM is not well adapted to do such thing. What you could do is to target parent element by navigating through the DOM with document.getElementById and childNodes. And once you have your parent element just write the new content you want, without doing replace.
In the end it would look something like this :
document.getElementById("someSection").childNodes[0].childNodes[1].childNodes[0].innerHTML = "";

Quote in HTML attribute destroys layout

My site has user generated content. I noticed that if the user has quotes in some text and later I displayed that text in an HTML attribute, the layout would get screwed up in IE.
Hello
However, if I had generated the same anchor with Javascript (Prototype library), the layout would not be screwed up in IE:
$$('body').first().appendChild(
new Element(
'a', {
title: 'user "description" of link',
href: 'link.html'
}
).update('Hello')
);
Why is this so? The JS and the plain HTML versions both have the same intended result, but only the JS doesn't screw up IE. What's happening behind the scenes?
BTW, I do strip_tags() and clean XSS attacks from all user input, but I don't strip all HTML entities because I use a lot of form text input boxes to display back user generated text. Form elements literally display HTML entities, which looks ugly.
You need to escape all output that is user-specified (using entities). The DOM-methods do that automatically.
I don't know how you are processing the user generated content, but you could use a replace function to clean up the input something like string.replace("\"", "")
The answer to your question: 'Why is it so' is because in your JavaScript example set the title attribute with single quotes. So the double quotes in the user generated string are already escaped.
In you A tag example, single quotes around the text you use in the title attribute may be a way to solve the rendering problem.
However, Your HTML attributes should be in double quotes, so you would be better off using entities, as suggested by #elusive in his answer.

Categories