JSFiddle - React, Tailwind, and code Playground

by Shaun Scovil

HTML

<div ng-app="myApp"
     ng-controller="MyViewController as view">
  <my-multi-part-form part="{{view.part}}">
    <my-form-part on-submit="view.save(data)">
      <label>
        Name:
        <input type="text" ng-model="formPart.data.name">
      </label>
      <button my-form-part-submit>
        Next
      </button>
    </my-form-part>
    <my-form-part on-submit="view.save(data)">
      <label>
        Age:
        <input type="number" ng-model="formPart.data.age">
      </label>
      <button my-form-part-submit>
        Next
      </button>
    </my-form-part>
    <my-form-part on-submit="view.save(data)">
      <label>
        Gender:
        <select ng-model="formPart.data.gender">
          <option value="male">Male</option>
          <option value="female">Female</option>
        </select>
      </label>
      <button my-form-part-submit>
        Done
      </button>
    </my-form-part>
  </my-multi-part-form>
  <div ng-if="view.part > 2">
    Complete!
  </div>
</div>

JavaScript

'use strict';

angular.module('myApp', [])
  .controller('MyViewController', MyViewController)
  .directive('myMultiPartForm', myMultiPartFormDirective)
  .controller('MultiPartFormController', MultiPartFormController)
  .directive('myFormPart', myFormPartDirective)
  .controller('FormPartController', FormPartController)
  .directive('myFormPartSubmit', myFormPartSubmitDirective)
;

function MyViewController($http) {
  var view = this;
  view.part = 0;
  view.save = function(data) {
    console.log('view save method called');
    $http({
      method : 'POST',
      url    : 'https://example.com',
      data   : data
    }).then(function success(res) {
      console.log('view save success callback');
    }).catch(function error(err) {
      console.log('view save error callback');
    }).finally(function complete() {
      view.part++;    
    });
  };
}

function myMultiPartFormDirective() {
  return {
    controller  : 'MultiPartFormController',
    controllerAs: 'multiPartForm',
    link        : postLink
  };

  function postLink(scope, iElement, iAttrs, multiPartForm) {
    console.log('multiPartForm DOM element linked');
    iAttrs.$observe('part', function (newValue) {
      console.log('multiPartForm part attribute changed');
      angular.forEach(multiPartForm.parts, function (part, index) {
        if (index == newValue) part.show();
        else part.hide();
      });
    });
  }
}

function MultiPartFormController() {
  console.log('multiPartForm controller instantiated');
  var multiPartForm = this;
  multiPartForm.parts = [];
}

function myFormPartDirective() {
  return {
    bindToController: {
      onSubmit: '&'
    },
    controller      : 'FormPartController',
    controllerAs    : 'formPart',
    link            : postLink,
    require         : ['myFormPart', '^myMultiPartForm'],
    scope           : true,
    template        : '<ng-transclude></ng-transclude>',
    transclude      : true
  };

  function postLink(scope, iElement, iAttrs,...