Web User
Web User

Reputation: 7746

jQuery (or JS) decodes HTML character entity in string

I am trying to dynamically populate a <select> element using jQuery and option values from an array of strings returned in a JSON response. One of the option values is Joe&#39;s Cafe which when decoded is Joe's Cafe. However, when I use the following code:

$.each(optionVals, function(idx, elem) {
    $('#restaurant').append('<option value="' + elem + '">' + elem + '</option>');
});

the corresponding option is not what I expect. I see this:

<option value="Joe's Cafe">Joe's Cafe</option>

instead of this:

<option value="Joe&#39;s Cafe">Joe&#39;s Cafe</option>

How do I prevent jQuery from decoding the HTML entity &#39; in the .append() operation? I checked the JSON response, and the HTML entity is intact. I checked the source after the options were loaded and the HTML entity has been decoded into the single quote '.

Upvotes: 3

Views: 1644

Answers (2)

Quentin
Quentin

Reputation: 944531

How do I prevent jQuery from decoding the HTML entity &#39; in the .append() operation?

You can't, because it isn't.

jQuery is generating some HTML and then getting the browser to convert it to a DOM. It then appends that DOM fragment to the document DOM that represents the page.

When you examine the DOM using a DOM inspector (or when you use innerHTML to convert it to a string) you are serialising the DOM to HTML. At this point the browser does not know (because it hasn't kept track, because it doesn't need to) if the apostrophe in the DOM came from a literal apostrophe or a character reference for one. The algorithm it uses to decide how to represent the character uses the literal one (there is no point in it using a 5 character code when it can use 1 more readable character instead).

<option value="Joe's Cafe">Joe's Cafe</option> and <option value="Joe&#39;s Cafe">Joe&#39;s Cafe</option> are two different ways of writing exactly the same thing in HTML. Which you get should not matter.


It may be the same thing in HTML but it is completely different when stored in a database.

It sounds like you want the form to submit the string Joe&#39;s Cafe to the server.

<option value="Joe&#39;s Cafe">Joe&#39;s Cafe</option> would not do that.

That would require: value="Joe&amp;#39;s Cafe"

Now you can achieve that by generating your DOM sanely instead of mashing strings together (because when you mash strings together, characters with special meaning in HTML get treated as having that special meaning).

$('#restaurant').append(
    $("<option />").val(elem).text(elem)
);

however your implication is that having raw apostrophes in the data is breaking your SQL.

That means you are vulnerable to SQL injection attacks and that the real solution is to fix this server side.

See How can I prevent SQL-injection in PHP? or look up how to use prepared statements to prevent SQL injection in whatever programming language you are using on server.

Upvotes: 6

Magicprog.fr
Magicprog.fr

Reputation: 4100

In order to avoid HTML entitites to be decoded, you can replace globally & by &amp; in your strings:

var optionVals = ["Joe&#39;s Cafe"];
$.each(optionVals, function(idx, elem) {
    elem = elem.replace(/&/g, "&amp;");
    $('#restaurant').append('<option value="' + elem + '">' + elem + '</option>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="restaurant"></select>

Upvotes: 2

Related Questions