We need to display currency amounts in a browser table and since those are numbers, they should be right aligned.
Problem is with currencies like Japan which do not have floating point currencies.
So for them, we cannot show 5.10 Yen
Now, the requirement is to show something like this:
(Note the alignment and the mixing of decimal currencies with non-decimal)
5.23
12.00
3.24
5
9
11.00
In the above, 5 and 9 are Japanese Yens while others are USD
So the requirement is to replace floating points with spaces for currencies like JPY. Spaces are required to have proper alignment of the currencies.
Offcourse, for other currencies, the 2 decimal places should be there.
Does anyone know how the above can be done?
Thanks a lot in advance!!
Based on the below replies:
1) The values are sent from a Java server and fed into a JavaScript library SlickGrid
2) We want to control values at the server level because the SlickGrid code is not very amenable for this kind of work.
3) Currencies are being stored as floats because customer wants to see them that way :( and that's kind of correct because mostly people are bothered about dollars not cents, but then, some people are concerned about cents too.
I was really hoping of some option with DecimalFormat only as that would have been the best solution.
Else I would have to resort to the ugly solution of parsing and string massaging.
Currency should never be stored as a floating point number. It should always be integer amounts of the lowest denomination you are working with (Yen, Cents, Paise).
If you need to work with amounts smaller than the lowest natural denomination, store currency as integer amounts representing multiples of a specified fraction. For example 6 tenths of a Yen.
As for the formatting, there is a discussion of simple options here.
following CSS is basically taken from the link in jsj's answer (extracting the most relevant portion)
HTML only version:
td { font-family: monospace; }
span.int {
text-align: right;
float: left;
width: 3em;
}
span.fractional {
text-align: left;
float: right;
width: 2em;
}
<table>
<tr><td><span class="int">5</span><span class="fractional">.23</span></td></tr>
<tr><td><span class="int">12</span><span class="fractional">.00</span></td></tr>
<tr><td><span class="int">3</span><span class="fractional">.24</span></td></tr>
<tr><td><span class="int">5</span><span class="fractional"></span></td></tr>
<tr><td><span class="int">9</span><span class="fractional"></span></td></tr>
<tr><td><span class="int">11</span><span class="fractional">.00</span></td></tr>
</table>
JavaScript version:
function spanInt(content){ var span = document.createElement('span');span.className = 'int'; span.textContent = content; return span; }
function spanFractional(content){ var span = document.createElement('span'); span.className = 'fractional'; span.textContent = content; return span;}
function tableCell_int(value){
var td = document.createElement('td');
td.appendChild(spanInt(value));
td.appendChild(spanFractional(''));
return td;
}
function tableCell_float(value){
var intPart = Math.floor(value);
var fracPart = value - intPart;
var td = document.createElement('td');
td.appendChild(spanInt(intPart));
td.appendChild(spanFractional('.' + Math.round(100*fracPart)));
return td;
}
function tr(cell){
var elt = document.createElement('tr');
elt.appendChild(cell);
return elt;
}
var theTable = document.getElementById('theTable');
function add_int(value){ theTable.appendChild(tr(tableCell_int(value))); }
function add_float(value){ theTable.appendChild(tr(tableCell_float(value))); }
add_float(5.23); add_float(12); add_float(3.24);
add_int(5); add_int(9); add_float(11);
td { font-family: monospace; }
span.int {
text-align: right;
float: left;
width: 3em;
}
span.fractional {
text-align: left;
float: right;
width: 2em;
}
<table id='theTable'></table>
Related
I try to do any less function which will be called to create some classes.
Here is the way I tried :
.makeCssColor{#couleur) {
.coul_#{couleur} {
background-color: fade(~"#{couleur}, 'Fonce'", 15%);
&.open, &:hover {
background-color: ~"#{couleur}, 'Fonce'";
}
.btMod {
background : url('/img/btModEvt_#{couleur}.png') left top no-repeat transparent;
}
}
}
And I try to call it to create the classes :
.makeCssColor("bleu");
.makeCssColor("rouge");
But it generate an error. I don't find the good way to do it... And it bothers me to repeat all these code for each color (there is more than these line code and more thant two colors !).
Can anyone give me a little help ? :)
[edit]
ok, thanks to your help, this code does not generate an error, but there is a mistake in the CSS file :
#marronFonce = #9d5a1e;
.makeCssColor(#couleur) {
.coul_#{couleur} {
.top {
background-color: #couleur, 'Fonce';
}
.mod {
background : url('/img/btModEvt_#{couleur}.png') left top no-repeat transparent;
}
}
}
.makeCssColor(marron);
Generate this into the css file :
.coul_marron .top{background-color:marron,'Fonce'}
.coul_marron background : url('/img/btModEvt_marron.png') left top no-repeat transparent;
So the background color isn't good :
.coul_marron .top{background-color:#9d5a1e}
.coul_marron background : url('/img/btModEvt_marron.png') left top no-repeat transparent;
I need to evaluate #couleur, 'Fonce' : #marronFonce => #9d5a1e.
I tried #{#couleur, 'Fonce'} but it doesn't works...
Fade function takes a colour and a fade percentage, in your case you are passing 2 colours. Pass them one at a time. I also made some adjustments on #couleur since i some cases they don't need to be escaped
.makeCssColor{#couleur) {
.coul_#{couleur} {
background-color: fade(#couleur, 15%), fade(Fonce, 15%);
&.open, &:hover {
background-color: #couleur, 'Fonce';
}
.btMod {
background : url('/img/btModEvt_#couleur.png') left top no-repeat transparent;
}
}
}
when you call the mixin use the below, no need to use quotes
.makeCssColor(bleu);
UPDATE - just pass it in
.makeCssColor(#couleur, #name) {
.coul_#{name} {
.top {
background-color: #couleur;
}
.mod {
background : url('/img/btModEvt_#{name}.png') left top no-repeat transparent;
}
}
}
then when you call it
.makeCssColor(#marronFonce, marron);
OR
other option is you can make a loop, it's more complicated but you can try it. I am using an example I already have on my computer
first define a variable with the colour and names
#sample:
~"0070" '#ebebe7',
~"08x2" '#00247a',
~"01k0" '#92918e';
then loops thru it
.sample-loop ( #l ) when ( #l > 0 ) {
#item: extract( #sample #l );
#code: extract( #item, 1 );
#colour: color(extract( #item, 2 ));
.ext-#{code} {
background-color: #colour;
}
.sample-loop( #l - 1 );
}
and finally call the loop to generate your classes
.sample-loop( 3 );
depending on which version of less you have, the 3 can coded so it is dynamic. If you have older version of less then you have to hard code the length of the variable, or assign the length to a variable so you can use it anywhere
I am trying to realize a modular approach to text sizing using the following starting variables:
#font-size: 1.7rem;
#line-height: 1.414;
I would like to write a mixin that would create this result but have not quite fully grasped LESS yet:
h4 {
font-size: #font-size * #line-height;
}
h3 {
font-size: (#font-size * #line-height) * #line-height;
}
h2 {
font-size: ((#font-size * #line-height) * #line-height) * #line-height;
}
h1 {
font-size: (((#font-size * #line-height) * #line-height) * #line-height) * #line-height;
}
You have an array with your selectors - #elements.
Then you get the length of #elements - it will be used as iterator through an array.
Then the loop starts. It has the name set-font-size. In Less loops are recursive mixins. This mixin takes some parameters and calls itself until some condition is correct. In this example, it works while #_i > 0. Every time it calls itself, the value of #_i decreases.
Inside mixin (or loop) you get current element from array by calling extract(#array, #index) command. Then you set the font size to your selector. Evry time mixin call itself, the value of font-size is increased #_font-size * #_line-height.
That's all :)
Codepen DEMO.
Less:
#elements: h1, h2, h3, h4;
#iterations: length(#elements); // lehgth of #elements
#font-size: 1.7rem;
#line-height: 1.414;
.set-font-size(#_i, #_elements, #_font-size, #_line-height) when (#_i > 0) {
#selector: extract(#_elements, #_i);
#{selector} {
font-size: #_font-size;
}
.set-font-size(#_i - 1, #_elements, #_font-size * #_line-height, #_line-height);
}
.set-font-size(#iterations, #elements, #font-size, #line-height);
Css output:
h4 {
font-size: 1.7rem;
}
h3 {
font-size: 2.4038rem;
}
h2 {
font-size: 3.3989732rem;
}
h1 {
font-size: 4.8061481rem;
}
I have a site running Bootstrap 3.3.7. I use less to adjust the styling. In version 4 of Bootstrap sass is introduced instead of less, and I noticed a new mixin which adds the ability to easily use predefined paddings and margins:
// Width
.w-100 { width: 100% !important; }
// Margin and Padding
.m-x-auto {
margin-right: auto !important;
margin-left: auto !important;
}
#each $prop, $abbrev in (margin: m, padding: p) {
#each $size, $lengths in $spacers {
$length-x: map-get($lengths, x);
$length-y: map-get($lengths, y);
.#{$abbrev}-a-#{$size} { #{$prop}: $length-y $length-x !important; } // a = All sides
.#{$abbrev}-t-#{$size} { #{$prop}-top: $length-y !important; }
.#{$abbrev}-r-#{$size} { #{$prop}-right: $length-x !important; }
.#{$abbrev}-b-#{$size} { #{$prop}-bottom: $length-y !important; }
.#{$abbrev}-l-#{$size} { #{$prop}-left: $length-x !important; }
// Axes
.#{$abbrev}-x-#{$size} {
#{$prop}-right: $length-x !important;
#{$prop}-left: $length-x !important;
}
.#{$abbrev}-y-#{$size} {
#{$prop}-top: $length-y !important;
#{$prop}-bottom: $length-y !important;
}
}
}
// Positioning
.pos-f-t {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: $zindex-navbar-fixed;
}
Source at GitHub
I would like to convert this mixin to less, and use it in my own Bootstrap 3.3.7 project. How would this mixin look like in less?
Less does not have any #each function or map like Sass does but even then converting this Sass code into its Less equivalent is fairly easy. All that is needed are a couple of loops each of which will mimic the two #each function in Sass and associative arrays.
In Less, we can use both comma and space as delimiters for values. So by using both of them we can achieve a behavior similar to that of maps. Even multi-level maps can be mimicked using this.
(Note: You need to know the basics of Less loops to understand this code but since you've already used Less, I assume that you are familiar with the concepts. If not, have a look at docs)
#props: margin m, padding p; /* the property and abbreviation */
#spacers: xs 10px 20px, md 20px 30px; /* the sizes, its length-x and length-y */
.loop-props(#prop-index) when (#prop-index > 0){ /* outer each loop */
#prop: extract(#props, #prop-index); /* get each prop-abbrev pair based on loop index */
#prop-name: extract(#prop, 1); /* the first value in each pair is the prop name */
#abbrev: extract(#prop, 2); /* the second value in each pair is the prop's abbrev */
/* call size loop mixin with each property name + abbreviation */
.loop-sizes(#prop-name; #abbrev; length(#spacers));
.loop-props(#prop-index - 1); /* call the next iteration of the outer each loop */
}
.loop-props(length(#props)) !important; /* initial mixin/loop call */
.loop-sizes(#prop-name; #abbrev; #size-index) when (#size-index > 0){ /* inner each */
#spacer: extract(#spacers, #size-index); /* extract each spacer value based on index */
#size: extract(#spacer, 1); /* first value in each spacer is the size */
#x: extract(#spacer, 2); /* second value is the length in X axis */
#y: extract(#spacer, 3); /* third value is the length in Y axis */
/* create the selectors and properties using interpolation */
.#{abbrev}-a-#{size} {
#{prop-name}: #y #x;
}
.#{abbrev}-t-#{size} {
#{prop-name}-top: #y;
}
.#{abbrev}-r-#{size} {
#{prop-name}-right: #x;
}
.#{abbrev}-b-#{size} {
#{prop-name}-bottom: #y;
}
.#{abbrev}-l-#{size} {
#{prop-name}-left: #x;
}
.#{abbrev}-x-#{size} {
#{prop-name}-right: #x;
#{prop-name}-left: #x;
}
.#{abbrev}-y-#{size} {
#{prop-name}-top: #y;
#{prop-name}-bottom: #y;
}
.loop-sizes(#prop-name; #abbrev; #size-index - 1); /* call next iteration */
}
As you'd have noticed, I have attached the !important to the mixin call itself instead of attaching it each property. When this is done, the Less compiler automatically attaches the !important to every property and so we needn't repeat it.
I'm trying to my grid system to LESS.
I'm using fractions as strings (there's a reason) and need to interpolate them in the calc() expression.
In Sass I can do this...
#mixin move($fraction: '1/1') {
position: relative;
left: calc(99.999999% * #{$fraction});
}
In LESS when I try this...
.move(#fraction: '1/1') {
#_fraction: ~'#{fraction}';
left: calc(99.999999% * #_fraction);
}
It ends up throwing a Cannot read property 'numerator' of undefined error.
Apparently LESS can tell it's a fraction but then it poops out.
Can any LESS pros enlighten me?
You need to escape multiplication, addition, division, and subtraction in LESS or it will try output the calculated result. When less sees * in your code, it is trying to multiply 99.999999% and #_fraction.
For example when LESS sees calc(5px + 5px); it will output left: calc(10px);. You can except it like this ~'calc(5px + 5px);'.
Try using this code.
.move(#fraction: '1/1') {
#_fraction: ~'#{fraction}';
left: calc(~'99.999999% *' #_fraction);
}
Is it possible to assign a variable based on another variable using less css?
pseudo code:
#userpick = red; /* this changes based on user pick */
#color1 = red;
#color2 = blue;
if( #userpick == #color1)
#systempick = #color2
else( #userpick == #color2)
#systempick = #color1
I want to be able to use #systempick as a color value not as a css style. For example:
border: 5px dashed #systempick;
Doesn't use a mixin, but resolves your desire
If the #userpick is stored as a string instead, then that could be used to access another variable name based off of it (a variable variable), like so:
LESS
#userpick: "blue"; /* this changes based on user pick, saved as a string */
#setopposite: "#{userpick}-opp";
//set opposing values
#red-opp: blue;
#blue-opp: red;
#systempick: ##setopposite;
.test {
color: #systempick;
}
CSS Output (note how blue outputs #ff0000, i.e. red)
/* this changes based on user pick */
.test {
color: #ff0000;
}
Since you are dealing with colors, the #userpick needs to be saved as a string because otherwise, LESS will automatically assign it a hex value rather than the color name.
You can use guards in mixins to change the color that is used, e.g.
.a when (#userpick = #color1) {
color: #color2;
}
.a when (#userpick = #color2) {
color: #color1;
}
You might get code duplication but its the only way to get an if statement.
Other ways are possible (e.g. inline javascript if using less.js or a function plugin if using dotless) but are probably a little hacky.
I was able to get what I needed, however this may not work on the PHP port of Less.
This was a bit tricky since you can assign variables only once. There are also some restrictions regarding scope of variables. I'm also comparing color values using HSV (hue, saturation, value)
.set_colors(#F00, #00F, #F00); /* pass red, blue and user pick */
.set_colors(#c1, #c2, #u) when (hue(#c1) = hue(#u)) and (saturation(#c1) = saturation(#u)) and (lightness(#c1) = lightness(#u)){
#color1 = #c1;
#color2 = #c2;
#userpick = #c1;
#systempick = #c2;
}
.set_colors(#c1, #c2, #u) when (hue(#c2) = hue(#u)) and (saturation(#c2) = saturation(#u)) and (lightness(#c2) = lightness(#u)){
#color1 = #c1;
#color2 = #c2;
#userpick = #c2;
#systempick = #c1;
}