I am working with an HTML table structure that contains values of text and integer. My goal is to identify which cells contain integer values and replace them with their value times -1. For instance:
This Year | 5 | 4 | -12
Last Year | 2 | 2 | 20
Would be updated to:
This Year | -5 | -4 | 12
Last Year | -2 | -2 | -20
Ideally, I would accomplish this with one line of JavaScript/jQuery. The line I am working with is:
$(".value-cell").filter(function( index ) {return $.isNumeric($(this).text());}).text(parseFloat($(this).text())*-1);
However, this line just fills the cells with NaN. I have tried a few variations of this but have not been able to accomplish what I am looking for.
UPDATE:
I should note, the filtration is working as expected and hitting the cells I want it to. I believe the problem lies with accessing $(this) in the text assignment, however, I am unsure of how else to access the text of the HTML element to multiply by -1.
Pass a function to .text() to have it operate on each element.
$(".value-cell").filter(function(index) {
return $.isNumeric($(this).text());
}).text(function(i, txt) {
return parseFloat(txt) * -1;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class=value-cell>abc</div>
<div class=value-cell>123</div>
And if you don't need the filtered set after this, you can get rid of the .filter() call and make the new value conditional.
$(".value-cell").text(function(i, txt) {
return $.isNumeric(txt) ? parseFloat(txt) * -1 : txt;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class=value-cell>abc</div>
<div class=value-cell>123</div>
And of course, a modern syntax solution with no jQuery dependency could look like this:
for (const el of document.querySelectorAll(".value-cell")) {
const t = el.textContent;
el.textContent = !t || isNaN(t) ? t : +t;
}
<div class=value-cell>abc</div>
<div class=value-cell>123</div>
Related
Hey so i've something like that
var zxc1 = 1846;
var zxc2 = 1649;
var zxc3 = 174;
var zxc4 = 27;
if(message.toLowerCase() == ('!asd')) { client.say(channel, `zxc1` +`(${+ zxc1.toLocaleString()})` +` | zxc2 `+`(${+ zxc2.toLocaleString()})` +` | zxc3 ` +`(${+ zxc3.toLocaleString()})` +` | zxc4 ` +`(${+ zxc4.toLocaleString()})` +` | :) `);}
After typing !asd:
Result : zxc1(NaN) | zxc2 (NaN) | zxc3 (174) | zxc4 (27) | 2
what's the problem?
Why is zxc3 and zxc4 working but zxc1 and zxc2 no
In ${+ zxc1.toLocaleString()} the + will be applying on the result of zxc1.toLocaleString() to coerce it back to a number (which seems counterproductive).
If you are not sure if something is a number I do recommend you use the number function e.g. ${Number(zxc1).toLocaleString()} rather than using +
The reason why 3 and 4 are working is because (most likely) your locale adds a thousands separator and so 1 and 2 are not castable back to numbers directly
(If the following question has English errors, tell me and I'll correct them.)
Hey, I have to do a project using Pug, I've done everything but now I'm stuck because I have to get a variable from the pug render to use it and show only 1 row when I click on the change button of my list.
At the start of my code, there's a script part with a function getValue,
script(src='book_list.js')
script
| function getValue(value){
| const hello = document.getElementById("test")
| $('#exampleModalLong').modal('show')
| hello.innerHTML = value
| window.test = value
| console.log(hello)
| alert(window.test)
| console.log(hello.innerHTML)
| }
When I use the function, the hello.innerHTML is printed on the console, but when I use the same document.getElementById("test").innerHTML, it makes an error.
each book in message
- var testISBN = document.getElementById("test").innerHTML;
if !{testISBN} != book.isbn
each val in book
p
hr
hr
img(src="", alt="")
label.col-form-label(for='recipient-name') #{val}
input#recipient-name.form-control(type='text' value=`${val}`)
And the result is :
58| .form-group
59| each book in message
> 60| - var testISBN = document.getElementById("test") .innerHTML;
61| if !{testISBN} != book.isbn
62| each val in book
63| p
Cannot read property 'getElementById' of undefined
Also can someone tell me if I used the unescaped string interpolation correctly in the line below ? Thanks for your help
Can you possibly do something like this in angular?
It's not quite possible to do this, as doesn't parse tags or something
{{ 10000 | currency:"<span>$</span>" }}
http://plnkr.co/edit/WluYoe2Ltmhmhvr8BBWX?p=preview
let alone somehow separate decimal number..
The ideal result would be
1 000 000<span class="dec">,00</span><span class="cur">€</span>
It's not really possible to do with any filter settings is it..?
I could try and modify angular's currency filter and the formatNumber function, but it still would take it as a text rather than a span element.
// edit
you can actually do this http://plnkr.co/edit/dcEhHi8sp43564ZvC4D1?p=preview
<p ng-bind-html-unsafe="10000 | currency:'<span>$</span>'"></p>
still clueless about decimals though
You can create a custom filter
app.filter('euro', function () {
return function (text) {
text = text.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 ");
var t = text + '<span class="desc">,00</span><span class="cur">€</span>';
return t;
};
});
<span ng-bind-html-unsafe="1000000 | euro"></span>
The result will be
1 000 000,00€
Working Demo
(The regex is posted by #Paul Creasey in his answer https://stackoverflow.com/a/1990554/304319)
It's actually possible to do this
<p ng-bind-html-unsafe="10000 | currency:'<span>$</span>'"></p>
or wrap it around the native currency filter like this
app.filter('currencys', ['$filter', '$locale',
function($filter, $locale) {
return function (num) {
var sym = $locale.NUMBER_FORMATS.CURRENCY_SYM;
return $filter('currency')(num, '<span>'+ sym +'</span>');
};
}
]);
and then use it like this
<span ng-bind-html-unsafe="10000 | currencys"></span>
Some locales have the currency sign prefixed, some postfixed, e.g. "one hundred euros" would be rendered "€ 100" or "100 €". What then?
If you don't mind doing some parsing, however read on:
The $locale service contains the symbols required for currency formatting:
$locale.NUMBER_FORMATS.CURRENCY_SYM
$locale.NUMBER_FORMATS.DECIMAL_SEP
(And there is more detailed info in $locale.NUMBER_FORMATS.PATTERNS[] - the value at position [1] is for currencies)
You could create a directive that uses the currency filter to obtain the initial formatted string, e.g. "1 000 000,50 €" then search for $locale.NUMBER_FORMATS.CURRENCY_SYM and replace it with <span>{{ $locale.NUMBER_FORMATS.CURRENCY_SYM }}</span>, do something similar for the decimal separator and then set the innerHTML of an element.
I have a template binding that displays a model attribute called 'date' which is a date, using Angular's date filter.
<span class="gallery-date">{{gallery.date | date:'mediumDate'}}</span>
So far so good. However at the moment, if there is no value in the date field, the binding displays nothing. However, I would like it to display the string 'Various' if there is no date.
I can get the basic logic using a binary operator:
<span class="gallery-date">{{gallery.date || 'Various'}}</span>
However I can't get it to work with the date filter:
<span class="gallery-date">{{gallery.date | date:'mediumDate' || "Various"}}</span>
How can I use the binary operator alongside the date filter?
Turns out all I needed to do was wrap the left-hand side of the expression in soft brackets:
<span class="gallery-date">{{(gallery.date | date:'mediumDate') || "Various"}}</span>
I made the following filter:
angular.module('app').filter('ifEmpty', function() {
return function(input, defaultValue) {
if (angular.isUndefined(input) || input === null || input === '') {
return defaultValue;
}
return input;
}
});
To be used like this:
<span>{{aPrice | currency | ifEmpty:'N/A'}}</span>
<span>{{aNum | number:3 | ifEmpty:0}}</span>
Just in case you want to try something else. This is what worked for me:
Based on Ternary Operator which has following structure:
condition ? value-if-true : value-if-false
As result:
{{gallery.date?(gallery.date | date:'mediumDate'):"Various" }}
How can I use the binary operator alongside the date filter?
<span class="gallery-date">{{gallery.date | date:'mediumDate' || "Date Empty"}}</span>
you also try:
<span class="gallery-date">{{ gallery.date == 'NULL' ? 'mediumDate' : "gallery.date"}}</span>
I really liked this answer, with ngBind, your default text can just live in the element body, and then if the ngBind evaluates to something non-null/undefined, your content is replaced automatically, and everythings happy
angularjs setting default values to display before evaluation
In your cshtml,
<tr ng-repeat="value in Results">
<td>{{value.FileReceivedOn | mydate | date : 'dd-MM-yyyy'}} </td>
</tr>
In Your JS File, maybe app.js,
Outside of app.controller, add the below filter.
Here the "mydate" is the function which you are calling for parsing the date.
Here the "app" is the variable which contains the angular.module
app.filter("mydate", function () {
var re = /\/Date\(([0-9]*)\)\//;
return function (x) {
var m = x.match(re);
if (m) return new Date(parseInt(m[1]));
else return null;
};
});
How would you proceed to transform this :
<pre>
key 1 value 1
key 2 value 2
value 2.2
key 3 value 3
value 3.1
value 3.2
value 3.3
key 4 value4.1 value4.5
</pre>
To this :
<div><pre>
key 1 value 1
</pre></div><div><pre>
key 2 value 2
value 2.2
</pre></div><div><pre>
key 3 value 3
value 3.1
value 3.2
value 3.3
</pre></div><div><pre>
key 4 value4.1 value4.5
</pre></div>
Namely : remplacing continuous blank line*s* (could contains space/tabs and multiples linefeed) to </pre></div><div><pre>
I tried :
var txt = $('pre').text();
txt = txt.replace(/(\r\n|\n|\r)/gm, "</pre></div><div><pre>");
$('div#test').append(txt);
Partially work : each line are changed, I loose my blocks.
Are <pre> line break stocked as \r ? \n ? (all OS? all browsers?)
What would be a good regex to do this?
Any other way you would suggest me to proceed with?
parse the text so you get a list of lines of text
trim each line
wrap each line in <div><pre> tags
concatenate the results together
I would do a remove of the prexisting pre element altogether after parsing out the text. So instead of "transforming" it just extract the text and build a different element altogether.
That does it for me. It could be better:
$(document).ready(function(){
var lines = $('pre').html().split(/\n\s*\n/);
$('pre').remove();
for(i = 0; i < lines.length; i++){
if($.trim(lines[i].length) > 0){
var preDiv = $('<pre />');
var keyDiv = $('<div />');
preDiv.append(keyDiv);
keyDiv.html(lines[i]);
$('body').append(preDiv);
}
}
});
It doesnt address any whitespace. You can remove it with trim() in the line keyDiv.html("key" + $.trim(lines[i]))
You can use jQuery's wrap function
$('pre').text($.trim($(this).text()).wrap('<div></div>');