Autoformat Numbers in an Interactive Grid
A lot of the applications I build allow users to enter large numbers of monetary amounts, and the way these numbers are presented can have an impact on how easy it is for them to read and check those numbers.
All such amounts are formatted for display using a system-wide standard format (in our case, the Australian standard
I would then simply add the class
edit_money to any item in the application and it would automatically apply the formatting; for example, if the user types in
12345.6, it changes the value to
If you want to skip to the punchline, scroll down past the next few paragraphs where I take you down a merry rabbit-hole that, as it turns out, was completely unnecessary (but still somewhat educational).
Now we’re on APEX 19.1 and starting to use Interactive Grids (IG) for a lot of new screens, but applying the edit_money class to the columns in the grid doesn’t work, because the edit item that is generated on-the-fly by the grid doesn’t [edit: I was wrong here] conform to the structure expected by my document-on-change function callback.
Aside: when Google failed me
this object that should give me access to the item’s value. I used a little trick to copy
this into a global variable and used the Chrome debug console to examine
this to see how to get the value of the cell being edited. Firstly, in the page Function and Global Variable Declaration I added
x=this. Running the page, I entered a value into the cell in the grid, opened the Chrome console, then typed “x”. Chrome immediately showed the structure of “x”:
That “triggeringElement” looks like it might be what I’m after, so I continued typing:
After finishing typing “.val()” it gave an error “val is not a function”. I’d seen other code around the place that converts triggeringElement to a jQuery object, so I tried that instead:
This spat out the number I’d entered. So initially I used
$(this.triggeringElement).val(). Later I did some more digging and realised I didn’t need jQuery here, I can use the
value attribute directly –
this.triggeringElement.value. I suspect this is one of those basic things that they teach you on day one of an “Intro to APEX Interactive Grids 101” class but I must have been sick that day 🙂
My final DA has the following attributes:
- Event = Change
- Selection Type = Column(s)
- Region = [the interactive grid region]
- Column(s) = [list of all the editable monetary columns]
- Action = Set Value
- Suppress Change Event = Yes
- Selection Type = Triggering Element
- Fire on Initialization = No
It’s not quite as simple as adding the class to all the items, but at least it’s just one dynamic action that I need to add to each interactive grid.
As pointed out by John, I went down this rabbit hole for one simple and annoying reason: I forgot that there are not one, but two “CSS Classes” attributes on each item, and I’d put my “edit_money” class in the wrong attribute.
29 May 2019 - 10:03 pm
A worthwhile journey but it shouldn’t be so difficult.
First wouldn’t it be great if IG just did this automatically? I think it should. If you give a format it should be used on the client side as well.
Your edit_money class should work with IG columns because they are just normal items. There are two CSS Classes attributes one under Appearance and one under Advanced. One applies to IG column and one applies to the column item. The PD help doesn’t make it easy to tell which is which. I just guess and check. You should add edit_money the one under advanced. I did this with your global event handler code and it worked.
The info on setValue triggering element is helpful. I think because it is an item using $v or apex.item().getValue() should be preferred over element.value or $().val() – just in case.