Rounding numbers in fields/lists

  • 1
  • Question
  • Updated 6 years ago
  • Answered
Many numeric and currency fields are by default using 2 decimals. However in many instances a truncated display showing only the integer part would look better in tables or field editor. How can this be done with SKUID?
Photo of Peter Baeza

Peter Baeza

  • 2,868 Points 2k badge 2x thumb

Posted 6 years ago

  • 1
Photo of Zach McElrath

Zach McElrath, Employee

  • 53,784 Points 50k badge 2x thumb
Official Response
The best way to do it would be to use a custom field renderer on those fields that you want to round to just the integer part / truncate. This field renderer will run all of the standard rendering logic, but will first override the metadata of the given field so that it will render as an integer.

Here's a Gist containing the code for this snippet... or see below.





Here's the body of the inline snippet:




var field = arguments[0],
value = arguments[1],
metadata = field.metadata,
dt = metadata.displaytype;

// For currency, double, and percent fields,
// manually override the field's metadata
// related to how many decimal points to display

if (dt == 'CURRENCY' || dt == 'DOUBLE' || dt == 'PERCENT') {
metadata.scale = 0;
}

// Run the field's default renderer
skuid.ui.fieldRenderers[dt][field.mode](field,value);

Photo of ktyler

ktyler

  • 9,334 Points 5k badge 2x thumb
Zach,
I take it you could use a similar snippet to intervene in any fields data entry... that is.. to process the value the user entered

is there somewhere where the available objects... i'm assuming that field.metadata is a skuid javascript object... are listed... a sort of javascrip api ?
Photo of Zach McElrath

Zach McElrath, Employee

  • 53,784 Points 50k badge 2x thumb
Ken, yes, there is a Skuid JavaScript API. We document much of it over on the Skuid Developer Guide under the "API" section, but there are some aspects that we have not officially documented yet.

In the context of this Snippet, "field" refers to an instance of the skuid.ui.Field object, which has, among many properties (which you can view by doing a JavaScript Console log, e.g. with console.log(field);), a property called "metadata". This essentially is a JavaScript version of the data returned in the Apex DescribeFieldResult for an SObjectField. As you can see by doing a console log on field.metadata, we provide most of the data in DescribeFieldResult, but not all of it.
Photo of Peter Baeza

Peter Baeza

  • 2,868 Points 2k badge 2x thumb
I tried to extend this example to do two things:

1: Right justify the numbers by adding CSS text align to the field. Works fine
2: Remove the currency prefix by changing CURRENCY displaytype to DOUBLE. Works partly.

The changing of displaytype works but not on the first row of the table. Why? And is there a better way to do this? If i edit the row and close it the currency prefix disappears but on refresh it appears again on the first row. Since the entire table is in one currency it just clutters the display to show this in every cell.

Modified code:

var field = arguments[0],
value = arguments[1],
metadata = field.metadata,
dt = metadata.displaytype;
field.element.css({'text-align': 'right'});

// For currency, double, and percent fields,
// manually override the field's metadata
// related to how many decimal points to display

if (dt == 'CURRENCY' || dt == 'DOUBLE' || dt == 'PERCENT') {
metadata.scale = 0;
if (dt == 'CURRENCY' ) {
metadata.displaytype = 'DOUBLE';
}
}

// Run the field's default renderer
skuid.ui.fieldRenderers[dt][field.mode](field,value);
Photo of Zach McElrath

Zach McElrath, Employee

  • 53,784 Points 50k badge 2x thumb
Peter, I think that the reason that it doesn't work on the first row of the table has to do with the "dt = metadata.displaytype" variable being a primitive (a String) and it being passed by value, not by reference --- just a JavaScript technicality that can easily be avoided. Just change this one line at the bottom:

skuid.ui.fieldRenderers[metadata.displaytype][field.mode](field,value);


This should work because field.metadata is an object, not a primitive, and its displaytype property will have been updated to 'DOUBLE' whereas the "dt" variable will, on the first row of the table, still refer to what it initially was, "CURRENCY".
Photo of Peter Baeza

Peter Baeza

  • 2,868 Points 2k badge 2x thumb
perfect, thanks that solved it
Photo of Peter Baeza

Peter Baeza

  • 2,868 Points 2k badge 2x thumb
Actually it would be nice to be able to include the currency with a template on the header instead. However it doesn't seem to work to use template merge fields for table fields. I guess this is because that would need to merge for every row in the table. But for example when displaying opportunity line items it would be nice to get the currency from the parent opportunity and merge with. Is this possible?
Photo of Zach McElrath

Zach McElrath, Employee

  • 53,784 Points 50k badge 2x thumb
Peter, can you ask this as a separate question on the community? This is an interesting idea that I think others would want to know how to do as well, but i think that if i answer it here, no one will find it :)
Photo of Peter Baeza

Peter Baeza

  • 2,868 Points 2k badge 2x thumb
sure
Photo of Glenn Elliott

Glenn Elliott, Champion

  • 7,768 Points 5k badge 2x thumb
Zach/Peter ... thanks for this script. Has been very useful for me.

A related question. I'm using this on a currency field that I have a summary at the bottom of. But the custom renderer isn't applying to the summary. Is there a small change that can make that happen? Also, it'd be nice to right align the field heading too if possible.

Screenshot below.

Thanks.

Photo of Anna Wiersema

Anna Wiersema, Alum

  • 10,920 Points 10k badge 2x thumb
Hi Glenn, I'm not sure about how to update the summary, but here is some CSS to make your table header text aligned right.
th {
     text-align: right;
}
Photo of Glenn Elliott

Glenn Elliott, Champion

  • 7,768 Points 5k badge 2x thumb
Thanks Anna. But just to be picky, I want to keep headers left aligned for all the other fields (to match their field contents) and right align the header and the summary for the currency field to match its right aligned field contents. I understand if this is one for the wish list!
Photo of Anna Wiersema

Anna Wiersema, Alum

  • 10,920 Points 10k badge 2x thumb
hmmm... i don't know how to do this myself with CSS, but I'll let you know if I find anything.
Photo of John Nelson

John Nelson, Product Manager

  • 3,356 Points 3k badge 2x thumb
Yep, that's no problem. Throw the following into an inline snippet and it'll switch the alignment for all of your summaries:

var $ = skuid.$;

$(function(){
$('td.nx-summary .nx-fieldtext').css('textAlign','right');
});


Now if you want to get rid of the "(sum)," that's requires a little more jQuery-ing. Basically, you'll need to remove the space after the number and the span containing the summary type. That's the reason for doing the preceding in JS and not CSS. If you don't care to remove the summary type you could just as easily use the same selector and css (substituting 'text-align') within a css resource.