Quantcast
Channel: Oracle Bloggers
Viewing all articles
Browse latest Browse all 19780

JET Composite Components XVI - Components in Form Layouts

$
0
0

Introduction

A common use for Composite Components is to create enhanced input components that address specialized use cases. A good example of this might be a specialized input component for entering IP Address formats. With this kind of component you would want to be able to use it everywhere that a normal JET input* type could be used. This article discusses the pattern that you can adopt to make this happen.

What's the Problem?

To illustrate this process I'm going to use an example form from a little application that I'm building. This is a wizard based UI that, guess-what, helps you to create CCAs. Here's an early version of one of the screens:

This form uses a classic oj-form-layout to responsively align the fields:

<div class="oj-form-layout">
      <div class="oj-form oj-sm-odd-cols-12 oj-md-odd-cols-3 oj-md-labels-inline">
        <div class="oj-flex">
          <div class="oj-flex-item">
            <label for="ccaname"
                   data-bind="text:res.ccawEditor.nameLabel"/>
          </div>
          <div class="oj-flex-item">
            <input id="ccaname"  placeholder="my-component"
                   data-bind="ojComponent: {component: 'ojInputText',
                                            value:workingCopy.name,
                                            required: true,
                                            rootAttributes: {
                                            style:'max-width:30em'}}">
          </div>
        </div>
        <div class="oj-flex">
          <div class="oj-flex-item">
            <label for="ccaversion"
                   data-bind="text:res.ccawEditor.versionLabel"/>
          </div>
          <div class="oj-flex-item">
            <input id="ccaversion"
                   data-bind="ojComponent: {component: 'ojInputText',
                                            value:workingCopy.version, required: true}">
          </div>
        </div>
        <div class="oj-flex">
          <div class="oj-flex-item">
            <label for="ccajversion"
                   data-bind="text:res.ccawEditor.jetVersionLabel"/>
          </div>
          <div class="oj-flex-item">
            <input id="ccajversion"
                   data-bind="ojComponent: {component: 'ojInputText',
                                            value:workingCopy.jetVersion, required: true}">
          </div>
        </div>
        <div class="oj-flex">
          <div class="oj-flex-item">
            <label for="ccadesc"
                   data-bind="text:res.ccawEditor.descriptionLabel"/>
          </div>
          <div class="oj-flex-item">
            <textarea id="ccadesc" rows="6" style="resize: both;"
                      data-bind="ojComponent: {
                          component: 'ojTextArea',
                          value: workingCopy.description,
                          rootAttributes: {style:'max-width:60%'}}"></textarea>
          </div>
        </div>
      </div>
    </div>
    

In this screen we can see a couple of version related fields. Right now these are simple ojInputText fields but I want to replace them with something a little more intelligent that would include behaviors such as validating the version according to Semantic Versioning rules and allowing range selection. So this seems like a good candidate for a Composite Component!

So the Composite Component (called <ccaw-semvar-input>) is created and dropped into replace the existing version number inputs:

<div class="oj-form-layout">
        <div class="oj-form oj-sm-odd-cols-12 oj-md-odd-cols-3 oj-md-labels-inline">
          <div class="oj-flex">
            <div class="oj-flex-item">
              <label for="ccaname"
                     data-bind="text:res.ccawEditor.nameLabel"/>
            </div>
            <div class="oj-flex-item">
              <input id="ccaname"  placeholder="my-component"
                     data-bind="ojComponent: {component: 'ojInputText',
                                              value:workingCopy.name,
                                              required: true,
                                              rootAttributes: {
                                              style:'max-width:30em'}}">
            </div>
          </div>
          <div class="oj-flex">
            <div class="oj-flex-item">
              <label for="ccaversion"
                     data-bind="text:res.ccawEditor.versionLabel"/>
            </div>
            <div class="oj-flex-item">
              <ccaw-semver-input id="ccaversion" version="{{workingCopy.version}}"
                               placeholder="1.0.0"
                               range-selection="false" required="true"/>

            </div>
          </div>
          <div class="oj-flex">
            <div class="oj-flex-item">
              <label for="ccajversion"
                     data-bind="text:res.ccawEditor.jetVersionLabel"/>
            </div>
            <div class="oj-flex-item">
              <ccaw-semver-input id="ccajversion" version="{{workingCopy.jetVersion}}"
                                 placeholder="2.3.0"
                                 range-selection="true" required="true"/>
            </div>
          </div>
          <div class="oj-flex">
            <div class="oj-flex-item">
              <label for="ccadesc"
                     data-bind="text:res.ccawEditor.descriptionLabel"/>
            </div>
            <div class="oj-flex-item">
              <textarea id="ccadesc" rows="6" style="resize: both;"
                        data-bind="ojComponent: {
                            component: 'ojTextArea',
                            value: workingCopy.description,
                            rootAttributes: {style:'max-width:60%'}}"></textarea>
            </div>
          </div>
        </div>
      </div>
  
Unfortunately, if you just do a straight substitution like this, then the result is not what you'd like:

As you can see we have two problems, firstly we've lost the alignment with the other field labels and secondly we've lost the required indicator. Let's look at solving each of those in turn.

Correcting the Alignment

What we're seeing here is not a bug in the framework, it is expected behavior for cases where you are mixing non-JET components into the form layout. The solution is actually outlined within the existing cookbook demo Form Layout - Non Components. All we have to do is to apply the classes oj-label-nocomp oj-label-for-non-control to the label e.g.

<div class="oj-flex">
      <div class="oj-flex-item">
        <label for="ccaversion"
               class="oj-label-nocomp oj-label-for-non-control"
               data-bind="text:res.ccawEditor.versionLabel"/>
      </div>
      <div class="oj-flex-item">
        <ccaw-semver-input id="ccaversion" version="{{workingCopy.version}}"
                         placeholder="1.0.0"
                         range-selection="false" required="true"/>

      </div>
    </div>
  
This will ensure that the labels are now correctly aligned.

Adding the Required Indicator

For the case of using a non-JET component, the framework supplies a class specifically for rendering the *required indicator. This class is called oj-label-required-icon. However, one thing we can't do is this:

<label class="oj-label-nocomp oj-label-for-non-control  oj-label-required-icon" .../>
  
Doing so would result in this:

As you can see, the required indicator is overriding both the color and font information for the label if it is applied directly. Thus the correct usage is:
<label class="oj-label-nocomp oj-label-for-non-control" for="ccajversion"&gt,
    <span class="oj-label-required-icon"/>
    <span data-bind="text:res.ccawEditor.jetVersionLabel"/>
  &lt/span>
  
With these small changes to the label styles the layout and responsiveness of your oj-form-layouts will return and you can mix in your composite components at will.


CCA Series Index

  1. Introduction
  2. Your First Composite Component - A Tutorial
  3. Composite Conventions and Standards
  4. Attributes, Properties and Data
  5. Events
  6. Methods
  7. The Lifecycle
  8. Slotting Part 1
  9. Slotting Part 2
  10. Custom Property Parsing
  11. Metadata Extensibility
  12. Advanced Loader Scripts
  13. Deferred UI Loading
  14. Using ojModule in CCAs
  15. Language Support
  16. CCAs in Form Layouts

Viewing all articles
Browse latest Browse all 19780

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>