Warning: We no longer develop features for this version of SKY UX, and we recommend that you use the latest version instead. This site describes the AngularJS (1.x) implementation of the SKY UX framework. We still support this version, but it is in maintenance mode. For more information, see developer.blackbaud.com/skyux.

Sectioned form

Sectioned forms are used when displaying a large amount of conceptually related information.

Sectioned form settings

  • bb-sectioned-form-sections — An array of sections. Each section can have the following properties:
    • formName(Optional.) A form name to associate with the section. If specified, the sectioned form will provide a visual indicator if any required fields are present and if the section is invalid after being submitted. The functionality provided around forms requires that the sectioned form component have a parent form of which the section forms are children.
    • heading — The display text used to identify the section.
    • itemCount(Optional.) The number of items contained within a given section.
    • templateUrl — The URL to the section's content template.
  • bb-sectioned-form-on-sections-visibility-change() — An optional expression called when the form sections' visibility is changed. The expression will be called with the following properties:
    • data — State representation pertaining to the visibility change.
      • visible — The visible state of the sections.
  • bb-sectioned-form-active-section-index — The index of a section that should be made active.
  • bb-sectioned-form-on-active-section-index-change() — An optional expression called when the active section is changed. The expression will be called with the following properties:
    • index — The index of the active section.

Sectioned form events

  • reinitializeSectionDisplay — Causes the form to revert to its initial display state.
  • bb-sectioned-modal — An attribute that may be applied to the bb-modal directive in order to style the modal for use with a sectioned form.

Demo

Markup

<div ng-controller="SectionedModalTestPageController as secModalCtrl">
  <button class="btn btn-primary" ng-click="secModalCtrl.openForm()" type="button">Open tab sectioned modal</button>
</div>

<script type="text/ng-template" id="demo/sectionedform/contactsectionedform.html">
  <bb-modal bb-sectioned-modal>
    <div class="modal-form" ng-controller="ContactSectionedFormController as contactSecFrmCtrl">
      <bb-modal-header>Tab sectioned modal - Index: <span>{{contactSecFrmCtrl.activeSectionIndex}}</span></bb-modal-header>
      <form name="contactForm" ng-submit="contactSecFrmCtrl.save()" novalidate>
        <div bb-modal-body>
          <bb-sectioned-form bb-sectioned-form-sections="contactSecFrmCtrl.sections" 
                             bb-sectioned-form-on-sections-visibility-change="contactSecFrmCtrl.sectionsVisibilityChanged(data)"
                             bb-sectioned-form-active-section-index="contactSecFrmCtrl.activeSectionIndex" 
                             bb-sectioned-form-on-active-section-index-change="contactSecFrmCtrl.activeSectionIndex = index">            
          </bb-sectioned-form>
        </div>
        <bb-modal-footer>
          <bb-modal-footer-button ng-click="contactSecFrmCtrl.showSections()" ng-if="contactSecFrmCtrl.sectionsHidden">Show sections</bb-modal-footer-button>
          <bb-modal-footer-button-primary></bb-modal-footer-button-primary>
          <bb-modal-footer-button-cancel></bb-modal-footer-button-cancel>
        </bb-modal-footer>
      </form>
    </div>
  </bb-modal>
</script>

<script type="text/ng-template" id="demo/sectionedform/basicinfo.html">
  <ng-form name="basicInfoForm" ng-controller="BasicInfoSectionController as basicInfo">
    <div class="row">
      <div class="col-xs-12 col-sm-6">
        <label class="control-label" for="name" ng-class="{'required': basicInfo.nameIsRequired}">Name</label>
        <input class="form-control" name="name" ng-model="basicInfo.fields.name" type="text" ng-required="basicInfo.nameIsRequired" />
      </div>
      <div class="col-xs-12 col-sm-6">
        <label class="control-label" for="id">Id</label>
        <input class="form-control" name="id" ng-model="basicInfo.fields.id" type="text" />
      </div>
    </div>
    <div class="row" style="padding-top: 10px;">
      <div class="col-xs-12">
        <label class="control-label" for="nameIsRequired">
          <input bb-check name="nameIsRequired" ng-model="basicInfo.nameIsRequired" type="checkbox" /> Mark 'Name' required
        </label>
      </div>
    </div>
  </ng-form>
</script>

<script type="text/ng-template" id="demo/sectionedform/addresses.html">
  <div class=" form-group">
    <div class="row">
      <div class="col-xs-12">
        <label>Home</label>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <label class="control-label">410 17th Street<br/>Denver, CO 80202-4402</label>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <label>Vacation</label>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <label class="control-label">3345 Franciscan Way<br/>Tampa, FL 10255-0098</label>
      </div>
    </div>
  </div>
</script>

<script type="text/ng-template" id="demo/sectionedform/phonenumbers.html">
  <div class=" form-group">
    <div class="row">
      <div class="col-xs-12">
        <label>Home</label> <label class="control-label">303.997.3301</label>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <label>Mobile</label> <label class="control-label">888.387.1211</label>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-12">
        <label>Work</label> <label class="control-label">303.997.2000</label>
      </div>
    </div>
  </div>
</script>

JavaScript

/*global angular */
(function () {
    'use strict';

    function SectionedModalTestPageController(bbModal) {
        var self = this;

        self.openForm = function () {
            bbModal.open({
                templateUrl: 'demo/sectionedform/contactsectionedform.html'
            });
        };
    }

    function ContactSectionedFormController($scope, ContactSectionedFormService) {
        var self = this;

        self.sections = [
            {
                formName: 'basicInfoForm',
                heading: 'Basic information',
                templateUrl: 'demo/sectionedform/basicinfo.html'
            },
            {
                heading: 'Addresses',
                itemCount: 2,
                templateUrl: 'demo/sectionedform/addresses.html'
            },
            {
                heading: 'Phone numbers',
                itemCount: 3,
                templateUrl: 'demo/sectionedform/phonenumbers.html'
            }
        ];

        //Open to addresses section
        self.activeSectionIndex = 1;

        // Simulate requesting a value from within a section
        self.save = function () {
            alert('Name = ' + ContactSectionedFormService.basicInfo.name);
            // Could also navigate form controllers, if using
            // alert('Name = ' + $scope.contactForm.basicInfoForm.name.$modelValue);
        }

        self.sectionsVisibilityChanged = function (data) {
            self.sectionsHidden = !data.visible;
        }

        self.showSections = function () {
            $scope.$broadcast('reinitializeSectionDisplay');
        };

        // Simulate pre-populating a field within a section
        ContactSectionedFormService.basicInfo = {
            id: '5324901'
        };
    }

    function BasicInfoSectionController(ContactSectionedFormService) {
        var self = this;
        self.fields = ContactSectionedFormService.basicInfo;
    }

    SectionedModalTestPageController.$inject = ['bbModal'];
    ContactSectionedFormController.$inject = ['$scope', 'ContactSectionedFormService'];
    BasicInfoSectionController.$inject = ['ContactSectionedFormService'];

    angular.module('stache')
        .controller('SectionedModalTestPageController', SectionedModalTestPageController)
        .controller('ContactSectionedFormController', ContactSectionedFormController)
        .service('ContactSectionedFormService', function () {})
        .controller('BasicInfoSectionController', BasicInfoSectionController);
}());