JET v3.0.0 Release Notes

v3.0.0 revision #32945 (17 March 2017)


These release notes cover the following topics:

View the Release Notes for the prior release (v2.3.0)

Things you need to know first

  • JET now ships with the CustomElements polyfill from Webcomponents 0.7.23. This library is required by the ojcomponentcore and ojcomposite modules. Applications should update their Require configurations to include a mapping for customElements (typically either to libs/webcomponents/CustomElements or libs/webcomponents/CustomElements.min).

  • If you are using JET Command Line (CLI) tooling, we now require that Node.js v4.0.0+ and npm v3.0.0+ are installed.

  • Library version numbers have changed for some libraries. You will need to update the version numbers in your requireJS config. See the Migration chapter of the JET Developers Guide for details on migration steps

  • If you are using theming you must regenerate your css file when you migrate. In major releases scss variables may be renamed, make sure to read the theming section below and follow any renaming instructions.

New Features included in v3.0.0

Data Visualizations

Data Visualization Gallery

A data visualization gallery with components, use cases, and featured demos has been added to the JET Cookbook.

Sunburst Root Node Content and Treemap Node Content

Custom HTML content for the sunburst root node and for treemap nodes can now be provided through a knockout template or JavaScript renderer. This is similar to the custom content support for status meter gauge and donut chart, as well as the custom tooltip support for the visualizations.

Sunburst and Treemap Drilling

Drill is now supported on sunburst and treemap, allowing for easy exploration through deep hierarchical data sets. Data can be populated up front or fetched on demand when the drill occurs.

Sunburst Expand/Collapse

Sunburst now supports the ability to expand or collapse nodes. This is particularly effective when used in conjunction with drilling, and data can also be populated up front or fetched on demand.

Treemap Label Wrapping

Treemap labels will now be wrapped by default for leaf nodes. This significantly improves the readability of treemaps in JET.

Performance

  • Performance of large data bar charts has been improved.
  • Performance of charts with large numbers of groups on a categorical axis has been improved, especially for Android devices.
  • Performance has been improved for charts with a large number of selected objects.
  • Performance has been improved for small multiples uses cases where many instances of simple visualizations (like spark charts or gauges) are used.
  • Zoom and scroll and data change animation performance has been improved, especially for bar charts.
  • A small memory leak was fixed for scrolling legends.

Other Enhancements

  • A labelMinLength property has been introduced on sunburst and treemap, providing control over the minimum number of visible characters needed in order to render a truncated label.

More information and best practices for using data visualization components can be found in this article: JET Data Visualizations: FAQ.


Native Theming

No new changes

Application Patterns

Web Application Patterns

No new changes

Hybrid Mobile Application Patterns

No new changes

Significant JET changes since 2.3.0

This section lists significant consumer-facing changes that have been made to JET since v2.3.0. Where bugs or ERs were used to track the change, they are included below. The following list does not include changes that are internal implementations, or changes made to samples, demos, or test collateral. It is expected that application code will not need to be modified to uptake v3.0.0.


Component Changes

ojPopup & ojDialog

The popup and dialog components now have default open and close animation effects. The animation effects are controlled via SCSS theme properties. See the popup or dialog animateStart event option for more details on the default animation and how to override.

The introduction of animation in the open and close events changes the behavior of these events from immediate to asynchronous. In some coding situations, you will want to wait until the animation has completed during the open or close of a popup or dialog. Automated QUnit testing is one example where your code will need to wait for animation to complete before interacting with the popup or dialog.

New APIs should be used for programmatic control of animations:
  1. oj.Context.getContext(popupDom).getBusyContext().whenReady method - Returns a promise that will resolve when the specific popup as completed open or close animation.
  2. oj.Context.getPageContext().getBusyContext().whenReady method - Returns a promise that will resolve when the page as a whole has completed all busy states on the page. Busy states include but not restricted to component animation effects.

ojPopup

The DOM structure of the ojPopup component has changed. In prior releases, the element bound to the popup component was the immediate parent of the popup's content. The element the popup component is bound to, will now be the root element. Static content defined before component binding will be relocated under an element marked with the ".oj-popup-content" selector. Popup content dynamically created after component creation, must be a child of the node identified by the ".oj-popup-content" selector. Page developers assigning dynamic content are encouraged to create their own marker element as the anchor for dynamic content versus using ".oj-popup-content" as the marker selector. See the ojPopup JSDoc for more on updating dynamic content.

The structure of the popups position option has changed. The jquery ui position utility structure has been deprecated over a new structure. The new structure will help prevent memory leaks by not holding on to references of dom elements and events. The deprecated jquery ui position object structure will continue to be supported. See the ojPopup JSDoc for more details.

ojSelect, ojCombobox, & ojInputSearch

The hidden select/input element is now moved inside the component container. In prior releases, the element bound to the select/combobox/inputSearch component was made hidden and left outside the component container. Now it is moved inside to make the components single rooted.

ojCollapsible

  1. The expandOn option is deprecated.
  2. The collapse and expand methods are deprecated, please use the expanded option to collapse and expand.

ojInputDateTime and ojInputTime

The timepicker on ojInputDateTime and ojInputTime has been changed from a dropdown list to a wheel-style picker popup. There are corresponding API changes for ojInputDateTime and ojInputTime. Automated tests may need to be updated to work with the new timepicker user interface.

The time part of the ojInputDateTime and ojInputTime will now be localized according to the current locale. In the previous version, by default, time always used 'hh:mm a' format independant of the locale. So based on the locale, you might see a change in the default time format in this version. For example, for the locale "en" the default time format will now be 'hh:mm' instead of "hh:mm a". This might impact the user experience. A value input of "1:00 PM" would now be interpreted as 1:00 am in 24 hour format.

Data Visualizations

The deprecated categoryFilter and categoryHighlight events have been removed. Use the optionChange listener to detect changes to the hiddenCategories and highlightedCategories properties respectively instead.

ojChart

The following deprecated attributes have been removed:

  • xAxis.referenceObjects[].min: Use xAxis.referenceObjects[].low instead.
  • xAxis.referenceObjects[].max: Use xAxis.referenceObjects[].high instead.
  • yAxis.referenceObjects[].min: Use yAxis.referenceObjects[].low instead.
  • yAxis.referenceObjects[].max: Use yAxis.referenceObjects[].high instead.
  • yAxis.referenceObjects[].items[].min: Use yAxis.referenceObjects[].items[].low instead.
  • yAxis.referenceObjects[].items[].max: Use yAxis.referenceObjects[].items[].high instead.
  • y2Axis.referenceObjects[].min: Use y2Axis.referenceObjects[].low instead.
  • y2Axis.referenceObjects[].max: Use y2Axis.referenceObjects[].high instead.
  • y2Axis.referenceObjects[].items[].min: Use y2Axis.referenceObjects[].items[].low instead.
  • y2Axis.referenceObjects[].items[].max: Use y2Axis.referenceObjects[].items[].high instead.
  • legend.referenceObjectTitle: Use legend.referenceObjectSection.title instead.
  • styleDefaults.groupTooltipType: Use valueFormats.group.tooltipDisplay instead.
  • styleDefaults.seriesTooltipType: Use valueFormats.series.tooltipDisplay instead.
  • styleDefaults.valueTooltipType: Use valueFormats.value.tooltipDisplay instead.
  • styleDefaults.sliceLabelPosition: Use styleDefaults.dataLabelPosition instead.
  • styleDefaults.sliceLabelStyle: Use styleDefaults.dataLabelStyle instead.

The following deprecated functions on the object returned by getDataItem() have been removed:

  • getBorderColor: Use borderColor instead.
  • getColor: Use color instead.
  • getGroup: Use group instead.
  • getLabel: Use label instead.
  • getSeries: Use series instead.
  • getTargetValue: Use targetValue instead.
  • getTooltip: Use tooltip instead.
  • getValue: Use value instead.
  • getX: Use x instead.
  • getY: Use y instead.
  • getZ: Use z instead.
  • isSelected: Use selected instead.

The following deprecated functions on the object returned by getLegend(), getXAxis(), getYAxis(), and getY2Axis() have been removed:

  • getBounds: Use bounds instead.
  • getTitle: Use title instead.

The following deprecated functions on the object returned by getPlotArea() have been removed:

  • getBounds: Use bounds instead.

ojLegend

The following deprecated functions on the object returned by getSection() have been removed:

  • getSection.getTitle: Use title instead.
  • getTitle: Use title instead.

The following deprecated functions on the object returned by getItem() have been removed:

  • getText: Use text instead.

ojSunburst

The following deprecated functions on the object returned by getNode() have been removed:

  • getColor: Use color instead.
  • getLabel: Use label instead.
  • getSize: Use size instead.
  • getTooltip: Use tooltip instead.
  • isSelected: Use selected instead.

ojTreemap

The following deprecated functions on the object returned by getNode() have been removed:

  • getColor: Use color instead.
  • getLabel: Use label instead.
  • getSize: Use size instead.
  • getTooltip: Use tooltip instead.
  • isSelected: Use selected instead.

ojThematicMap

The following deprecated functions on the object returned by getArea() and getMarker() have been removed:

  • getColor: Use color instead.
  • getLabel: Use label instead.
  • getTooltip: Use tooltip instead.
  • isSelected: Use selected instead.

Button

Given the decreasing importance of forms on the modern web, Toggle Buttons no longer register a "form reset" handler that updates the Button in the event of a form reset.

Navigation List

Added overflow option to show overflowed items in popup. This is applicable for horizontal navigation list only. Please refer JS documentation for more details.

ojDataGrid

The following changes were made to the ojDataGrid:

  • ojDataGrid headers, cells, and sort icon containers are now treated as flex boxes to allow for easier content alignment. See the the flex layout demos for more information about flex.
  • To assist in aligning content new class names can be used on cells to change the flex justify-content and align-items properties. See the ojDataGrid demos or styling documentation for examples.
  • New theming variables were also introduced to make changing the default alignment easier through SASS.
  • ojDataGrid now supports native iOS, Android, and Windows themes, see the ojDataGrid demos for examples by toggling different platforms.
  • ojDataGrid cells and headers have modified the DOM structure to remove the content divs. Also by default text is now placed directly in the cell not a child span.
  • When using nested headers and providing custom dimensions through styles or CSS the datagrid will no longer multiply the requested header dimension by its depth. If a value is specified datagrid will utilize that value.
  • $dataGridSelectionAffordanceBorder variable has been renamed to $dataGridSelectionAffordanceBorderColor.

API Changes

The responsive grid classes oj-row and oj-col have been removed (they were opt in in 2.1), use the flex layout classes instead.

ojChart

The following attributes have been deprecated:

  • title: Titles should be rendered outside the component for consistency with other text on the page.
  • subtitle: Subtitles should be rendered outside the component for consistency with other text on the page.
  • footnote: Footnotes should be rendered outside the component for consistency with other text on the page.
  • series[].areaClassName: Use series[].areaSvgClassName instead.
  • series[].areaStyle: Use series[].areaSvgStyle instead.
  • series[].boxplot.medianClassName: Use series[].boxplot.medianSvgClassName instead.
  • series[].boxplot.medianStyle: Use series[].boxplot.medianSvgStyle instead.
  • series[].boxplot.q2ClassName: Use series[].boxplot.q2SvgClassName instead.
  • series[].boxplot.q2Style: Use series[].boxplot.q2SvgStyle instead.
  • series[].boxplot.q3ClassName: Use series[].boxplot.q3SvgClassName instead.
  • series[].boxplot.q3Style: Use series[].boxplot.q3SvgStyle instead.
  • series[].boxplot.whiskerClassName: Use series[].boxplot.whiskerSvgClassName instead.
  • series[].boxplot.whiskerStyle: Use series[].boxplot.whiskerSvgStyle instead.
  • series[].boxplot.whiskerEndClassName: Use series[].boxplot.whiskerEndSvgClassName instead.
  • series[].boxplot.whiskerEndStyle: Use series[].boxplot.whiskerEndSvgStyle instead.
  • series[].className: Use series[].svgClassName instead.
  • series[].style: Use series[].svgStyle instead.
  • styleDefaults.boxPlot.medianClassName: Use styleDefaults.boxPlot.medianSvgClassName instead.
  • styleDefaults.boxPlot.medianStyle: Use styleDefaults.boxPlot.medianSvgStyle instead.
  • styleDefaults.boxPlot.whiskerClassName: Use styleDefaults.boxPlot.whiskerSvgClassName instead.
  • styleDefaults.boxPlot.whiskerStyle: Use styleDefaults.boxPlot.whiskerSvgStyle instead.
  • styleDefaults.boxPlot.whiskerEndClassName: Use styleDefaults.boxPlot.whiskerEndSvgClassName instead.
  • styleDefaults.boxPlot.whiskerEndStyle: Use styleDefaults.boxPlot.whiskerEndSvgStyle instead.
  • xAxis.referenceObjects[].className: Use xAxis.referenceObjects[].svgClassName instead.
  • xAxis.referenceObjects[].style: Use xAxis.referenceObjects[].svgStyle instead.
  • yAxis.referenceObjects[].className: Use yAxis.referenceObjects[].svgClassName instead.
  • yAxis.referenceObjects[].style: Use yAxis.referenceObjects[].svgStyle instead.
  • y2Axis.referenceObjects[].className: Use y2Axis.referenceObjects[].svgClassName instead.
  • y2Axis.referenceObjects[].style: Use y2Axis.referenceObjects[].svgStyle instead.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • groups[].labelStyle
  • legend[].referenceObjectSection.titleStyle
  • legend[].sections[].items[].lineStyle
  • legend[].sections[].titleStyle
  • legend[].seriesSection.titleStyle
  • legend[].textStyle
  • legend[].titleStyle
  • pieCenter.labelStyle
  • styleDefaults.dataLabelStyle
  • styleDefaults.sliceLabelStyle
  • styleDefaults.stackLabelStyle
  • styleDefaults.tooltipLabelStyle
  • styleDefaults.tooltipValueStyle
  • xAxis.tickLabel.style
  • xAxis.titleStyle
  • yAxis.tickLabel.style
  • yAxis.titleStyle
  • y2Axis.tickLabel.style
  • y2Axis.titleStyle

The styleDefaults.animationDuration string type has been deprecated

The getTitle() method has been deprecated because the title attribute has been deprecated.

The array format of the valueFormats attribute has been deprecated in favor of the object type. The new format uses the old valueFormats[].type attribute as a key and the value is an object with the same keys as before except for 'type'.

ojGantt

The following attributes have been deprecated:

  • rows[].tasks[].className: Use rows[].tasks[].svgClassName instead.
  • rows[].tasks[].style: Use rows[].tasks[].svgStyle instead.

The following attributes now accept values in ISO String format instead of number type(deprecated). Note that these attributes do not support Date type and non-ISO format string type:

  • end
  • referenceObjects[].value
  • rows[].tasks[].end
  • rows[].tasks[].start
  • start
  • viewportEnd
  • viewportStart

The rows function type has been deprecated.

The array format of the valueFormats attribute has been deprecated in favor of the object type. The new format uses the old valueFormats[].type attribute as a key and the value is an object with the same keys as before except for 'type'.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • dependencies[].svgStyle
  • referenceObjects[].svgStyle
  • rows[].labelStyle
  • rows[].tasks[].labelStyle

The following translations have been deprecated:

  • translations.accessibleDurationDays
  • translations.accessibleDurationHours
  • translations.accessibleMilestoneInfo
  • translations.accessibleRowInfo
  • translations.accessibleTaskInfo

ojIndexer

The following changes were made to the ojIndexer:

  • The IndexerModel interface has been overhauled. See the jsdoc for the updated interface.
  • The indexerCharacters translation property has been moved from ojListView to ojIndexer.
  • The oj.IndexerModelTreeDataSource is now the default IndexerModel implementation instead of the one retrieved from ListView with the getIndexerModel() method, which is now deprecated.

ojInputDateTime

The following sub-IDs (used by getNodeBySubId and getSubIdByNode methods) have been added:

  • oj-inputdatetime-calendar-clock-icon
  • oj-inputdatetime-time-input
  • oj-timepicker-cancel-button
  • oj-timepicker-content
  • oj-timepicker-hour
  • oj-timepicker-meridian
  • oj-timepicker-minute
  • oj-timepicker-now
  • oj-timepicker-ok-button

ojInputTime

The following sub-ID (used by getNodeBySubId and getSubIdByNode methods) has been removed:

  • oj-listbox-drop

The following sub-IDs (used by getNodeBySubId and getSubIdByNode methods) have been added:

  • oj-timepicker-cancel-button
  • oj-timepicker-content
  • oj-timepicker-hour
  • oj-timepicker-meridian
  • oj-timepicker-minute
  • oj-timepicker-now
  • oj-timepicker-ok-button

ojLegend

The following attributes have been deprecated:

  • title: Titles should be rendered outside the component for consistency with other text on the page.
  • sections[].items[].className: Use sections[].items[].svgClassName instead.
  • sections[].items[].markerClassName: Use sections[].items[].markerSvgClassName instead.
  • sections[].items[].markerStyle: Use sections[].items[].markerSvgStyle instead.
  • sections[].items[].style: Use sections[].items[].svgStyle instead.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • sections[].titleStyle
  • textStyle

The getTitle() method has been deprecated because the title attribute has been deprecated.

ojListView

The following changes were made to the ojListView:

  • Clicking any JET component inside an item will now update the currentItem option (if the item is focusable) and the selection option (if the item is selectable and selectionMode is not none). If you want to disable the behavior, specify 'oj-clickthrough-disabled' class on the ojComponent.
  • ListView now uses wai-aria grid/row/gridcell roles for both flat and hierarchical list.
  • As a result of using grid role, content inside item are now wrapped with an additional div element with a gridcell role (not in card layout mode).
  • When changing ListView to card layout mode, application should refresh the ListView so that the wai-aria properties are updated correctly (and vice versa).
  • When in card layout mode, left and right arrow keys are now used to navigate between items.
  • If an item is not focusable, then it is not selectable as well, including when the item is within a selection range (created using shift+click).
  • ListView now supports busy state in page level BusyContext.
  • The getIndexerModel() method has been deprecated. Use the oj.IndexerModelTreeDataSource instead to as a data for both the Indexer and the associated ListView.

ojPictoChart

The following attributes have been deprecated:

  • items[].className: Use items[].svgClassName instead.
  • items[].style: Use items[].svgStyle instead.

ojSparkChart

The following attributes have been deprecated:

  • areaClassName: Use areaSvgClassName instead.
  • areaStyle: Use areaSvgStyle instead.
  • className: Use svgClassName instead.
  • style: Use svgStyle instead.
  • items[].className: Use items[].svgClassName instead.
  • items[].style: Use items[].svgStyle instead.
  • referenceObjects[].className: Use referenceObjects[].svgClassName instead.
  • referenceObjects[].style: Use referenceObjects[].svgStyle instead.

ojSunburst

The following attributes have been deprecated:

  • nodes[].className: Use nodes[].svgClassName instead.
  • nodes[].style: Use nodes[].svgStyle instead.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • nodeDefaults.labelStyle
  • nodes[].labelStyle

ojTimeAxis

The following attributes now accept values in ISO String format instead of number type(deprecated). Note that these attributes do not support Date type and non-ISO format string type:

  • end
  • start

ojTimeline

The following attributes have been deprecated:

  • majorAxis.style: Use majorAxis.svgStyle instead.
  • minorAxis.style: Use minorAxis.svgStyle instead.
  • overview.style: Use overview.svgStyle instead.
  • series[].items[].style: Use series[].items[].svgStyle instead.
  • series[].style: Use series[].svgStyle instead.

The following attributes now accept values in ISO String format instead of number type(deprecated) and Date type(deprecated). Note that these attributes do not support non-ISO format string type:

  • end
  • referenceObjects[].value
  • series[].items[].end
  • series[].items[].start
  • start
  • viewportEnd
  • viewportStart

The series function type has been deprecated.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • majorAxis.svgStyle
  • minorAxis.svgStyle
  • overview.svgStyle
  • series[].items[].svgStyle
  • series[].svgStyle
  • styleDefaults.item.descriptionStyle
  • styleDefaults.item.titleStyle
  • styleDefaults.majorAxis.labelStyle
  • styleDefaults.minorAxis.labelStyle
  • styleDefaults.overview.labelStyle
  • styleDefaults.series.emptyTextStyle
  • styleDefaults.series.labelStyle

The following translations have been added:

  • translations.accessibleItemDesc
  • translations.accessibleItemEnd
  • translations.accessibleItemStart
  • translations.accessibleItemTitle

ojTrain

The following attributes and methods have been deprecated:

  • selected: Use selectedStep instead.
  • nextSelectableStep(): Use getNextSelectableStep() instead.
  • previousSelectableStep(): Use getPreviousSelectableStep() instead.
  • setStep(stepProperties): Use updateStep(id, stepProperties) instead.

ojTreemap

The following attributes have been deprecated:

  • nodes[].className: Use nodes[].svgClassName instead.
  • nodes[].style: Use nodes[].svgStyle instead.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • nodeDefaults.header.labelStyle
  • nodeDefaults.labelStyle
  • nodes[].labelStyle

ojLedGauge

The following attributes have been deprecated:

  • className: Use svgClassName instead.
  • style: Use svgStyle instead.
  • title: Use label instead.
  • title.text: Use label.text instead.
  • title.style: Use label.style instead.

ojRatingGauge

The following attributes have been deprecated:

  • changedState.className: Use changedState.svgClassName instead.
  • changedState.style: Use changedState.svgStyle instead.
  • hoverState.className: Use hoverState.svgClassName instead.
  • hoverState.style: Use hoverState.svgStyle instead.
  • selectedState.className: Use selectedState.svgClassName instead.
  • selectedState.style: Use selectedState.svgStyle instead.
  • unselectedState.className: Use unselectedState.svgClassName instead.
  • unselectedState.style: Use unselectedState.svgStyle instead.

ojStatusMeterGauge

The following attributes have been deprecated:

  • plotArea.className: Use plotArea.svgClassName instead.
  • plotArea.style: Use plotArea.svgStyle instead.
  • className: Use svgClassName instead.
  • style: Use svgStyle instead.

The following attributes now accept a CSS style object instead of a string type(deprecated):

  • metricLabel.style
  • title.style

ojInputNumber's translations.numberRange and NumberRangeValidator changes

When the min and max options are non-null and equal to each other (e.g., min=1 and max=1) these new keys are used for the hint and the messageDetail:

  • hint.exact
  • messageDetail.exact

ojTree: return value from GetSubIdByNode() has been corrected (bug 24839280)

Any use of the return value from this API should be reviewed.

editableValue no longer has the validate method, the validators option, the required option, or the translation required option

Since these options are not used by all its sub-classes, we moved these options out of EditableValue and into the sub-classes that use them.

ojSlider and ojSwitch no longer have the validate method

The validate method has been removed from ojSlider and ojSwitch. The validate method is used to validate the component using the validators and converters on the component, and one of the first things validate does is clear the messagesCustom option. Since ojSlider and ojSwitch don't have the validate method anymore, you can clear the error messages shown to the user by setting the messagesCustom option to an empty array. The error messages on the UI will be cleared out.

ojCheckboxset, ojRadioset, ojSelect, ojSlider and ojSwitch no longer have the validators option

The validators option has been removed from ojCheckboxset, ojRadioset, ojSelect, ojSlider, and ojSwitch. Since the user does not enter values into these components, the validators option never made sense to be on these components. Use messagesCustom option to add custom validation.

ojSlider no longer has the required option or required translations

The required option has been removed from ojSlider. ojSlider has no user interface to show 'nothing is set', so required did not make sense on ojSlider.

ojCheckboxset: throws an Error if ojCheckboxset's value option is not an Array (Bug 24912817 - enforce ojcheckboxset's value to be an array)

The ojCheckboxset's value option takes an Array. In previous releases, even though it is a 'set' component, we allowed null and strings. This was inconsistent with the ojButtonset component, which is also a set, but doesn't allow null and strings.

In this release we tightened up on the API to make it consistent with ojButtonset and also to make it clearer and cleaner how it will be used. It's a set, so it needs to take an Array. If you want to unset all the options, then you need to set value to an empty Array.

We throw an error if it is used incorrectly so it can be fixed by the application developer. The error you will see something like this: "Invalid 'value' set on JET Checkboxset: red.It must be an Array.".

To fix your pages, search all instances of ojCheckboxset components in your application, and look at what the value option is bound to. If it is a string or null, then you will need to change it to an Array. For example, if you have ko.observable("red"), change it to ko.observable(["red"]) or ko.observableArray(["red"]). If you have ko.observable(null), change it to ko.observable([]) or ko.observableArray(). If you have ko.observable(), this is the same as value is undefined, and we automatically make an undefined value into an emtpy array. For clarity sake, it is recommended to use ko.observableArray(); or ko.observable([]);

ojCheckboxset and ojRadioset style class changes

The oj-choice-row and oj-choice-row-inline classes have been deprecated and replaced by oj-choice-item. Use oj-choice-direction-column or oj-choice-direction-row on the root dom element to make the label/input line up in a column or a row, respectively. It defaults to oj-choice-direction-column.

To make the changes:

  • change class="oj-choice-row-inline" to class="oj-choice-item"
  • On the root dom element, add "oj-choice-direction-row" to the style class list e.g., class="oj-choice-direction-row"
  • Change class="oj-choice-row" to class="oj-choice-item".
  • You do not have to add 'oj-choice-direction-column' on the root dom element since that is the default.

Performance Improvement: 'ojs/ojvalidation' module has been broken up into three modules

In previous releases, the 'ojs/ojvalidation' module contained all of JET validators and converters. In this release the 'ojs/ojvalidation' module has been broken up so you can be more specific what you need and make the download payload smaller.

The three new modules are: 'ojs/ojvalidaton-datetime', 'ojs/ojvalidation-number', and 'ojs/ojvalidation-base'.

  • 'ojs/ojvalidaton-datetime' contains all the validators and converters for datetime and depends on the 'ojs/ojvalidation-base' module.
  • 'ojs/ojvalidation-number' contains all the validators and converters for number and depends on the 'ojs/ojvalidation-base' module.
  • 'ojs/ojvalidation-base' module contains the other validators and converters (e.g., RequiredValidator, IntlConverterUtils).

Changes you should make:

  • If you only need the datetime validators/converters, then change 'ojs/ojvalidation' to 'ojs/ojvalidation-datetime'
  • If you only need the number validators/converters, then change 'ojs/ojvalidation' to 'ojs/ojvalidation-number'
  • If you do not need the datetime or number validators/converters, then change 'ojs/ojvalidation' to 'ojs/ojvalidation-base'
  • If you did not include 'ojs/ojvalidation' at all but relied on all the validators and converters being loaded when you loaded a form control module, and you now see an error like, "Cannot read property 'createConverter' of null", then you need to include the specific validation module you need, e.g., the 'ojs/ojvalidation-datetime' module if you are using a datetime validator/converter.
  • For now the ojvalidation module is deprecated and is backward compatible. It will still work if you use it, but it is recommended that you update all your 'ojs/ojvalidation' modules to one of the new ones: 'ojs/validation-base', 'ojs/ojvalidation-datetime', or 'ojs/ojvalidation-number'

ojFilmStrip

FilmStrip 'currentItem' option should be of type object. Directly setting a value of type string or number for this option has been deprecated. The value set must be an object containing the string id or numeric index or both.

Composite

Metadata
  • New oj.Composite.getMetadata(name) function for retrieving composite metdata.
  • Composites are now required to have a metadata file and the minimum set of required properties defined.
  • New required top level properties: name, version, jetVersion.
  • New optional top level properties: compositeDependencies, description, slots.
  • Properties can now have an optional enumValues field that lists out allowed values for string properties.

Please see the Metadata section of the jsDoc for more info.

Lifecycle Listeners
  • The dispose callback is deprecated in favor of the new detached lifecycle callback. Please see the Lifecycle section of the jsDoc for more info.
  • oj.Composite.defaults has been deprecated. Since composites are designed to be reusable/shareable components, we do not recommend overriding the default lifecycle listener names and potentially breaking consumed composites.
Events and Event Listeners
  • The [propertyName]-changed event fired by composite components has been deprecated. Applications should listen to the corresponding [propertyName]Changed event instead (e.g. valueChanged instead of value-changed).
  • In addition to the standard add/removeEventListener APIs, event listeners can be added declaratively via on-[event-name] attributes and on[EventName] element properties. Please see the Events section of the jsDoc and demo for more info.
Subproperties
  • Subproperties of complex properties can be exposed via nested properties objects in the Metadata.
  • Subproperties can be set via attributes using dot notation or on the element using the new setProperty API. See the Subproperties section of the jsDoc and demo for more info.
  • A new subproperty field has been added on property change events.
Automation

We have published a set of automation guidelines for composites to follow and exposed a set of automation APIs for composites to use and override. Please see the Automation section of the jsDoc, demo, and "Preparing Oracle JET Composite Components for Automation Testing" section of the Developer's Guide for more info.

Theme Changes

Variable Changes

  • radioset and checkboxset:
    • The following variables were introduced:
      1. $radioCheckboxImageHeightWidth: Used to specify the height and width of the image, if using backgroundImage instead of html inputs. For example, $radioCheckboxImageHeightWidth: 20px !default;
      2. $radioCheckboxInputToEdgePadding:: Used to set the spacing between edge and the input (html input or input image).
      3. $radioCheckboxInputToLabelPadding:: Used to set the spacing on the input (html input or input image) to give spacing between the input and the text.
    • Checkboxset and Radioset's touch targets are now larger and easier to tap in the Alta Web Theme.

      In previous releases, the Alta Web theme rendered the radioset and checkboxset components showing the native html's input elements which are fixed in size, whereas the other themes (iOS, Android, and Windows) showed images instead (e.g., a checkmark image) that are larger than the inputs and easier to tap. We found the larger touch targets are more usable even on a desktop, so in v3.0 we changed the Alta Web Theme to use images instead of the native input; $radioCheckboxImageDir: 'backgroundImage' !default;.

      Because all our themes render the radios and checkboxes as images now, we have changed the $radioCheckboxRenderInputAs variable's default value from html to backgroundImage. If you create your own theme, backgroundImage will be the default for this variable.

      If you need to customize the radio and checkbox image .svgs for your own theme, then use the $radioCheckboxImageDir variable (introduced in v2.1). Copy JET's radio and checkbox .svgs and put them in a directory of your choice, and set this theming variable to be that directory. Do not change the names of the .svg files, but you can change the content. e.g., change the color.

      Changes you should make:

      If you use the Alta Web theme exclusively, then you may have gotten away with using no label element for each input element of your ojCheckboxset or ojRadioset. The label element is required for each input when $radioCheckboxImageDir: 'backgroundImage' !default; because the label element is where we render the checkmark image. Now that the Alta Web theme renders the checkmark image, you must have a label element for each input element and use the 'for' attribute on label to point to the input.

  • Navigation List: The following variables were introduced:
    1. $navigationBarStackedItemPadding: Used to specify padding for horizontal navigation list (navigation bar) item when icon and text are stacked.

Component Focus Indicator Changes

The following Jet Components have moved from the oj-focus CSS class to a new oj-focus-highlight CSS class. This class is applied in accordance with the new $focusHighlightPolicy SASS variable.

  • Popup: JET Popup now shows a focus ring around the popup container in all themes by using the oj-focus-highlight CSS class.

Framework Changes

Router Changes

oj.Router.defaults.baseUrl:
There is a change in the value returned by the property baseUrl. In earlier versions, the file name was always stripped from the value returned by this property, now the value returned is the value previously set. The default value is '/'. Action: Review and modify places using the value returned by this property.

Child router state behavior:
The child router current state now always becomes undefined when the parent router transition to another state. In addition the canExit and exit callback are invoked on the child router current state. This fixes bug 21459990. The motivation for introducing this change is that it allows components depending on this state to do some clean up when the parent router changes. Also it allows a state change to occurs when transitioning back to the same child router state. The result is that some child router stateId observable will mutate to undefined when they did not in previous version. Action: Watch for places where your application does not properly handle the case where the stateId or currentState becomes undefined.

New API on the go method for special type of routing:
There are cases, by example for building a wizard like user interface, when it is desirable to not record navigation on the browser history, or to replace the current entry of the browser history. For this, a new argument has been added to the go method.
Here is an example of usage of the new API:
router.go('stepC', { historyUpdate: 'skip' } );    // Does not record the state change to the browser history
router.go('pageB', { historyUpdate: 'replace' } ); // Replace the current entry of the browser history

Busy Context

The purpose of the new API is to accommodate sequential dependencies of asynchronous operations. A common use cases defining the API is for automation testing (qunit and webdriver). Automation test developers can use this API to wait until components finish animation effects or data fetch before trying to interact with components.

The new oj.Context.getPageContext().getBusyContext() API will consider the activity on the page and block BusyContext.whenReady until all the components on the page are not busy or a timeout period has elapsed. There are four primary wait scenarios:

  1. Components that implement new animation effects.
  2. Components that must fetch data from a REST endpoint.
  3. General wait conditions that are not specific to the Jet framework. The customer might choose to register some blocking condition associated with application domain logic such as REST endpoints.
  4. Wait until the bootstrap of the page has completed - jet libraries loaded via requireJS.

The granularity of a busy context can be scoped for the entirety of the page or for a specific dom DOM element, oj.Context.getContext(element). Busy contexts have hierarchical dependencies mirroring the document's DOM structure with the root being the page context.

Library Changes

Custom Elements 0.7.23

JET now ships with the CustomElements polyfill from Webcomponents 0.7.23. This library is required by the ojcomponentcore and ojcomposite modules. Applications should update their Require configurations to include a mapping for customElements (typically either to libs/webcomponents/CustomElements or libs/webcomponents/CustomElements.min).

RequireJS 2.3.2

JET now ships with RequireJS 2.3.2. No application changes should be necessary.

jQuery 3.1.1

JET now ships with jQuery 3.1.1. Applications may need to update their Require files accordingly.

ES6-Promise 4.0.5

JET now ships with ES6-Promise 4.0.5. If the application loads ojs/ojcore before using Promise functionality, then no application changes should be necessary. Otherwise, the application loading this library will need to call polyfill() on the instance returned by the 'promise' module to polyfill the global environment, e.g.,
require(['promise'], function(promise)
{
    promise.polyfill(); // this line was not needed in previous versions
    ...
});

Tooling Changes

Refer to the Oracle JET Developer Guide for detailed information on the impact of the following changes to Oracle JET Tooling and how to migrate a JET application built using v2.3.0 Tooling and Oracle JET runtime libraries to use v3.0.0 Tooling and Oracle JET runtime libraries:

Node versions

JET tooling now requires that Node.js v4.0.0+ and npm v3.0.0+ are installed.

Bower replaced with npm

JET tooling no longer requires Bower, and uses npm instead for front-end package management. An oraclejet npm module is published that contains the Oracle JET runtime artifacts. When scaffolding a new application using the v3.0.0 Oracle JET yeoman generator (generator-oraclejet), the Oracle JET runtime and all of its dependencies (eg. jQuery, knockout, etc) will be pulled in via npm instead of Bower. The Bower distribution of Oracle JET will continue to be released in case any existing apps wish to keep using Bower.

CCA theming

JET tooling now runs SASS tasks in CCA sub-directories of a JET application.

Changes to the --destination option

There are two changes to the --destination option for grunt serve tasks:

  • The --destination=server-only option is now available for web apps
  • The --destination=deviceOrEmulatorName option is no longer available

Custom serve tasks

It is now possible to customize grunt serve tasks, allowing the user to configure the watch process and specify custom commands to run when certain files are edited.

iOS 10 compatibility

The CSP meta tag inserted into a JET hybrid app's index.html file during a grunt build now contains gap://ready to maintain compatibility with iOS 10. This is typically only required when the cordova-plugin-device Cordova plugin has been included in the app.

Known Issues

The following table calls out specific known issues, with workarounds where available.

Category Bug # Description Workaround (if available)
ojCheckboxset/ojRadioset 25751908 Your checkbox or radio is no longer visible or clicking on the row doesn't work. This is because you do not have a label element and/or you do not wrap your input/label in a span with class='oj-choice-item'. You must have this structure for the radioset/checkboxset to work:
                    
<span class='oj-choice-item'>
  <input id='foo' type='checkbox'>
  <label for='foo'>Foo</label>
</span>
                    
                  
or if you don't want a label, you can do it this way:
                    
<span class='oj-choice-item'>
  <input id='foo' type='checkbox' aria-label='foo'>
  <label for='foo'></label>
</span>
                    
                  
You need to have an input, and a label pointing to the input (this can be empty, and if so you need to set aria-label on the input), and you need to wrap these with an element with class='oj-choice-item'. When we rendered the native input in the Alta Web theme, you didn't need to do this, but now that we render an image instead (See Theme Changes), you do need to do this since we need this structure to style it.
ojRouter bookmarking additional data 25752718 The ability to bookmark additional data on the URL is not working when using the param URL adapter.

This issue is related to the methods store() and retrieve() on the oj.Router object. When using store() to add bookmarkable data, the URL correctly add a request parameter ojRouter=xxx but on a browser refresh or when using the bookmarked URL, the method retrieve() returns undefined instead of the previously stored data.
The only workaround, if it is possible in your environment, is to switch from using the param URL adapter to the path URL adapter. There is a section in the Cookbook Router Demo named "Working with the path URL adapter", that describes how to setup URL rewrite rules that work with the URL Path Adapter.
CSS n/a Oracle JET is using new versions of grunt-sass (2.0.0) and node-sass (4.2.0). This means a new libsass is being used. Unfortunately, this new libsass has an issue (https://github.com/sass/libsass/issues/2294) where computed color functions (such as lighten and darken) sometimes produce different values than before. Unless a new version gets released and up-taken by JET by the time JET 3.0.0 releases, you may encounter these color value changes if you are using Sass for your own styling or are using the JET-provided CSS files. The JET --oj-secondary-text-color variable or Sass $secondaryTextColor variable in Alta is an example of a computed color that uses lighten(#333333, 10%). Luckily the variation is extremely subtle so most people will not notice, e.g.:
  • lighten(
    #333333
    , 10%)
    used to produce #4d4d4d but now produces #4d4c4c
  • darken(
    #4d4d4d
    , 10%)
    used to produce #343434 but now produces #343333
n/a
Selenium with ojCheckboxset/ojRadioset n/a Selenium's ExpectedConditions.elementToBeClickable() thinks an element is not clickable if it has opacity: 0. In this release we hide the ojCheckboxset and ojRadioset's input element (in our themes that render an image instead of an input) using opacity: 0. In previous releases, we hid the input element using the oj-helper-hidden-accessible styleclass. We needed to make the change to fix a voiceover issue.

Therefore, if you use Selenium's ExpectedConditions.elementToBeClickable() to check if the ojRadioset or ojCheckboxset's input is enabled, then this will no longer work.

With opacity:0 the input element is actually clickable (you can click on it manually and selenium's click() method works), but the elementToBeClickable condition doesn't work.
You can look to see if the input is enabled (has oj-enabled style on it) instead of calling elementToBeClickable.
Webcomponents n/a ojcore now has a dependency on the webcomponents 3rdparty library, which has introduced a bug in IE11 iframes as described in the following webcomponents issue that occurs on refresh. We suggest using the workaround described in the webcomponents issue and add the following code before requirejs is loaded within your iframe.
                    
<head>
  ...
  <script>
  if (!document.createElement) {
    document.createElement = document.constructor.prototype.createElement;
    document.createElementNS = document.constructor.prototype.createElementNS;
    document.importNode = document.constructor.prototype.importNode;
  }
  </script>
  <script src="../js/libs/require/require.js"></script>
  ...
</head>
                    
                  
Tooling n/a Running grunt serve on a JET hybrid app using distribution credentials causes the app to be deployed to the device, but when it launches automatically, it displays the splashscreen for a few seconds and then crashes. This is due to an issue with ios-deploy. Launch the app on the device manually, or use developer credentials rather than distribution credentials.
BusyContext n/a Page-level busy state may not be released properly if the following types of component or object is destroyed while it is busy (such as fetching data or animating):
  • ojCollapsible
  • ojDataGrid
  • ojIndexer
  • Any visualization components
  • PullToRefreshUtils
If the above components/objects are destroyed while busy, the page-level whenReady promise will never resolve. Similarly, the page-level isReady method will always return false.
Where possible, do not rely on the page-level BusyContext. Instead, scope the BusyContext to the specific DOM element the application needs to wait on. This can be accomplished by including the "data-oj-context" attribute on the node that the component is bound to and using getContext to retrieve the BusyContext object.

<div id="datagrid" data-oj-context data-bind="ojComponent: {component: 'ojDataGrid'}"></div>
...
<script>
  var busyContext = oj.Context.getContext(document.getElementById("datagrid")).getBusyContext();
  busyContext.whenReady().then(function() {
    // Handler logic when the component is ready
  });
</script>
                  
If you need to rely on a page-level BusyContext (for example, when you are using BusyContext in Selenium or WebDriver tests), verify that your test waits for the .whenReady() promise before proceeding to the next UI action. This will ensure that any UI action that may destroy a component is executed after the operation contributing to the busy state is complete.