How to populate currency symbols in html 5 input element - javascript

I have the following html Input element:
<input size=6 type="text" id="prd_price" title="prd_price" name="prd_price" >
I want Currency Symbol ман for "Azerbaijani manat
" to be saved in the database. I would like to populate this as the symbol inside HTML Input element and perhaps concatenate with the price of a product. But when I populate the Input Element dynamically with the UTF-8 Code, it remains in the code form and does not become the Currency Symbol it is suppose to become.
Anyone knows what am I missing here...

The UTF-8 encoding can represent the complete Unicode catalogue (in fact, the letter U in the acronym comes from Unicode) so you don't need HTML entities in the first place. Such entities are only necessary if have characters that your current encoding cannot handle, which isn't the case here.
If you absolutely need to use those HTML entities (e.g., you consume a third-party data feed you cannot tweak) you need to realise that they only make sense in HTML context. A fairly common error in jQuery is to use .text() where you should really be using .html().
In this precise situation you have an <input> element so you cannot use either. Your only choice is .val(). However, since an <input> cannot contain HTML at all everything you feed .val() with will be eventually handled as plain text.
A little trick you can use is to create a detached node so you can use .html() to populate it with HTML and .text() to extract the plain text representation:
var $input = $("#prd_price");
// Original string "&#1084 ;&#1072 ;&#1085 ;" fixed:
var symbols = "ман"
var plainText = $("<span></span>").html(symbols).text()
$input.val(plainText);
... will render as:
ман
Demo

First of all I got the UTF-8 Code for Azerbaijani manat ман which is able to be run in javascript from "https://r12a.github.io/apps/conversion/". In this case it came up to be \u043C\u0430\u043D. Then I ran it up with the following code to get it display inside the input element using javascript:
var x = "\u043C\u0430\u043D";
var r = /\\u([\d\w]{4})/gi;
x = x.replace(r, function (match, grp) {
return String.fromCharCode(parseInt(grp, 16)); } );
x = unescape(x);
console.log(x);

Related

Dynamic Unicode Generation into the DOM

I have a function linking to a method for a JavaScript library I'm working on. Basically taking romanized Korean and converting it to specific Unicode sequences and re-inserting it into the DOM. The resulting strings that it generates are correct, but the re-insertion back into the DOM seems off...
For example: If I have the following in my DOM:
<ko>hangug-eo</ko>
The function is meant to convert it accordingly, replacing hangug-eo with 한국어 to show on the browser:
한국어 within the <ko> tags...
The function that does the string setting within the DOM is as follows:
function (){
var z=document.getElementsByTagName('ko');
for(x=z.length;x--;){
z[x].childNodes[0].data=kimchi.go(z[x].childNodes[0].data);
}
}
However, it seems that all this seems to be doing is just placing the &# Unicode entities straight into the DOM without it converting to their respective character equivalents... So all I'm seeing is 한국어
Can anyone please point out what I may be doing wrong?
kimchi.go() is the function that ultimately provides the Unicoded string...
You can always just set the text directly using textContent without having to use HTML entities:
z[x].textContent = '한국어';
But if you need to use HTML entities, just use innerHTML instead
z[x].innerHTML = kimchi.go(z[x].childNodes[0].data);
You can see the latter in the example below.
https://jsfiddle.net/nmL3to8w/1/

JS inserting substr(1) into a var

From an open code I have this line
var average = parseFloat($(this).attr('id').split('_')[0]),
It gets the first part of a div id with '_' as delimiter. The problem is that an id cannot start with a number (naming violation convention). So I am going to add a letter before the id value in my php script. How do I insert substr(1) to this var to remove this letter and get 'average' as expected?
Assuming you're talking about this format for an id:
<div id="A1000_bc"></div>
You can insert the substr(1) like this:
var average = parseFloat(this.id.split('_')[0].substr(1));
I might prefer to do it like this so it's a little less presumptious about the exact format and just grabs the first floating point numeric sequence:
var average = parseFloat(this.id.match(/[\d\.\+\-]+/)[0]);
Also, notice how I removed the jQuery. $(this).attr("id") performs a lot worse than this.id and offers no advantages here. jQuery should be used only when it's actually better than plain JS.
Both of these methods assume you are only going to present the code with properly formatted ids. If you want to handle a default condition when the id is not in the right format, then you will need multiple lines of code with some if conditions to check for validity and offer a default result when not valid.
Both options work here: http://jsfiddle.net/jfriend00/B4Rga/
Incidentally, if you control the HTML here, then there are better places to put data like this than in an id. I'd suggest a custom data attribute (HTML5 standard, but works everywhere).
<div id="whatever" data-avg="3.5"></div>
Then, you can get the data like this without having to parse it:
var average = parseFloat(this.getAttribute("data-avg"));
var average = parseFloat(
$(this) // you've got a jQuery object here - bad place
.attr('id') // you've got a string here - why not
.split('_') // you've got an array here - bad idea
[0] // you've got a string here - why not
// you need to have a number string here
);
Remeber: substr(1) can only be called on Strings.

How can spaces be converted to &nbsp without breaking HTML tags?

I've inherited some pretty complex code for a web forum, and one of the features I'm trying to implement is the ability for spaces to not be truncated into only one. This is mainly because our users often want to include ASCII art, tables etc in their posts.
I first did this using a simple search and replace in javascript, which had the side effect of breaking HTML tags (eg <a href=....> became <a href=.....>).
I then tried doing this on server side, when the strings are retrieved, by having spaces converted before links and code people insert is converted to HTML. This works to a degree but it causes some issues with other parts of the code, for example where a message is truncated to appear on the home page, it might leave some of the space code, such as
Here is a message&nb
I think there may be a way to just alter the original javascript to achieve this - it just needs to only match spaces that are not inside a HTML tag.
The script I was using originally was message = message.replace(/\s/g, " ").
Thanks for any help you can provide with this.
You can use the pre element to include preformatted text, which renders spaces as-is. See http://www.w3.org/TR/html5-author/the-pre-element.html
Those docs specifically say one of the best uses of the pre element is "Displaying ASCII art".
Example: http://jsbin.com/owuruz/edit#preview
<pre>
/\_/\
____/ o o \
/~____ =ø= /
(______)__m_m)
</pre>
In your case, just put your message inside a pre tag.
Yes, but you need to process text content of elements, not all of the HTML document content. Moreover, you need to exclude style and script element content. As you can limit yourself to things inside the body element, you could use a recursive function like following, calling it with process(document.body) to apply it to the entire document (but you probably want to apply it to a specific element only):
function process(element) {
var children = element.childNodes;
for(var i = 0; i < children.length; i++) {
var child = children[i];
if(child.nodeType === 3) {
if(child.data) {
child.data = child.data.replace(/[ ]/g, "\xa0");
}
} else if(child.tagName != "SCRIPT") {
process(child);
}
}
}
(No reason to use the entity reference here; you can use the no-break space character U+00A0 itself, referring to it as "\xa0" in JavaScript.)
One way is to use <pre> tags to wrap your users posts so that their ASCII art is preserved. But why not use Markdown (like Stackoverflow does). There's a couple of different ports of Markdown to Javascript:
Showdown
WMD
uedit

Interactive string manipulation via javascript

I have a webapp that must allow users to interactively manipulate strings (words, phrases and so on...)
Example:
given a foobar string, if the user clicks on b the string is split in two and a whitespace is added, resulting in foo bar.
I could put each single character inside a span element, but I fear this would be troublesome for long strings.
Any advice?
This version using jQuery (not necessary) should pretty much do what you need if I understood you correctly:
// Given a textarea with the content
var text = $('textarea').text().split('');
$('textarea').click(function(){
text.splice(this.selectionStart, 0, " ");
this.value = text.join('');
});
It's a very simple and not cross browser enabled example, but it should get you started.
Yes, it will be ok, but setup your event handler not on individual spans, but on the whole container and then see here: http://en.wikipedia.org/wiki/Flyweight_pattern

How to decode HTML entities using jQuery?

How do I use jQuery to decode HTML entities in a string?
Security note: using this answer (preserved in its original form below) may introduce an XSS vulnerability into your application. You should not use this answer. Read lucascaro's answer for an explanation of the vulnerabilities in this answer, and use the approach from either that answer or Mark Amery's answer instead.
Actually, try
var encodedStr = "This is fun & stuff";
var decoded = $("<div/>").html(encodedStr).text();
console.log(decoded);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div/>
Without any jQuery:
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
console.log(decodeEntities('1 & 2')); // '1 & 2'
This works similarly to the accepted answer, but is safe to use with untrusted user input.
Security issues in similar approaches
As noted by Mike Samuel, doing this with a <div> instead of a <textarea> with untrusted user input is an XSS vulnerability, even if the <div> is never added to the DOM:
function decodeEntities(encodedString) {
var div = document.createElement('div');
div.innerHTML = encodedString;
return div.textContent;
}
// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')
However, this attack is not possible against a <textarea> because there are no HTML elements that are permitted content of a <textarea>. Consequently, any HTML tags still present in the 'encoded' string will be automatically entity-encoded by the browser.
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}
// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))
Warning: Doing this using jQuery's .html() and .val() methods instead of using .innerHTML and .value is also insecure* for some versions of jQuery, even when using a textarea. This is because older versions of jQuery would deliberately and explicitly evaluate scripts contained in the string passed to .html(). Hence code like this shows an alert in jQuery 1.8:
//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();
//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
* Thanks to Eru Penkman for catching this vulnerability.
Like Mike Samuel said, don't use jQuery.html().text() to decode html entities as it's unsafe.
Instead, use a template renderer like Mustache.js or decodeEntities from #VyvIT's comment.
Underscore.js utility-belt library comes with escape and unescape methods, but they are not safe for user input:
_.escape(string)
_.unescape(string)
I think you're confusing the text and HTML methods. Look at this example, if you use an element's inner HTML as text, you'll get decoded HTML tags (second button). But if you use them as HTML, you'll get the HTML formatted view (first button).
<div id="myDiv">
here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
Results here !
</div>
First button writes : here is a HTML content.
Second button writes : here is a <B>HTML</B> content.
By the way, you can see a plug-in that I found in jQuery plugin - HTML decode and encode that encodes and decodes HTML strings.
The question is limited by 'with jQuery' but it might help some to know that the jQuery code given in the best answer here does the following underneath...this works with or without jQuery:
function decodeEntities(input) {
var y = document.createElement('textarea');
y.innerHTML = input;
return y.value;
}
You can use the he library, available from https://github.com/mathiasbynens/he
Example:
console.log(he.decode("Jörg &amp Jürgen rocked to & fro "));
// Logs "Jörg & Jürgen rocked to & fro"
I challenged the library's author on the question of whether there was any reason to use this library in clientside code in favour of the <textarea> hack provided in other answers here and elsewhere. He provided a few possible justifications:
If you're using node.js serverside, using a library for HTML encoding/decoding gives you a single solution that works both clientside and serverside.
Some browsers' entity decoding algorithms have bugs or are missing support for some named character references. For example, Internet Explorer will both decode and render non-breaking spaces ( ) correctly but report them as ordinary spaces instead of non-breaking ones via a DOM element's innerText property, breaking the <textarea> hack (albeit only in a minor way). Additionally, IE 8 and 9 simply don't support any of the new named character references added in HTML 5. The author of he also hosts a test of named character reference support at http://mathias.html5.org/tests/html/named-character-references/. In IE 8, it reports over one thousand errors.
If you want to be insulated from browser bugs related to entity decoding and/or be able to handle the full range of named character references, you can't get away with the <textarea> hack; you'll need a library like he.
He just darn well feels like doing things this way is less hacky.
encode:
$("<textarea/>").html('<a>').html(); // return '<a&gt'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
decode:
$("<textarea/>").html('<a&gt').val() // return '<a>'
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea/>
Try this :
var htmlEntities = "<script>alert('hello');</script>";
var htmlDecode =$.parseHTML(htmlEntities)[0]['wholeText'];
console.log(htmlDecode);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
parseHTML is a Function in Jquery library and it will return an array that includes some details about the given String..
in some cases the String is being big, so the function will separate the content to many indexes..
and to get all the indexes data you should go to any index, then access to the index called "wholeText".
I chose index 0 because it's will work in all cases (small String or big string).
Use
myString = myString.replace( /\&/g, '&' );
It is easiest to do it on the server side because apparently JavaScript has no native library for handling entities, nor did I find any near the top of search results for the various frameworks that extend JavaScript.
Search for "JavaScript HTML entities", and you might find a few libraries for just that purpose, but they'll probably all be built around the above logic - replace, entity by entity.
I just had to have an HTML entity charater (⇓) as a value for a HTML button. The HTML code looks good from the beginning in the browser:
<input type="button" value="Embed & Share ⇓" id="share_button" />
Now I was adding a toggle that should also display the charater. This is my solution
$("#share_button").toggle(
function(){
$("#share").slideDown();
$(this).attr("value", "Embed & Share " + $("<div>").html("⇑").text());
}
This displays ⇓ again in the button. I hope this might help someone.
You have to make custom function for html entities:
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g,'>').replace(/"/g, '"');
}
Suppose you have below String.
Our Deluxe cabins are warm, cozy & comfortable
var str = $("p").text(); // get the text from <p> tag
$('p').html(str).text(); // Now,decode html entities in your variable i.e
str and assign back to tag.
that's it.
For ExtJS users, if you already have the encoded string, for example when the returned value of a library function is the innerHTML content, consider this ExtJS function:
Ext.util.Format.htmlDecode(innerHtmlContent)
Extend a String class:
String::decode = ->
$('<textarea />').html(this).text()
and use as method:
"<img src='myimage.jpg'>".decode()
You don't need jQuery to solve this problem, as it creates a bit of overhead and dependency.
I know there are a lot of good answers here, but since I have implemented a bit different approach, I thought to share.
This code is a perfectly safe security-wise approach, as the escaping handler depends on the browser, instead on the function. So, if some vulnerability will be discovered in the future, this solution is covered.
const decodeHTMLEntities = text => {
// Create a new element or use one from cache, to save some element creation overhead
const el = decodeHTMLEntities.__cache_data_element
= decodeHTMLEntities.__cache_data_element
|| document.createElement('div');
const enc = text
// Prevent any mixup of existing pattern in text
.replace(/⪪/g, '⪪#')
// Encode entities in special format. This will prevent native element encoder to replace any amp characters
.replace(/&([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+);/gi, '⪪$1⪫');
// Encode any HTML tags in the text to prevent script injection
el.textContent = enc;
// Decode entities from special format, back to their original HTML entities format
el.innerHTML = el.innerHTML
.replace(/⪪([a-z1-8]{2,31}|#x[0-9a-f]+|#\d+)⪫/gi, '&$1;')
.replace(/⪪#/g, '⪪');
// Get the decoded HTML entities
const dec = el.textContent;
// Clear the element content, in order to preserve a bit of memory (in case the text is big)
el.textContent = '';
return dec;
}
// Example
console.log(decodeHTMLEntities("<script>alert('&awconint;&CounterClockwiseContourIntegral;∳∳⪪#x02233⪫');</script>"));
// Prints: <script>alert('∳∳∳∳⪪#x02233⪫');</script>
By the way, I have chosen to use the characters ⪪ and ⪫, because they are rarely used, so the chance of impacting the performance by matching them is significantly lower.
Here are still one problem:
Escaped string does not look readable when assigned to input value
var string = _.escape("<img src=fake onerror=alert('boo!')>");
$('input').val(string);
Exapmle: https://jsfiddle.net/kjpdwmqa/3/
Alternatively, theres also a library for it..
here, https://cdnjs.com/libraries/he
npm install he //using node.js
<script src="js/he.js"></script> //or from your javascript directory
The usage is as follows...
//to encode text
he.encode('© Ande & Nonso® Company LImited 2018');
//to decode the
he.decode('© Ande & Nonso® Company Limited 2018');
cheers.
To decode HTML Entities with jQuery, just use this function:
function html_entity_decode(txt){
var randomID = Math.floor((Math.random()*100000)+1);
$('body').append('<div id="random'+randomID+'"></div>');
$('#random'+randomID).html(txt);
var entity_decoded = $('#random'+randomID).html();
$('#random'+randomID).remove();
return entity_decoded;
}
How to use:
Javascript:
var txtEncoded = "á é í ó ú";
$('#some-id').val(html_entity_decode(txtEncoded));
HTML:
<input id="some-id" type="text" />
The easiest way is to set a class selector to your elements an then use following code:
$(function(){
$('.classSelector').each(function(a, b){
$(b).html($(b).text());
});
});
Nothing any more needed!
I had this problem and found this clear solution and it works fine.
I think that is the exact opposite of the solution chosen.
var decoded = $("<div/>").text(encodedStr).html();

Categories

Resources