javascript dynamic css styling - javascript

I'm trying to get all characters after "."(dot) and set some styling to them with JavaScript.
Example: $10.12 . I want to set some styling to numbers "12".
I have this number dynamically created in phtml file inside span.
I tried something like this, but without success:
var aa = document.getElementById('testdiv').innerHTML; // gets my span
var bb = aa.toString().split(".")[1]; // gets all numbers after "."
bb.setAttribute("style","width: 500px;");
Thanks to everyone! You really helped me. I would vote for every answer, but unfortunately I can't vote yet.

Your mistake begins here:
var aa = document.getElementById('testdiv').innerHTML; // gets my span
That's not your span, but its HTML contents. To take care of setting the width, you need something like this instead:
var aa = document.getElementById('testdiv'); // gets my span
aa.style.width = "500px";

You can only apply styling to HTML elements, not text nodes.
Try this instead:
var elem = document.getElementById('testdiv');
var parts = elem.innerHTML.toString().split(".");
parts[1] = "<div style=\"width: 500px\">" + parts[1] + "</div>";
elem.innerHTML = parts.join(".");
I've used because it's immediately apparent that a style has been applied, but if you want the number to appear consistent, as in "$10.12" without the "12" on a new line, you will probably need to apply additional styles or rethink how you're outputting the HTML.

You cannot set style to the textNode, the work around is to create an element to wrap the character after "." by using span. The idea is simple. First split it by "." and check if it has "." inside, if yes, create an element to wrap it and set style. Finally, join it back by "."
var inner = document.getElementById('testdiv').innerHTML;
var arr = inner.toString().split(".");
if(arr.length > 1)
{
arr[1] = '<span style="display: inline-block; width: 500px;">' + arr[1] + '</span>';
}
newContent = arr.join(".");
document.getElementById('testdiv').innerHTML = newContent;

You could do something like this:
document.getElementById('testdiv').innerHTML = document.getElementById('testdiv').innerHTML.replace( /(\d+).(\d+)/, '$1.<span id="end">$2</span>' );
document.getElementById('end').style.fontWeight = 'bold';
jsFiddle example
Your example fails at bb.setAttribute since you're trying to set an attribute on a string instead of a node. What you need to do is essentially rebuild the 10.12 with <span> elements surrounding the text you want to alter, and then you can use other JavaScript methods to modify the styling. The method you were using was almost correct, except the last part won't work because the split() method returns a string, not a node.

You can do this with regexp:
onlyDigitsText = text.replace(/\.([0-9]*)/g, ".<span class='highlighted'>$1</span>");
JsFiddle example

Try
var elem = document.getElementById('testdiv');
elem.innerHTML = elem.innerHTML.replace( /(\d+)\.(\d+)/g, '$1.<span class="decimalPart">$2</span>' );
// (\d+) one or more digits
// \. a dot character. Must be escaped otherwise it means ANY character
// (\d+) one or more digits
// g regex flag to replace all instances, not just one.
Then in your css add styling for the decimalPart class
.decimalPart {
width: 500px;
}
This has the added advantage of separating your styles from your html.
UPDATE
Following your comment to get the character just before the number use
elem.innerHTML.replace( /(\s)([^\s\d]*?)(\d+)\.(\d+)/g, '$1<span class="currencySymbol">$2</span>$3.<span class="decimalPart">$4</span>' );
// (\s) space, tab, carriage return, new line, vertical tab, form feed
// ([\s\d]*?) any set of characters that are not a digit or the above zero or more times
// (\d+) one or more digits
// \. a dot character. Must be escaped otherwise it means ANY character
// (\d+) one or more digits
// g regex flag to replace all instances, not just one.
Please note I have made an allowance for currency symbols that take up more than a single character.

Related

Javascript regex For Removing height/width from style

Using HTMLFilter addrules in CKEDITOR, I'm trying to remove the height/width from the STYLE of plain text.
They don't return the actual object just plain text style so I really can't use jQuery or other DOM manipulation tools.
I have the below regex code that successfully removes HEIGHT and WIDTH but still leaves the actual dimensions.
I'm new to regular expressions so I'm sure it's something rather simple. Just not sure what.
Thank you.
var str = "width:100px;height:200px;float:left;";
var regex = /(height|width):(?=(.*?);)/gi;
console.log(str.replace(regex,""));
You used a lookahead, and it is a non-consuming pattern, i.e. the text it matches does not become part of the whole match value. Thus, it does not get removed
Use a pattern like
/(?:height|width):[^;]*;/gi
See the regex demo.
Details
(?:height|width) - a non-capturing group matching either height or width
: - a colon
[^;]* - a negated character class matching 0+ chars other than ;
; - a semi-colon.
See JS demo:
var str = "width:100px;height:200px;float:left;";
var regex = /(?:height|width):[^;]*;/gi;
console.log(str.replace(regex,""));
A non-regex solution with javascript built-ins methods to remove the height/width from the STYLE of plain text.
function isNotWidthHeight(style) {
return style.toLowerCase().indexOf("width") === -1 && style.toLowerCase().indexOf("height") === -1 && style;
}
var str = "margin:0 auto;width:100px;height:200px;float:left;";
var array = str.split(';').filter(isNotWidthHeight);
console.log(array.join(';'));
You need to capture the values too.
.*? instead of (?=(.*?);) will be enough.
var str = "width:100px;height:200px;float:left;";
var regex = /(height|width):.*?;/gi;
console.log(str.replace(regex,""));
Pretty close, you just need an extra group and something to wait until either ; or word boundary, \b. This will grab any setting including calc or whatever settings can follow until the ; or end of inline style.
var str = "width:100px;height:200px;float:left;";
var str2 = "width:calc(100vh - 20px);height:100%;float:left;";
var regex = /((width|height):[\s\S]+?;|\b)/gi;
console.log(str.replace(regex,""));
console.log(str2.replace(regex,""));

Why am I not able to insert text nodes which only have zero width whitespaces set?

I am trying to insert whitespace text nodes using JS but it's simply not working. Is the innerHtml property getting ignored for a TextNode?
See my JSFiddle
insertWhitespace = function() {
var contentEditable = document.getElementById("txt");
var element = document.getElementById("annyoing-html");
var textNodeLeft = document.createTextNode("");
var textNodeRight = document.createTextNode("");
textNodeLeft.innerHtml = "​";
textNodeRight.innerHtml = "​";
contentEditable.insertBefore(textNodeLeft, element);
if(element.nextSibling != null) {
contentEditable.insertBefore(textNodeRight, element.nextSibling);
} else {
element.appendChild(textNodeRight);
}
};
I actually plan to insert zero whitespace characters but it's not working like this anyway.
How can I insert such text nodes?
HTML entities (&entity;-formatted strings) are, shockingly, for HTML.
For JavaScript, you need to use JavaScript escape sequences.
In this case, non-breaking space, which is \xA0
However, it is very bad practice to chain NBSPs together to artificially create space. You should be using margins, padding, positioning... ANYTHING, so long as it's CSS. Spacing is part of presentation, and presentation is the job of CSS.
For completeness, you can use normal spaces (" ") provided you set the container's CSS to include white-space: pre-wrap to make the whitespace significant.
Text nodes do not have a .innerHTML property (nb: note the case)
The simplest solution is to simply specify the right content as Unicode literals when you create the elements:
var textNodeLeft = document.createTextNode("\u200b");
var textNodeRight = document.createTextNode("\u200b");
As has been stated before, is a HTML entity. You are trying to fill a text node, not HTML.
Therefore, to fill a "non-breaking whitespace" ( ) into a text node, you can use its unicode character code:
var textNode = document.createTextNode("\xA0");
// or
var textNode2 = document.createTextNode("");
textNode2.data = "\xA0"; // or
textNode2.textContent = "\xA0";
Yes, text nodes don't have the .innerHTML property. Only HTMLElements do.
So, this will work:
var textNodeLeft = document.createElement("span");
textNodeLeft.innerHTML = " ";

Get javascript node raw content

I have a javascript node in a variable, and if I log that variable to the console, I get this:
"​asekuhfas eo"
Just some random string in a javascript node. I want to get that literally to be a string. But the problem is, when I use textContent on it, I get this:
​asekuhfas eo
The special character is converted. I need to get the string to appear literally like this:
​asekuhfas eo
This way, I can deal with the special character (recognize when it exists in the string).
How can I get that node object to be a string LITERALLY as it appears?
As VisionN has pointed out, it is not possible to reverse the UTF-8 encoding.
However by using charCodeAt() you can probably still achieve your goal.
Say you have your textContent. By iterating through each character, retrieving its charCode and prepending "&#" as well as appending ";" you can get your desired result. The downside of this method obviously being that you will have each and every character in this annotation, even those do not require it. By introducing some kind of threshold you can restrict this to only the exotic characters.
A very naive approach would be something like this:
var a = div.textContent;
var result = "";
var treshold = 1000;
for (var i = 0; i < a.length; i++) {
if (a.charCodeAt(i) > 1000)
result += "&#" + a.charCodeAt(i) + ";";
else
result += a[i];
}
textContent returns everything correctly, as ​ is the Unicode Character 'ZERO WIDTH SPACE' (U+200B), which is:
commonly abbreviated ZWSP
this character is intended for invisible word separation and for line break control; it has no width, but its presence between two characters does not prevent increased letter spacing in justification
It can be easily proven with:
var div = document.createElement('div');
div.innerHTML = '​xXx';
console.log( div.textContent ); // "​xXx"
console.log( div.textContent.length ); // 4
console.log( div.textContent[0].charCodeAt(0) ); // 8203
As Eugen Timm mentioned in his answer it is a bit tricky to convert UTF characters back to HTML entities, and his solution is completely valid for non standard characters with char code higher than 1000. As an alternative I may propose a shorter RegExp solution which will give the same result:
var result = div.textContent.replace(/./g, function(x) {
var code = x.charCodeAt(0);
return code > 1e3 ? '&#' + code + ';' : x;
});
console.log( result ); // "​xXx"
For a better solution you may have a look at this answer which can handle all HTML special characters.

Javascript regexp replace, multiline

I have some text content (read in from the HTML using jQuery) that looks like either of these examples:
<span>39.98</span><br />USD
or across multiple lines with an additional price, like:
<del>47.14</del>
<span>39.98</span><br />USD
The numbers could be formatted like
1,234.99
1239,99
1 239,99
etc (i.e. not just a normal decimal number). What I want to do is get just whatever value is inside the <span></span>.
This is what I've come up with so far, but I'm having problems with the multiline approach, and also the fact that there's potentially two numbers and I want to ignore the first one. I've tried variations of using ^ and $, and the "m" multiline modifier, but no luck.
var strRegex = new RegExp(".*<span>(.*?)</span>.*", "g");
var strPrice = strContent.replace(strRegex, '$1');
I could use jQuery here if there's a way to target the span tag inside a string (i.e. it's not the DOM we're dealing with at this point).
You could remove all line breaks from the string first and then run your regex:
strContent = strContent.replace(/(\r\n|\n|\r)/gm,"");
var strRegex = new RegExp(".*<span>(.*?)</span>.*", "g");
var strPrice = strContent.replace(strRegex, '$1');
This is pretty easy with jQuery. Simply wrap your HTML string inside a div and use jQuery as usual:
var myHTML = "<span>Span 1 HTML</span><span>Span 2 HTML</span><br />USD";
var $myHTML = $("<div>" + myHTML + "</div>");
$myHTML.find("span").each(function() {
alert($(this).html());
});
Here's a working fiddle.
try using
"[\s\S]*<span>(.*?)</span>[\s\S]*"
instead of
".*<span>(.*?)</span>.*"
EDIT: since you're using a string to define your regex don't forget to esacpe your backslashes, so
[\s\S]
would be
[\\s\\S]
You want this?
var str = "<span>39.98</span><br />USD\n<del>47.14</del>\n\n<span>40.00</span><br />USD";
var regex = /<span>([^<]*?)<\/span>/g;
var matches = str.match(regex);
for (var i = 0; i < matches.length; i++)
{
document.write(matches[i]);
document.write("<br>");
}
Test here: http://jsfiddle.net/9LQGK/
The matches array will contain the matches. But it isn't really clear what you want. What does there's potentially two numbers and I want to ignore the first one means?

How to replace whitespaces using javascript?

I'm trying to remove the whitespaces from a textarea . The below code is not appending the text i'm selecting from two dropdowns. Can somebody tell me where i'd gone wrong? I'm trying to remove multiple spaces within the string as well, will that work with the same? Dont know regular expressions much. Please help.
function addToExpressionPreview() {
var reqColumnName = $('#ddlColumnNames')[0].value;
var reqOperator = $('#ddOperator')[0].value;
var expressionTextArea = document.getElementById("expressionPreview");
var txt = document.createTextNode(reqColumnName + reqOperator.toString());
if (expressionTextArea.value.match(/^\s+$/) != null)
{
expressionTextArea.value = (expressionTextArea.value.replace(/^\W+/, '')).replace(/\W+$/, '');
}
expressionTextArea.appendChild(txt);
}
> function addToExpressionPreview() {
> var reqColumnName = $('#ddlColumnNames')[0].value;
> var reqOperator = $('#ddOperator')[0].value;
You might as well use document.getElementById() for each of the above.
> var expressionTextArea = document.getElementById("expressionPreview");
> var txt = document.createTextNode(reqColumnName + reqOperator.toString());
reqOperator is already a string, and in any case, the use of the + operator will coerce it to String unless all expressions or identifiers involved are Numbers.
> if (expressionTextArea.value.match(/^\s+$/) != null) {
There is no need for match here. I seems like you are trying to see if the value is all whitespace, so you can use:
if (/^\s*$/.test(expressionTextArea.value)) {
// value is empty or all whitespace
Since you re-use expressionTextArea.value several times, it would be much more convenient to store it an a variable, preferably with a short name.
> expressionTextArea.value = (expressionTextArea.value.replace(/^\W+/,
> '')).replace(/\W+$/, '');
That will replace one or more non-word characters at the end of the string with nothing. If you want to replace multiple white space characters anywhere in the string with one, then (note wrapping for posting here):
expressionTextArea.value = expressionTextArea.value.
replace(/^\s+/,'').
replace(/\s+$/, '').
replace(/\s+/g,' ');
Note that \s does not match the same range of 'whitespace' characters in all browsers. However, for simple use for form element values it is probably sufficient.
Whitespace is matched by \s, so
expressionTextArea.value.replace(/\s/g, "");
should do the trick for you.
In your sample, ^\W+ will only match leading characters that are not a word character, and ^\s+$ will only match if the entire string is whitespace. To do a global replace(not just the first match) you need to use the g modifier.
Refer this link, you can get some idea. Try .replace(/ /g,"UrReplacement");
Edit: or .split(' ').join('UrReplacement') if you have an aversion to REs

Categories

Resources