Scott KlementDirector, Product Development and Support
Profound Logic
JSON and JavaScript Tips and Tricks
Copyright © 1999-2016
• Introduction To JavaScript and JSON
• How To Learn JavaScript
• How It Fits Into Profound UI
• Profound Events and APIs
• Debugging JavaScript
• Incorporating JavaScript Libraries
• Examples
• How JSON can Help Simplify
Session Agenda
Copyright © 1999-2016
What are JavaScript and JSON?
JavaScript
• Scripting language developed by Netscape
• Originally developed for use in web browsers to make screens more interactive
• Very, very popular, used in almost all web sites
• Also available outside of browsers (Node.js)
JSON
• JavaScript Object Notation
• Simple (or "shorthand") way to set values in JavaScript
• Now used separately from JavaScript as a document format
Copyright © 1999-2016
How Popular?
Top 9 languages (of
316 that GitHub
recognizes) shown
Copyright © 1999-2016
What JavaScript is NOT
"JavaScript is to Java what Hamster is to Ham"
Copyright © 1999-2016
We use it to create the products themselves
• Visual Designer, Genie, Atrium, Genie Admin, Mobile, etc.
Customers can use it as well
• Make your screens react as users use the mouse or keyboard
• Update screen without going back to server-side code
• Write your own "automatic" transforms in Genie
• Custom DDS Conversion
• Make your own widgets
• Incorporate 3rd party web frameworks and tools
• And so much more!
docs: http://www.profoundlogic.com/docs/display/PUI/JavaScript+Coding
Role in Profound UI displays
Copyright © 1999-2016
JavaScript is a complete programming language, and too much to learn in this session
• I can explain some basics
• If you know another language, it shouldn't be too hard to adapt
• I can provide links to where you can learn more
• Main focus is how to use it in Profound UI displays
• Profound UI displays usually use short/simple snippets of code
Resources for learning JavaScript
• W3 Schools Tutorial (online) http://www.w3schools.com/js/default.asp
• W3 Schools JavaScript Reference (online)
http://www.w3schools.com/jsref/default.asp
• SitePoint (books/e-books) https://www.sitepoint.com/
Learning JavaScript
Copyright © 1999-2016
Quick JavaScript Basics (1 of 3)
Declaring and Comparing
• declare a variable with var
• type of variable is determine by what is assigned to it – and can change.
• A single =means "assign value"
• Double == means "compare" data types will be converted if necessary
• Triple === means "compare" but result only matches if it’s the same data type
var myString = "Hello World";
var myNumber = 1;
var myArray = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ];
if ( myVariable == "something") {
doSomething();
}
else {
doSomethingElse();
}
if ( myNumber == "1" ) // works!
if ( myNumber === "1" ) // doesn't work, different types
Copyright © 1999-2016
Quick JavaScript Basics (2 of 3)
while ( myNumber > 1) {
// do something while myNumber > 1
}
do {
// do while myNumber > 1, test condition at end of loop.
}
while ( myNumber > 1 );
for (var x=1; x<=10; x++) {
// do something 10 times.
}
var employee_rec = {
first: "Scott",
last: "Klement",
num: 1000
}
for (field in employee_rec) {
// do something for each field in an "object" (data structure)
console.log(field + " = " + employee_rec[field]);
}
Copyright © 1999-2016
Quick JavaScript Basics (3 of 3)
function printSomething( something ) {
console.log(something);
}
// prints "Hello World"
printSomething("Hello World");
// functions can be variables – allow for "callbacks"
// this function automatically calls a routine "num" times.
function repeat( num, callback ) {
for (var x=1; x<=num; x++) {
callback(x);
}
}
// this will print 1-5 on the console display
repeat( 5, printSomething);
// anonymous functions are functions defined on-the-fly just to assign
// to variables or parameters. This prints 1-5 with "call number" before it.
repeat( 5, function(n) { printSomething("call number " + n)});
Copyright © 1999-2016
Tutorials and Books Assume You Write HTML Manually
Consider this example from W3Schools.com's JavaScript Tutorial;
In Profound UI, you drag/drop widgets to make your screen rather than coding HTML. So how
would you use this example in a Profound UI Display?
Tutorials/Books Assume HTML
<script>
function myFunction() {
document.getElementById("demo").innerHTML = "Paragraph
changed.";
}
</script>
<h1>My Web Page</h1>
<p id="demo">A Paragraph</p>
<button type="button" onclick="myFunction()">Try it</button>
Copyright © 1999-2016
Profound UI Equivalents of Tags Are Widgets
There are equivalent properties in Profound UI (Rich Display or Genie)
A Label widget replaces the <p>
(paragraph) HTML tag.
A Button widget replaces the <button>
HTML tag.
<p id="demo">A Paragraph</p>
<button type="button"
onclick="myFunction()">
Try it
</button>
Copyright © 1999-2016
Events Are Properties Of The Widgets
Widgets have properties that correspond to all of the events. You can simply code your JavaScript
in the property field. If you click the button it will provide a code editor with syntax
highlighting, etc.
Copyright © 1999-2016
Event Properties Can Call JavaScript Kept in a Script File
When your code gets more sophisticated, or you want to reuse it, etc, it should
be placed in a file in the IFS. Once set up, you'll be able to call the function
from your JavaScript events
Copyright © 1999-2016
Where Do I Put My Script File?
Docs: http://www.profoundlogic.com/docs/display/PUI/Code+Organization
You can place it in a stream file (PC-style) in the IFS
• /www/YOUR-INSTANCE/htdocs/profoundui/userdata/custom
• It must end in .JS
• It can go in any subdirectory beneath custom
• For example, I might create a subdirectory named jsdemo for my scripts
• In Genie, you must add it to the start.html file
<script type="text/javascript"
src="/profoundui/userdata/custom/jsdemo/example.js"></script>
• The src= in <script> tags only includes directories beneath htdocs
• The Rich Display controller (/profoundui/start URL) and Visual Designer will automatically load
files in that directory when they are restarted or refreshed
• Mobile apps should use the "external javascript" property
• You can use any editor for JavaScript, but Notepad++ (free) and RDi are good ones.
Copyright © 1999-2016
Example Function in a Script File
This function is placed in /www/MY-INSTANCE/htdocs/profoundui/userdata/jsdemo/test.js
function myFunction() {
document.getElementById("demo").innerHTML = "Paragraph changed";
}
function myFunction(){
pui.set("demo", "Paragraph changed.");
}
Modifying an element's innerHTML works nicely for an output field, but for other field
types it can cause problems. This is because Profound UI widgets are built by putting
HTML tags in the page, and then adding their own functionality beyond that.
Profound provides APIs thare are better (and shorter/simpler) for setting/getting values.
Instead of innerHTML, use the pui.set() API.
docs: http://www.profoundlogic.com/docs/pages/viewpage.action?pageId=17137692
Copyright © 1999-2016
Tip: Common Profound UI APIs
• pui.get(id) (alias: get) = retrieve the value of a widget
• pui.set(id, "newValue") (alias: changeElementValue) = set the value of a widget
• getObj(id) (alias for document.getElementById) = get an underlying browser DOM
object for an id.
• applyProperty(id, propertyName, value) = change a widget's property
• pressKey(keyName) = press a function key or enter
• pui.click(id) = click a button on a Rich Display (with no id, just submits the screen)
All of the JavaScript APIs are found in our documentation under
• http://www.profoundlogic.com/docs
• JavaScript Coding
• API Reference
Since Profound UI widgets frequently do things above and beyond what the underlying
HTML tags can do, we recommend using our APIs instead of DOM properties like
innerHTML, value, etc.
Copyright © 1999-2016
Tip: Avoid Naming Conflicts With Objects
The JavaScript code that runs in a given page must co-exist.
• What if Profound UI (now or in the future) had a function named myFunction?
• What if you decided to use a 3rd party tool, and it happened to use myFunction?
• You can minimize this risk by making your own "namespace" using an object.
// Create an "acme" object if it does not already exist
if (typeof acme == "undefined") acme = {};
// Now you can define functions (or variables, etc) that start with "acme."
// which greatly reduces the chance of a conflict
acme.myFunction = function() {
pui.set("demo", "Paragraph changed.");
}
I recommend naming the namespace a short name, based on the company or software
you're writing. For example, if you work for Acme, Inc. you might do this:
Copyright © 1999-2016
Profound UI Has The Browser Events and More
An event runs (or "fires") when something happens. A lot of JavaScript code runs during
events. Thinking about code in terms of it running when an event occurs is important in
JavaScript.
In the preceding example, I used the onclick event of a button widget, so the code ran
when the button was clicked.
All of the events you'll find in HTML are in Profound UI as well. Plus there are many
additional events that are unique to Profound UI.
There isn't time to cover all events in this talk, but I've listed them for you to read on the
following slides.
docs: http://www.profoundlogic.com/docs/display/PUI/Code+Organization
Copyright © 1999-2016
Standard Widget-Level Events (Cursor Movement)
Standard Events on all Profound UI Widgets. These are run when…
• onfocus = the text cursor ("caret") moves to this widget. This can happen by
"tabbing" to the widget, or by clicking on it with the mouse. In either case, the caret
will move to the widget and keyboard input will go to this widget. This is referred to
as "having focus."
• onblur = focus leaves a field. This is called "blur" because it is the opposite of focus.
• onmouseover = the mouse cursor is moved over a widget. (Does not work on touch
screens.)
• onmouseout = the mouse cursor is moved away from a widget. It is the opposite of
onmouseover. (Does not work on touch screens.)
• onmousemove = run whenever the mouse is moved above a widget. This is run for
every movement, no matter how slight, so be careful what you code here, it will be
run many times!
Copyright © 1999-2016
Standard Widget-Level Events (keyboard/mouse buttons)
Standard Events on all Profound UI Widgets. These are run when…
• onchange = run after a user has changed a widget.
• onmousedown = run when the mouse button is pressed down
• onmouseup = run when the mouse button is released
• onclick = run when the left or right mouse button is clicked on a widget.
• ondblclick = run when the mouse button is double-clicked on a widget
• onkeydown = run when the widget has focus and the user pushes down a key on the
keyboard
• onkeypress = run when a user presses a character-generating key. (This event is
deprecated by the current browser standards, and is inconsistent across browsers. I
recommend onkeydown instead.)
• onkeyup = run when the widget has focus and the user releases a key on the
keyboard
Copyright © 1999-2016
Standard Record-Format Events
These events are configured at the record-format level
• onload = run when a record format has finished loading
• onsubmit = run when the display is submitted back to the server. This event should
return true normally, or false to stop the display from submitting to the server
Record Format Events Only Available in Genie
• onpageload = run when 5250 screen has loaded, but before customizations
• subfile row onclick = run when a row is clicked on a subfile that was created by
"detect subfile" without "detect subfile patterns"
• subfile row ondblclick = run when a row is double-clicked on a subfile that was
created by "detect subfile" without "detect subfile patterns"
Copyright © 1999-2016
Drag and Drop Events
In Output Field, HTML Container, Image and Grid widgets (Rich Display File Only)
• ondragstart = run when user begins drag/drop for this widget
• ondragenter = run when a widget is dragged over a drop target
• ondragleave = run when a widget is dragged out of (leaves) a drop target
• ondrop = run when the user drops (button is released) a widget
Copyright © 1999-2016
Widget-Specific Events
Menu Widget
• onoptionclick = run when user clicks a menu option
Fusion Chart Widget
• onchartclick = run when user clicks a chart section in a Fusion Chart widget
ComboBox or Textbox with Auto-complete
• onselect = run when a selection is made from the selection list
Spinner Widget
• onspin = run when the user clicks the up/down arrows on a spinner widget
File Upload or File Upload Drag/Drop Widget (Genie only)
• onupload = run when the user uploads a file to the IFS.
Copyright © 1999-2016
Grid (Subfile) Widget-Specific Events
These events only exist in the Grid Widget
• onrowclick = run when a row is clicked
• onrowdblclick = run when a row is double-clicked
• onrowmouseover = run when the mouse is moved over a row
• onrowmouseout = run when the mouse is moved out of a row
• onpagedown = run when the user pages down in the subfile. You should return true
to allow the page down, or false to stop the grid from paging
• onpageup = run when th user pages up in the subfile. You should return true to allow
the page up, or false to stop the grid from paging
• onscroll = run when the user scrolls the grid with the scrollbar
• onfilterchange = run when the user changes the grid's filter
Copyright © 1999-2016
Global Events
These events are not defined in properties. Instead, they are defined in your JavaScript
code. Once set, they persist for the entire session (or until you un-set them.)
• pui.inputfilter = run for each field submitted to the server, allows you to filter out
unwanted ("garbage") characters.
• pui.onbeforetimeout = run before a timeout occurs, this event can return false to
prevent Profound UI from doing timeout processing (requires client-side timeouts
enabled)
• pui.onload = runs each time any Rich Display record format has loaded, before
running the record-format's onload property event. (Rich Display only)
• pui.onoffline = run when a connection cannot be made to a server. Used by mobile
apps when they wish to do their own processing (such as save data locally, show
locally-stored display records, etc) when the server is not available.
• onsubmit = run before each display is submitted to the server
• ontimeout = runs after client-side timeout processing has ended the session on the
server. Allows you to control what happens (ex: print a custom message, start a new
session, etc.)
Copyright © 1999-2016
Global Events, continued…
These events are not defined in properties. Instead, they are defined in your JavaScript
code. Once set, they persist for the entire session (or until you un-set them.)
• pui.onuseractivity = run every time the user moves the mouse or presses a key.
Usually used for writing custom timeout handling routines.
• pui.overrideSubmitUrl = run when calculating the URL to submit responses to. Can be
used to modify the URL, for example so that additional data appears in Apache logs.
• pui.validate = runs for each modified field in a Rich Display record format that the
user has modified. Routine can prevent submission by returning an error message, or
can modify field values before they are sent to the server.
Copyright © 1999-2016
Global Events (Genie-Specific)
These events are defined in your Genie JavaScript code (such as custom.js) and usually
used to perform rule-based screen customizations.
• afterLoad (function) = run after every 5250 screen has been rendered and
customizations applied. The function must be named afterLoad()
• beforeLoad (function) = run before every 5250 screen has been rendered. The
function must be named beforeLoad().
• customize (function) = used to write code that customizes a screen in JavaScript (as
opposed to using the Genie Designer for customizations.) Run after the beforeLoad()
function, but before designer-based enhancements are rendered, for each 5250
screen. The function must be named customize()
• pui.genie.afterInit = run after automatic enhancements have been applied, but before
designer-based enhancements are applied.
• pui.onPCCommand = run when the STRPCCMD command sends a command, allows
you to write your own custom pc command tool.
• pui.onshutdown = run when a Genie session is being ended
Copyright © 1999-2016
Example: Totalling a Grid
Grid has id=PRODSFL
and we want to total the field
named PSTOCK
Copyright © 1999-2016
Tip: Manipulating Grid Data Values
When a grid in a Rich Display is loaded using the traditional method (such as the WRITE opcode from RPG) you can access the values of the fields on the display with the following grid methods:
• gridObject.grid.getDataValue(row, "fieldname");
• gridObject.grid.setDataValue(row, "fieldname", "newValue");
• gridObject.grid.getAllDataValues(use-filter);
• gridObject.grid.isRowFilteredOut(row);
docs: http://www.profoundlogic.com/docs/display/PUI/Grid+Methods
Notes:
• gridObject is an object that refers to the grid. Use getObj("id") API to retrieve it
• row is the row number (subfile RRN) to retrieve or set
• "fieldname" is the DDS field name to set
• "newValue" is the new value you'd like to set.
NOTE: the dataValueAPIs are unusual in that they refer to DDS field names. Almost everything else refers to the id property of the widget.
A common mistake is to confuse these.
Copyright © 1999-2016
Coding a Totalling Function
NOTES:
• to make it work on more than one grid, we take the id of the grid and the field name as parameters
• getObj() gives us the HTML DOM object of the grid
• getAllDataValues() returns the entire content of the grid the "true" parameter tells it to exclude rows that are filtered out (if filters are used)
• Number() forces the content of the field into a numeric data type
acme.total_grid_field = function( gridName, field ) {
var total = 0;
var data = getObj(gridName).grid.getAllDataValues(true);
for (var x=0; x<data.length; x++) {
total += Number(data[x][field]);
}
return total;
}
Add this below the "myFunction" example, using the "acme" object as before.
Copyright © 1999-2016
Adding the Totals to the Display File
NOTES:
• Drag an output field below the subfile
• Set the id = total
• Right-click and unbind FIELD0001 from the value
• Set the value to something like "total will go here". (This will be replaced.)
Copyright © 1999-2016
Run the total routine from the onload event
Set up the JavaScript to be run
• click an empty space on the screen so the properties box shows "Screen properties"
• Find the "onload" property
• Set it to JavaScript that calls our total function
pui.set("total", acme.total_grid_field("PRODSFL", "PSTOCK"));
NOTES:
• This calls our function, passing the id and field name when the display has loaded
• the output of our function is passed to pui.set() which sets the total field we added
• JavaScript and ids are case-sensitive, it's important to keep the upper/lower case the same
• Since we changed the display file, we need to compile and re-run the program
• If we had only changed the script, we could use pui.refresh() to re-load it without compiling
Copyright © 1999-2016
Now the total is there – but so what?
Copyright © 1999-2016
So what? I could've done that from RPG!
Yes! But…
• RPG (or Cobol, PHP, Node.js – any server-side code) runs before the display is loaded
• Since ours ran in the "onload" event, so it looked about the same.
• What if you wanted to change it without going back to the server and re-loading the
display? With JavaScript you can change it on any event!
Try this:
• Select the grid
• Find the "onfilterchange" event
• Put the same code that we ran in "onload" in that event – it now runs anytime the
user changes the filter!
Copyright © 1999-2016
Tip: How Do I Format Numbers?
When a Field Value is Set With JavaScript
• If it is a textbox (or other input-capable field) and bound to a DDS variable, the value
can be sent back to the server
• The binding dialog does NOT affect the format of the field you set with JavaScript.
You must do the formatting in your JavaScript code
var newVal = 10.50;
pui.set("total", newVal );
// the above will display as 10.5 not 10.50!
// it does not matter if you specified 2 decimals in your binding dialog
// since this is not coming from the server program.
Solutions…
• Most newer browsers (Chrome, Firefox, IE11, etc) support toLocaleFormat() and
Intl.NumberFormat() which have some good number formatting tools
• You can always download a 3rd party tool, or write your own…
Copyright © 1999-2016
The Acme Number Formatter
acme.numberFormatter = new Intl.NumberFormat("en-US", {
useGrouping: false,
minimumIntegerDigits: 1,
minimumFractionDigits: 2
});
acme.format = function(num) {
num = Number(num);
if ( num === 0 || isNaN(num) ) {
return "";
}
else {
return acme.numberFormatter.format(num);
}
}
Intl.NumberFormat
• Second parameter is a JSON object specifying the formatting options
• Since I'm running this outside of a function, it is run when my script is loaded and will
be available when acme.format() is called later.
Copyright © 1999-2016
Formatting Numbers
Options Used
• en-US = use the convention used in the USA. Period for decimals, comma as a thousands
separator
• minimumIntegerDigits = show at least X digit(s) to the left of the decimal place
• minimumFractionDigits = show at least X digit(s) to the right of the decimal place
• useGrouping = whether to show thousands separators (true=show, false=don't)
Note: Intl.NumberFormat (and toLocaleFormat() which is similar) is not a feature of Profound UI, it
is part of the browser. Read more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
var newVal = 10.5;
pui.set("total", acme.format(newVal));
// the above will display as 10.50
Copyright © 1999-2016
Example: Update Totals as they Change
This display is for entering new invoices
It uses the new RPG ALIAS feature to allow long names
The Item Description, Quantity and Price fields are textboxes
(input-capable.)
We want the [line_total] and [total] fields to update as they change
the prices or quantities!
Copyright © 1999-2016
JavaScript to Re-Calculate the Totals
acme.recalculate_invoice = function() {
var itemsGrid = getObj("itemsGrid").grid;
var total = 0;
for (var rrn=1; rrn<=itemsGrid.getRecordCount(); rrn++) {
var quantity = itemsGrid.getDataValue(rrn, "quantity");
var price = itemsGrid.getDataValue(rrn, "price");
var line_total = quantity * price;
total += line_total;
itemsGrid.setDataValue(rrn, "line_total", acme.format(line_total));
}
pui.set("total", acme.format(total));
}
Notes
• getObj(id).grid gets the grid field of the object, saving us some typing
• getRecordCount() tells how many rows are in the grid.
• getDataValue() and setDataValue() are used to get/set the grid values
Copyright © 1999-2016
Run the JavaScript in the onchange event
Change the Display File
• To run this, select the [quantity] field, then ctrl-click the [price] field. Now both are
selected.
• Find the onchange property, and set it to: acme.recalculate_invoice()
• Compile and run the display file. When values are changed, the total updates!
• Notice the way the numbers are formatted
Copyright © 1999-2016
Using the Browser's Developer Tools
Internet Explorer
• Click the "gear" (menu) and select F12 Developer Tools
• or, click outside the Profound UI display (such as in the URL bar) and press F12
Chrome
• Click the menu (…) and select more tools / developer tools
• or, press ctrl-shift-I
Firefox (built-in tools)
• Click the "Firefox" menu, then Web Developer
• or, press
Firefox (Firebug add-on)
• Use the Firebug icon near the URL bar
Copyright © 1999-2016
Some Developing/Debugging Tricks
To Reload Scripts from the Server Without Restarting Profound UI
• Use developer tools
• Select the console tab
• Type pui.refresh() at the prompt
• In fact, you can run any JavaScript at the console prompt, an easy way to test stuff out
• Likewise, pui.refresh() could be called from your display file's events
To Debug Scripts
• The exact mechanism varies from browser to browser, but…
• Each has a debugger in the developer tools
• All allow you to set breakpoints, view variable values as it runs, etc.
• You can select from the JavaScript files in memory to find yours
• Very powerful! (more-so than the IBM STRDBG or even RDi debugger!)
Copyright © 1999-2016
Try the Developer Tools!
Try Refreshing
• Change useGrouping to true, save your changes
• Go to the developer tools, select console, type pui.refresh()
• Watch the formatting change on the display!
Try Debuggging
• Go into the developer tools
• In the debugger, find your script file (acme.js or whatever you named it)
• Set a breakpoint in the acme.recalculate_invoice function
• Change a value (or use pui.refresh() to reload the display) and see it work
• Try viewing values, stepping through code, etc.
Copyright © 1999-2016
Trick: Debugging Inline Code
To Debug Code NOT In a Separate File (coded directly in a Profound UI property)
• Add a line that contains this statement: debugger;
• Open the developer tools
• Run the script – notice it stops on "debugger", like a breakpoint.
• Don't forget to remove the debugger line once you're finished debugging.
Copyright © 1999-2016
Tip: Use the Console To Find Errors
Finding Errors in Code
• The developer tool console will show any errors in JavaScript (unless the code used "catch" to catch them.)
• Some Profound UI specific events will catch errors and display them in a popup
• For example, imagine your script file started like this:
if (typeof acme == "undefined") acme = {};
something.invalid.is=0;
Copyright © 1999-2016
Trick: Log Your Own Messages To the Console
When Breakpoints Are Clumsy
• Sometimes setting a breakpoint is impractical, for example, for an event that runs many times, clicking "continue" in the debugger until you get to the right instance can be frustrating
• Try adding code that uses console.log() to print debug info to the developer's console, instead!
for (var rrn=1; rrn<=itemsGrid.getRecordCount(); rrn++) {
var quantity = itemsGrid.getDataValue(rrn, "quantity");
var price = itemsGrid.getDataValue(rrn, "price");
console.log("row:" + rrn + " price:" + price + " qty:" + quantity);
.
.
Copyright © 1999-2016
Tip: You Can Use Other JavaScript Libraries/Frameworks
Since Profound UI uses standard web technologies (HTML5, CSS, JavaScript) you can use it together with almost any JavaScript library.
Like the JavaScript tutorials, the library examples will show HTML tags, but you can adapt them. For example, here's a free library (Walter Zorn's Tooltips) that creates tooltips with HTML capabilities:
http://www.walterzorn.de/en/tooltip/tooltip_e.htm
You can incorporate it into Profound UI by:
• Download the zip file from the above link
• Unzip it into the /www/YOUR-INSTANCE/htdocs/wz_tooltip directory
• Add a <script> tag into your start.html file, just inside the <body> element
• For Genie, start.html is in your Genie skin, and can be edited in the Genie Admin
• For a Rich Display, it is found in the following IFS file:
/www/YOUR-INSTANCE/htdocs/profoundui/userdata/html/start.html
Copyright © 1999-2016
Example Start.html (Genie shown)
For example, in Genie I would add the <script> tag as follows:
Copyright © 1999-2016
Trying Out Zorn's Tooltips
Next time you re-load (or use pui.refresh()) it will load Zorn's tooltip library into memory.
You can now call it's routines. The docs tell you to use the onmouseover and onmouseoutproperties of an HTML tag, but in Profound UI, use the widget properties instead.
Copyright © 1999-2016
Another 3rd-party Example From Our Docs
There are many thousands of JavaScript tools on the Internet that you can use!
For another example, if you want more editing capabilities in your application, check out TinyMCE, from the Profound UI documentation.
http://www.profoundlogic.com/docs/display/PUI/Integrating+TinyMCE+Editor
Copyright © 1999-2016
Tip: Use JSON to simplify
JSON is JavaScript Object Notation – a "shorthand" for populating objects. I've already shown one
example when doing number formatting. Compare these definitions:
var options = new Object();
options.minimumIntegerDigits = 1;
options.minimumFractionDigits = 2;
options.useGrouping = false;
The regular ("longhand") way
var options = {
minimumIntegerDigits: 1,
minimumFractionDigits: 2,
useGrouping: false
}
The JSON ("shorthand") way
Using JSON format makes things simpler by eliminating the need to type the object name, or to split
the code into multiple lines. For parameters you can define and pass them in one line.
var options = new Object();
options.useGrouping = false;
var fmt = new Intl.NumberFormat("en-US", options);
-vs-
var fmt = new Intl.NumberFormat("en-US", { useGrouping: false });
Copyright © 1999-2016
Tip: Use JSON For Your ACME Code
acme = {
total_grid_field: function( gridName, field) {
. . . code here . . .
},
numberFormatter: new Intl.NumberFormat("en-US", {
. . . code here . . .
}),
format: function(num) {
. . . code here . . .
},
recalculate_invoice: function() {
. . . code here . . .
}
}
Using JSON can make your code simpler, even when defining a file full of routines, like the acme.js
file we built earlier.
The bodies of the functions are omitted for brevity, but they are the same as they were before, only
the acme.xxx = function() part is replaced.
Copyright © 1999-2016
Questions?
For more goodness:
Read about what's happening at Profound Logic in our blog:
http://www.profoundlogic.com/blog/
Share the cool stuff you can do with Profound UI, and discuss JavaScript programming with other customers in the Profound Logic forum:
http://www.profoundlogic.com/forum/
If there's time left, I'm
happy to answer your
questions.
Top Related