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);
}());