Working with Layout and Navigation

Use the Oracle JET ojAccordian, ojCollapsible, ojDialog, oj-flex*, ojMasonryLayout, ojNavigationList, offCanvasUtils, ojPanel, ojPopup, oj-size*, and ojTab components and patterns to control the initial data display and allow the user to access additional content by expanding sections, selecting tabs, or displaying dialogs and popups.

The Oracle JET Cookbook and JavaScript API Reference for Oracle® JavaScript Extension Toolkit (JET) include complete demos and examples for using the layout and navigation components, and you may also find the following tips and tricks helpful.

Topics:

For information about the flex layout (oj-flex*) and responsive grid (oj-size) classes, see Designing Responsive Applications

Working with Accordions

The Oracle JET ojAccordion component contains a list of ojCollapsible components. Each child element of the ojAccordion expands or collapses when the user selects its header to display the child element's content.

You can define the ojAccordion on the HTML div element. For each collapsible, add a div child element and add the collapsible's header and block of content as children of the div element. You can use any valid markup to define the header and block of content.

ojAccordion will add the ojCollapsible binding to each div child element by default. However, you can also specify the ojCollapsible binding explicitly to control the collapsible's behavior.

The following code shows a portion of the markup used to create the accordion shown in this section. In this example, the second collapsible (Header 3) is explicitly bound to an ojCollapsible component, and the first collapsible (Header 1) uses the default ojCollapsible binding added by the ojAccordion component.

<div id="accordionPage" data-bind="ojComponent: {component: 'ojAccordion'}">
  <div id="c1">
    <span><span class="demo-icon-font demo-education-icon-24"></span> Header 1</span>
    <p class="oj-p">Content 1.</p>
  </div>
  <div id="c3" data-bind="ojComponent: {component: 'ojCollapsible', expanded:true}">
    <span>Header 3</span>
    <div>
      <label id="mainlabelid">Colors</label>
      <div id="radiosetSetBasicDemoId" aria-labelledby="mainlabelid"
         data-bind="ojComponent: {component: 'ojRadioset', 
                   value: 'red'}" >
        <span class="oj-choice-item">
            <input id="blueopt" type="radio" name="rbb" value="blue">
            <label for="blueopt">Blue</label>
        </span>
        <span class="oj-choice-item">
            <input id="greenopt" type="radio" name="rbb" value="green">
            <label for="greenopt">Green</label>
        </span>
        <span class="oj-choice-item">
            <input id="redopt" type="radio" name="rbb" value="red">
            <label for="redopt">Red</label>
        </span>
      </div>
    </div>
  </div>
  ... content omitted
</div>

The Oracle JET Cookbook at Accordions contains the sample code to create the accordion pictured in this section. You can also find examples for expanding multiple child elements and responding to events.

For additional information about working with the ojCollapsible component, see Working with Collapsibles.

Working with Collapsibles

The Oracle JET ojCollapsible component contains a header and a block of content that expands or collapses when selected.

Define the ojCollapsible on the HTML div element. Add the header and content elements as children of the component. You can use any valid markup to represent the header and block of content. In this example, the collapsible is using the h3 element to contain the header and a p element to contain the content.

<div id="collapsiblePage" data-bind="ojComponent: {component: 'ojCollapsible'}">
  <h3>Header 3</h3>
  <p>I'm a  Collapsible.</p>
</div>

To apply the binding, you can use the Knockout applyBindings() method and reference the id of the div element that contains the ojCollapsible component.

require(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout', 'ojs/ojcollapsible'],
function(oj, ko, $)
{  
  $(document).ready(
    function()
    {
      ko.applyBindings(null, document.getElementById('collapsiblePage'))
    }
  );
});

The Oracle JET Cookbook Collapsibles demos contain the complete example for creating this collapsible as well as examples that show nested collapsibles, collapsibles with different header elements or borders, and event handling.

Working with Dialogs

You can use the Oracle JET ojDialog component to display dialogs that are themable and follow WAI-ARIA authoring practices for accessibility. By default, the ojDialog component renders modal dialogs which require user interaction before control returns to the calling window.

Typically, you create the ojDialog component on the HTML div element. Define the dialog title in the div element's title attribute and use the Knockout data-bind syntax to define the ojDialog. Add content to the dialog using the oj-dialog-body and oj-dialog-footer sections.

The ojDialog component includes support for the header close icon and close handler, but you must add your own markup for creating the OK button in the oj-dialog-footer section, as shown in the code sample below.

<div id="dialogWrapper">
  <div style="display:none" id="modalDialog1" title="Modal Dialog"
       data-bind="ojComponent:{component: 'ojDialog', initialVisibility: 'hide'}">
    <div class="oj-dialog-body">
       The dialog window can be moved, resized and closed with the 'x' icon.
       Arbitrary content can be added to the oj-dialog-body and oj-dialog-footer
       sections.
    </div>
    <div class="oj-dialog-footer">
      <button id="okButton" data-bind="ojComponent: {component: 'ojButton', label: 'OK'}">
      </button>
    </div>
  </div>
  <button id="buttonOpener"
          data-bind="ojComponent: {component: 'ojButton', label: 'Open Modal Dialog'}">
  </button>
</div>

You must also add code to handle the events on the OK and button opener buttons, in addition to the Knockout applyBindings() call that completes the component binding.

require(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout', 'ojs/ojbutton', 'ojs/ojdialog'],
function(oj, ko, $)
{  
  function dialogModel() {
    var self = this;
     self.handleOpen = $("#buttonOpener").click(function() {
       $("#modalDialog1").ojDialog("open"); });
     self.handleOKClose = $("#okButton").click(function() {
       $("#modalDialog1").ojDialog("close"); });
  }
  $(function() {
    ko.applyBindings(new dialogModel(), document.getElementById('dialogWrapper'));
  });
});

Note:

Although the ojDialog component is wrapped as a jQuery UI widget, its structure differs from the jQuery UI dialog widget. For additional detail, see the ojDialog API documentation.

The Oracle JET Cookbook includes the complete code for this example at Dialogs. You can also find samples for creating a modeless ojDialog and dialogs rendered with custom headers and other display options.

Working with Masonry Layouts

Use the Oracle JET ojMasonryLayout component to create a responsive grid of tiles containing arbitrary content. You can specify the size of each tile by defining the number of rows and columns that the tile will contain relative to the other tiles in the layout.

Masonry layouts are advanced dashboard components that are useful when tiles are of different sizes because the component will shift tiles to fill in gaps, if possible. Masonry layouts are not intended for page layout, and you typically use them when you want to compact tiles in both horizontal and vertical directions at the same time. You can also use masonry layout when you want to allow users to operate on tiles, such as resizing, inserting, deleting, and reordering of tiles. Additionally, masonry layout animates the resulting layout changes to help preserve the context of the user.

The image below shows a basic masonry layout with eight tiles. In this example, the third tile in the layout occupies two columns and one row, the sixth tile occupies one column and two rows, and the remaining tiles occupy one column and one row. As the screen gets narrower the third and fourth tiles interchange their position to fit to the layout size.

Topics:

Configuring Masonry Layouts

Define the ojMasonryLayout on the HTML div element and add the group of sibling child elements that the component will manage. To specify the relative size of the tiles, add one of the ojMasonryLayout size style classes to each child element.

The code sample below shows the markup for the basic ojMasonryLayout shown in this section. The example uses the Knockout foreach binding to iterate through the child elements.

<div id="masonrylayout-basic-example">
  <div class="demo-scroll-container">
    <div id="masonryLayout" data-bind="ojComponent: {component: 'ojMasonryLayout'}">
      <!-- ko foreach: chemicals -->
      <div class="oj-panel oj-panel-alt2 demo-tile" data-bind="text: name, css: sizeClass"></div>
      <!-- /ko -->
    </div>
  </div>
</div>

The size of each tile is determined by the value in the sizeClass variable which is defined in the application's main script shown below.

require(['ojs/ojcore', 'knockout', 'jquery', 
         'ojs/ojknockout', 'ojs/ojmasonrylayout'],
function(oj, ko, $)
{
  $(document).ready(
    function()
    {
      function MyModel() {
        var self = this;
     
        self.chemicals = [
          { name: 'Hydrogen', sizeClass: 'oj-masonrylayout-tile-1x1' },
          { name: 'Helium', sizeClass: 'oj-masonrylayout-tile-1x1' },
          { name: 'Lithium', sizeClass: 'oj-masonrylayout-tile-2x1' },
          { name: 'Beryllium', sizeClass: 'oj-masonrylayout-tile-1x1' },
          { name: 'Boron', sizeClass: 'oj-masonrylayout-tile-1x1' },
          { name: 'Carbon', sizeClass: 'oj-masonrylayout-tile-1x2' },
          { name: 'Nitrogen', sizeClass: 'oj-masonrylayout-tile-1x1' },
          { name: 'Oxygen', sizeClass: 'oj-masonrylayout-tile-1x1' }
        ];
      }
      
      ko.applyBindings(new MyModel(), 
        document.getElementById('masonrylayout-basic-example'));
    }
  );
});

The Oracle JET Cookbook at Masonry Layouts contains the complete example for the basic masonry layout shown in this section. You can also find demos that illustrate the different tile sizes, and masonry layouts that you can resize, reorder, and flip.

Note:

The ojMasonryLayout component does not provide accessibility features such as keyboard navigation. It is the responsibility of the application developer to make the items in the layout accessible. For tips and additional detail, see the ojMasonryLayout API documentation.

Understanding the ojMasonryLayout Layout Process

ojMasonryLayout lays out its child tiles based on the size of the screen, the size of the tiles, and the order in which you define them.

To determine the layout, ojMasonryLayout:

  • Processes the tiles in the order in which they originally appear in the DOM.

  • Determines the number of columns to display based on the width of the component and the width of a 1x1 tile.

  • Determines the number of rows to display based on the number of columns and the number and sizes of tiles to lay out.

  • Lays out the grid cells in a left-to-right, top-to-bottom order (or right-to-left, top-to-bottom order when the reading direction is right-to-left).

    Tiles will be positioned in the first empty cell in which they fit. This can result in empty cells in the layout. Subsequent tiles may fill those earlier gaps if they fit.

If the component is resized, ojMasonryLayout will redo the layout, and the number of columns and rows may change.

ojMasonryLayout Size Style Classes

ojMasonryLayout supports tile sizes ranging from one to three columns and one to three rows, as shown in the following table.

Style Class Description

oj-masonrylayout-tile-1x1

A tile that spans one column and one row

oj-masonrylayout-tile-1x2

A tile that spans one column and two rows

oj-masonrylayout-tile-1x3

A tile that spans one column and three rows

oj-masonrylayout-tile-2x1

A tile that spans two columns and one row

oj-masonrylayout-tile-2x2

A tile that spans two columns and two rows

oj-masonrylayout-tile-2x3

A tile that spans two columns and three rows

oj-masonrylayout-tile-3x1

A tile that spans three columns and one row

oj-masonrylayout-tile-3x2

A tile that spans three columns and two rows

Working with Nav Lists

The Oracle JET ojNavigationList component enhances the HTML list (ul) element to provide a themable, WAI-ARIA compliant component that displays a list of vertical or horizontal navigation links. You can configure the nav list to slide in and out of view, expand and collapse, and respond to changes in screen size.

Topics:

Understanding Data Requirements for Nav Lists

The data source for the ojNavigationList component can be one of the following:

  • Flat or hierarchical static HTML

    The following image shows a vertical nav list that displays static, hierarchical HTML.

    The following code sample shows a portion of the markup used to create the ojNavigationList component with hierarchical static content and the Oracle JET component binding. The markup uses ul and li HTML elements to define the nav list, with nested lists for the hierarchical data. The markup also specifies selectedItem as a Knockout observable in the component's selection option that will update when the user selects a list item.

    <div id="navlistdemo">
      <div id="navlistcontainer" style="max-width:300px">
        <div aria-label="Choose a navigation item" data-bind="ojComponent:{
                        component:'ojNavigationList', 
                        selection: selectedItem,
                        navigationLevel: 'application',
                        drillMode:'none'}">
          <ul>
            <li id="home" >
              <a href="#" >Home</a>
            </li>
            <li id="gettingStarted" >
              <a href="#" >Getting Started</a>
            </li>
            <li id="cookbook">
              <a href="#" >Cookbook</a>
            </li>
            <li id="styleLab" class="oj-disabled">
              <a href="#" >Style Lab</a>
            </li>
            <li id="library">
              <a href="#">Library</a>
              <ul>
                <li id="articles">
                  <a href="#">Article</a>
                </li>
                ... contents omitted
              </ul>
            </li>
          </ul>
        </div>
      </div>
      <br>
      <div>
        <p class="bold">Last selected list item:
          <span data-bind='text: selectedItem'></span>
        </p>
      </div>
    </div>  
    

    The code to apply the binding and define selectedItem is shown below. In this example, the initial value of the Knockout observable is set to save, and the nav list will initially display with the Save item selected.

    require(['ojs/ojcore','knockout','jquery','ojs/ojknockout','ojs/ojnavigationlist'],
      function(oj, ko, $) 
      // this callback gets executed when all required modules are loaded
      {
        function ViewModel(){
          this.selectedItem = ko.observable("home");
        }
        var vm = new ViewModel();
        ko.applyBindings(vm, document.getElementById('navlistdemo'));
      }
    );
    
  • Oracle JET TreeDataSource, including oj.JsonTreeDataSource and oj.CollectionTreeDataSource.

    Typically, you use one of the Oracle JET TreeDataSource components when your list data contains groups. To use a TreeDataSource, specify the method that returns the tree data in the data option for the ojNavigationList component.

    <div aria-label="Choose a navigation item" data-bind="ojComponent:{
                    component:'ojNavigationList',
                    drillMode: 'sliding',
                    optionChange : onSelect,
                    data : dataSource,
                    item: {template: 'folder_template'}
                    }">
    </div>
    
  • Oracle JET TableDataSource, including oj.ArrayTableDataSource and oj.CollectionTableDataSource

    Use oj.ArrayTableDataSource when the underlying data is a static array or Knockout observableArray. If you use an observableArray, the nav list will automatically react when items are added or removed from the array.

    Use oj.CollectionTableDataSource when oj.Collection is the model for the underlying data. The nav list will automatically react to model events from the underlying oj.Collection.

    To use a TableDataSource, specify the method that returns the table data in the data option for the ojNavigationList component.

    <div aria-label="Choose a navigation item" data-bind="ojComponent:{
                    component: 'ojNavigationList', 
                    drillMode: 'none',
                    selection: selectedItem,
                    data: dataSource,
                    item: {template: 'server_template'}}">
    </div>
    

The Oracle JET Cookbook contains a number of ojNavigationList examples, including ones that illustrate the use of each supported data source. For details, see Nav Lists.

Working with Nav Lists and Knockout Templates

You can use a Knockout template to contain the markup for your list item content. Reference the name of the template in the ojNavigationList component's template option.

The code sample below shows a portion of the markup and template for a nav list using an oj.ArrayTableDataSource object for its data. In this example, the template is named server_template.

<div aria-label="Choose a navigation item" data-bind="ojComponent:{
                component: 'ojNavigationList', 
                drillMode: 'none',
                selection: selectedItem,
                data: dataSource, 
                item: {template: 'server_template'}}">
</div>

<script type="text/html" id="server_template">
  <li data-bind="attr:{ id : $data['id']}, css:{'oj-disabled' : $data['disabled']=='true'}">
    <a href="#" data-bind="text: $data['name']"></a>
  </li>
</script>

At runtime, the nav list iterates through the array and displays the content contained in name and applies styling for disabled items.

You can find the complete code sample for this nav list at Nav List (ArrayTableDataSource).

For additional information about working with Knockout templates, see Using Knockout.js Templates and the ojModule Binding.

Working with offCanvasUtils

The Oracle JET framework offCanvasUtils are useful if you want to store content in a region that is not part of the viewport. With the offCanvasUtils, you can configure the region to slide in and out of view at the start, end, top, or bottom of the viewport, either by pushing existing content out of view or by overlaying the region.

The following image shows two examples of regions configured to slide in at the start of the viewport. In the region configured for push, offCanvasUtils pushes aside as much of the viewport content as needed to display the region. In the region configured for overlay, the content is displayed over the main content, obscuring the content.

Configuring an Off-Canvas Partition

To configure an off-canvas partition, create a HTML div wrapper to contain both the content and the off-canvas partition and use offCanvasUtils to show, hide, or toggle the partition view.

The Oracle JET Cookbook Drawer Utilities demos contain the sample code that implements the off-canvas partitions shown in this section and links to the oj.OffcanvasUtils API documentation. You can also find examples that implement the off-canvas partitions as responsive design patterns that change their position from off screen to fixed inside the viewport based on a media query. For more information about responsive design and media queries, see Designing Responsive Applications.

Working with Panels

Panels use Oracle JET styles included with the Alta theme to display a bounded section on the page. You can customize the size, color, and content of the panel.

In this example, three panels are displayed with three different colors. The content for the first two panels is defined using the HTML header and paragraph elements. The content for the third panel is defined as an ojCollapsible component. The oj-panel-* classes are defined on the div elements that represent the panels.

<div id="panelPage">
  <div class="oj-flex">
    <div class="oj-panel demo-mypanel">
      <h3>Header</h3>
      <p>Hello world!</p>
      How is it going out there?
    </div>

    <div class="oj-panel oj-panel-alt1 demo-mypanel">
      <h3 class="oj-header-border">Header</h3>
      <p>Hello world!</p>
      It's going great in JET land.
    </div>

    <div class="oj-panel oj-panel-alt2 demo-mypanel">
      <div data-bind="ojComponent: {component: 'ojCollapsible', expanded: true}">
        <h3>Header</h3>
        <div>
          <p>I'm a collapsible inside a panel</p>
          When you close the collapsible the panel will shrink.
        </div>
      </div>
    </div>
  </div>
</div>

When panels are on the same row they will have equal height because they are in a div element defined with the oj-flex style class. You can change the default behavior by adding responsive classes to set alignment. For an example, see Flex Layouts - Align.

You can customize the size or display using styles, or you can create a custom style class. In this example, the panel is customized using the demo-mypanel class, shown below.

.demo-mypanel {
  width:  200px;
}

The Oracle JET Cookbook contains the complete code for this example at Panel Content. You can also find an example that shows the available panel colors at Panel Colors.

For additional information about using and customizing the Oracle JET themes included with Oracle JET, see Theming Applications. For more information about the ojCollapsible component, see Working with Collapsibles.

Working with Popups

The Oracle JET popup framework includes the ojPopup component that you can use to create popups on your page. To manage stacking order of ojPopup and all Oracle JET components that use popups internally, such as ojDialog and ojMenu, the popup framework uses the CSS z-index property and re-parents the popup DOM into a zorder container.

Topics:

Working with ojPopup

You can use the Oracle JET ojPopup component to create themable popups that follow WAI-ARIA authoring practices for accessibility. The image below shows a popup displayed with default options, but you can customize the popup's modality, position, tail, and chrome.

You can create the ojPopup on the HTML div or span element. Add the popup's content as the child of that element. For the image shown above, the ojPopup is defined on the div element, with the content defined in the span element.

<div style="display:none" id="popup1"
     data-bind="ojComponent:{component: 'ojPopup'}">
  <span>Hello World!!!</span>
</div>

In this example, the popup displays when the user clicks Go. The Go button is defined as an ojButton component that references the popup's id attribute to display the popup when clicked.

<div id="popupWrapper">
  <div style="display:none" id="popup1"
       data-bind="ojComponent:{component: 'ojPopup'}">
    <span class="blink-rainbow">Hello World!!!</span>
  </div>
  <button id="btnGo"
    data-bind="ojComponent: {component: 'ojButton', label: 'Go'},
               click: function()
               {
                 $('#popup1').ojPopup('open', '#btnGo');
               }">
  </button>
</div>

In this example, the popup’s modality defaults to modeless which means that the popup will not block user input on the page behind the popup. You can change this to modal by setting the component’s modality option as described in the ojPopup API documentation.

data-bind="ojComponent:{component: 'ojPopup', modality:'modal'}"

When the user clicks the Go button now, the popup blocks user input of the page behind the popup with a blocking overlay pane.

The image is described in the surrounding text.

The popup’s default modality is defined in the $popupModalityOptionDefault SCSS variable and is specific to the chosen theme. For the Alta desktop theme, the SCSS variable is set to null which defaults to modeless, and the code sample below shows the generated CSS:

.oj-popup-option-defaults {
  font-family: "{}"; }

The Oracle JET Cookbook contains the complete example for this popup at Popups. You can also find examples that customize the popup and that use the popup as a tooltip for accessibility.

Note:

The ojPopup component defines default roles for accessibility and keyboard navigation. You can find details about the component's accessibility support in the ojPopup API documentation. In addition, you can find some general recommendations about best practices for making the gestures that launch the popup accessible.

Working with the Oracle JET Popup Framework

The popup framework uses the CSS z-index property and re-parents the popup DOM to manage the stacking order of ojPopup and all Oracle JET components that use popups internally, such as ojDialog and ojMenu. z-index defaults should be sufficient for most purposes, but you can modify them using SCSS variables to generate new CSS or modify the CSS styles directly.

When a popup of any type opens, the Oracle JET framework re-parents it into a zorder container in the document body and re-parents it back to its original location when closed. For example, if you add the ojPopup component shown in Working with ojPopup to the main content in an Oracle JET Web Nav Drawer Starter Template, the browser DOM reflects its initial placement within the document body.

When the user clicks the Go button to display the popup, the Oracle JET framework re-parents it into the oj_zorder_container div as a direct child of the body element.

The purpose of re-parenting is to better manage the stacking context as it relates to how popups are used versus where they are defined in the document. The zorder container has a default root container that holds popups open. When the popup is re-parented, it is wrapped in a div containing the oj-popup-layer style and assigned a z-index weight. If there are multiple open popups on the page, each popup is re-parented to the zorder container, and the active popup will be the popup with the highest z-index weight.

For example, at initial display, the ojPopup's layer is marked with the oj-popup-layer style which has a z-index value of 1000. Popups of the same type are assigned the same z-index values. If there are multiple popups open, the popup that has active focus will be assigned a greater z-index value of 1001, and the oj-popup-layer.oj-focus-within style is applied.

In most cases, you should never need to modify the CSS z-index defaults since the resulting behavior may be unpredictable. If needed, however, you can update the SCSS variables used to generate the application's CSS or modify the CSS styles directly. The following table shows the default CSS style selectors, SCSS variables, and z-index values.

CSS Selector SCSS Variable Z-Index Value

oj-popup-layer

$popupZindex

1000

oj-popup-layer.oj-focus-within

$popupZindex + 1

1001

oj-popup-layer.oj-popup-tail-simple

$noteWindowZindex

1030

oj-popup-layer.oj-popup-tail-simple.oj-focus-within

$noteWindowZindex + 1

1031

oj-listbox-drop-layer

$popupZindex

1000

oj-menu-layer

$popupZindex

1000

oj-dialog-layer

$dialogZindex

1050

oj-dialog-layer.oj-focus-within

$dialogZindex + 1

1051

oj-component-overlay

Uses z-index value of associated oj-popup_type-layer. For example, the z-index of oj-dialog-layer is 1050, and oj-component-overlay will use 1050 when the associated popup is a dialog.

Varies according to oj-popup_type-layer.

When popup components are initially defined on the page, they are defined with a default z-index value of 1 using the CSS selectors shown in the following table. The root popup is absolutely positioned on the page in relation to its parent container. Setting the value to 1 ensures that the root popup's children will display above the popup.

Oracle JET Component CSS Selector SCSS Variable Z-Index Value

ojMenu

oj-menu

$defaultZindex

1

ojPopup

oj-popup

$defaultZindex

1

ojDialog

oj-dialog

$defaultZindex

1

ojCombobox, ojSelect

oj-listbox-drop

$defaultZindex

1

ojInputDateTime, ojInputDate, ojInputTime

oj-popup

$defaultZindex

1

Editable components using note windows for messaging

oj-popup.oj-popup-tail-simple

$defaultZindex

1

For additional information about Oracle JET's popup strategy, see the ojPopup API documentation.

For additional information about Oracle JET's use of CSS and SCSS, see Theming Applications. For more information about the CSS z-index property, see http://www.w3.org/wiki/CSS/Properties/z-index.

Working with Tabs

You can use the Oracle JET ojTabs component to create themable, sortable, and removable tabs that follow WAI-ARIA authoring practices for accessibility. The tab bar is customizable, and you can add buttons, radiosets, or other components as needed. The tab bar position is also customizable, and you can configure the tab bar to display on the top, bottom, or side (start or end) of the tab's content, as shown in the following image.

To create the ojTabs component, add it to a HTML div container element on your page. To create the tab bar, add the HTML ul element, and add li child elements for each tab. To define the tab content, add div elements for each as a direct child of the container div in the order in which you want the content to appear.

The code sample below shows the markup for an ojTabs component that contains four tabs that display text. In this example, the tab bar position is set to bottom, and the fourth tab is disabled.

<div id="tabs-container">
  <div id="tabs" data-bind="ojComponent:{component: 'ojTabs', disabledTabs: [3], edge: 'bottom'}">
    <!-- tab bar -->
    <ul>
      <li><span>Tab 1</span></li>
      <li><span>Tab 2</span></li>
      <li><span>Tab 3</span></li>
      <li><span>Disabled Tab</span></li>
    </ul>
 
    <!-- tab contents -->
    <div id="tabs-1">
      <p>Tab 1 Content</p>
    </div>
    <div id="tabs-2">
      <p>Tab 2 Content</p>
    </div>
    <div id="tabs-3">
      <p>Tab 3 Content</p>
    </div>
    <div id="tabs-4">
      <p>Disabled Tab Content</p>
    </div>
  </div>
</div>

Note:

Although the ojTabs component is wrapped as a jQuery UI widget, its structure differs from the jQuery UI tabs widget. For additional detail, see the ojTabs API documentation.

The Oracle JET Cookbook includes the code sample for creating a basic ojTabs component pictured in this section at Tabs. In addition, you will find samples that show events that are triggered on the ojTabs component, add and remove tabs to a page, create horizontal tabs inside vertical tabs, and create tabs that are sortable, contain icons for the header, or that truncate depending on the width of the display.