wearefine/fae

View on GitHub
app/assets/javascripts/fae/form/_form_manager.js

Summary

Maintainability
C
1 day
Test Coverage
/* global Fae */

/**
 * Fae form manager
 * @namespace form
 * @memberof Fae
 */
Fae.form.formManager = {

  $theForm:                 null,
  $managerForm:             null,
  savedFieldSettings:       null,
  mainContentClass:         'main-content',
  fmContainerClass:         'js-form-manager-container',
  formManagerFormClass:     'form-manager-form',
  launchManagerClass:       'js-launch-form-manager',
  cancelManagerClass:       'js-form-manager-cancel',
  saveAndCloseManagerClass: 'js-form-manager-submit',
  helperTextTextElClass:    'helper_text_text',
  infoAttr:                 'data-form-manager-info',
  languageAttr:             'data-language',
  requiredEl:               '<abbr title="required">*</abbr> ',
  containerManagerDataId:   'data-form-manager-id',
  ignoredFields: [
    'seo_title',
    'seo_description',
    'social_media_title',
    'social_media_description',
    'social_media_image'
  ],

  init: function(formSelector) {
    var _this      = this;
    formSelector   = formSelector || 'form:first';
    _this.$theForm = $(formSelector);

    // Draw initial label/helper overrides
    _this.setupAllFields(_this.$theForm);

    $('body').on('click', '.'+_this.launchManagerClass, function(e) {
      e.preventDefault();
      _this.$theForm = $(this).parents('form');
      _this._launchManager($(this));
    });

    $('body').on('click', '.'+_this.saveAndCloseManagerClass, function(e) {
      e.preventDefault();
      _this._saveAndCloseManager($(this));
    });

    $('body').on('click', '.'+_this.cancelManagerClass, function(e) {
      e.preventDefault();
      _this._closeManager($(this));
    });

  },

  setupAllFields: function($theForm) {
    _this = this;
    if ($theForm.length && $theForm.attr(_this.infoAttr)) {
      this.savedFieldSettings = JSON.parse($theForm.attr(_this.infoAttr));

      $.each(JSON.parse(this.savedFieldSettings.fields), function(i, fieldSettings) {
        _this._determineFieldSetup(fieldSettings);
      });
    }
  },

  _determineFieldSetup: function(fieldSettings) {
    var $container = $('[data-form-manager-id="'+fieldSettings.formManagerId+'"]');
    _this._setupField($container, fieldSettings.label, fieldSettings.helper);

    if ($container.hasClass('image')) {
      var $captionContainer = $('.' + fieldSettings.formManagerId + '_caption_container');
      var $altContainer = $('.' + fieldSettings.formManagerId + '_alt_container');

      if ($captionContainer) {
        var captionLabel = fieldSettings.label + ' Caption';
        _this._setupField($captionContainer, captionLabel, '');
      }
      if ($altContainer) {
        var altLabel = fieldSettings.label + ' Alt Text';
        _this._setupField($altContainer, altLabel, '');
      }
    }
  },

  _setupField: function($container, overriddenLabel, overriddenHelper) {
    var _this = this;
    if ($container.length) {
      var $label                 = $container.find('label:first');
      var $helperTextContainerEl = $container.find('h6');
      var $labelInner            = $label.find('.label_inner');
      var $labelTextEl           = $label;
      if ($labelInner.length) {
        $labelTextEl = $labelInner;
      }
      var $labelsCheckbox = $labelTextEl.find('input');

      var newLabelText = '';
      if ($container.hasClass('required') || $label.hasClass('required') || $labelInner.text().indexOf('*') !== -1) {
        newLabelText = _this.requiredEl;
      }

      newLabelText += overriddenLabel;
      $labelTextEl.html(newLabelText);

      if($labelsCheckbox.length) {
        $labelTextEl.append($labelsCheckbox);
      }

      // Don't mess with image alt text or caption helpers
      if ($container.attr('class').indexOf('alt_container') !== -1
          || $container.attr('class').indexOf('caption_container') !== -1
         ) {
        return;
      }

      // Just do the helper thing no matter what, aka allow empty
      $label.removeClass('has_no_helper_text');

      // Main form and nested form markup differs, deal with it
      if ($container.find('h6').length) {
        $label.find('.'+_this.helperTextTextElClass).text(overriddenHelper);
      } else {
        if ($helperTextContainerEl.length) {
          $helperTextContainerEl.find('.'+_this.helperTextTextElClass).text(overriddenHelper);
        } else {
          $helperTextContainerEl = $('<h6 />', {class: 'helper_text'}).append($('<span />', {class: 'helper_text_text', text: overriddenHelper}));
        }
        $label.append($helperTextContainerEl);
      }
    }
  },

  _launchManager: function() {
    var _this = this;

    // Show all language inputs so we can manage them
    _this.$theForm.find('['+_this.languageAttr+']').show();

    _this.$managerForm =
      $('<form />', {action: '#', class: _this.formManagerFormClass})
        .append($('<header />', {class: 'content-header js-content-header js-will-be-sticky'})
          .append($('<a />', {href: '#', text: 'Cancel', class: 'button '+_this.cancelManagerClass}))
          .append($('<a />', {href: '#', text: 'Submit', class: 'button js-form-manager-submit'}))
      );

    // Insert a bunch of inputs for label/helper text
    _this._gatherAndInjectManagerEls();

    $('.'+_this.fmContainerClass).append(_this.$managerForm);
    _this._revealManagerForm();

  },

  _gatherAndInjectManagerEls: function() {
    $(_this.$theForm.find('['+_this.containerManagerDataId+']')).each(function(i) {
      var $container    = $(this);

      if ($container.hasClass('hidden') || !_this._shouldDisplayInManager($container)) { return; }

      var $label        = $container.find('label:first');
      var $labelTextEl  = $label;
      var $labelInner   = $label.find('.label_inner');
      if ($labelInner.length) {
        $labelTextEl = $labelInner;
      }
      var $helperTextTextEl  = $label.find('.'+_this.helperTextTextElClass);
      var containerManagerId = $container.attr(_this.containerManagerDataId);
      var iDParts            = containerManagerId.split('_');
      iDParts.shift();
      var fMLabelText        = _this._titleize(iDParts.join(' '));
      var labelInputValue    = $labelTextEl.clone().children().remove().end().text().replace('*','').trim();
      var helperInputValue   = $helperTextTextEl.text();

      var $fmFieldContainer             = $('<div />', {class: "form-section", 'data-form-manager-id': $container.attr('data-form-manager-id')});
      var $fmSingleFieldContainer       = $('<div />', {class: "single-field"});
      var $fmSingleHelperFieldContainer = $('<div />', {class: "single-field"});
      var $fmFieldTitle                 = $('<div />', {class: "field_title"});
      var $fmHelperFieldTitle           = $('<div />', {class: "field_title"});
      var $fMLabel                      = $('<label />', {text: fMLabelText, class: 'fm_label'});
      var $fMHelper                     = $('<label />', {text: 'Helper', class: 'fm_label'});
      var $labelInput                   = $('<input />', {type: 'text', id: $container.attr('data-form-manager-id')+'_label_input', class: 'label_input', value: labelInputValue});
      var $helperInput                  = $('<input />', {type: 'text', id: $container.attr('data-form-manager-id')+'_helper_input', class: 'helper_input', value: helperInputValue});

      _this.$managerForm.append(
        $fmFieldContainer.append(
          $fmSingleFieldContainer.append(
            $fmFieldTitle.append(
              $fMLabel
            ),
            $labelInput
          ),
          $fmSingleHelperFieldContainer.append(
            $fmHelperFieldTitle.append(
              $fMHelper
            ),
            $helperInput
          )
        )
      );

    });
  },

  _revealManagerForm: function() {
    var _this = this;
    $('.'+_this.mainContentClass).hide();
    $('.'+_this.fmContainerClass).show();
    $('.'+_this.formManagerFormClass).fadeIn('fast');
  },

  _saveAndCloseManager: function() {
    _this = this;
    _this._submitManager();
    _this._closeManager();
  },

  _closeManager: function() {
    var _this = this;
    $('.'+_this.fmContainerClass).children().remove();
    $('.'+_this.mainContentClass).show();
  },

  _submitManager: function() {
    var _this = this;
    var payload = {
      form_manager: {
        form_manager_model_name: _this.$theForm.data('form-manager-model'),
        form_manager_model_id:   _this.$theForm.data('form-manager-model-id'),
        fields: {}
      }
    };

    // Gather everything in the inputs for a POST
    $.each(_this.$managerForm.find('['+_this.containerManagerDataId+']'), function(i) {
      var $container    = $(this);
      var formManagerId = $container.attr(_this.containerManagerDataId);
      var requiredValue = $container.hasClass('required') ? 1 : 0;

      payload.form_manager.fields[formManagerId] = {
        formManagerId: formManagerId,
        label:         $container.find('.label_input').val(),
        helper:        $container.find('.helper_input').val(),
        required:      requiredValue
      };
    });

    // Reset the labels/helpers to the custom ones just made
    $.each(payload.form_manager.fields, function(i, fieldSettings) {
      _this._determineFieldSetup(fieldSettings);
    });

    $.ajax({
      url: Fae.path+'/form_managers/update',
      type: 'post',
      data: payload,
      headers: {
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
      },
      dataType: 'json',
      success: function (data) {
        // do something?
      }
    });

  },

  _shouldDisplayInManager: function($container) {
    var _this = this;
    var should = true;
    $(_this.ignoredFields).each(function(i, fuzzyClass) {
      if ($container.attr('class').indexOf(fuzzyClass) > -1) {
        should = false;
        return false;
      }
    });
    return should;
  },

  _capitalize: function(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  },

  _titleize: function(str) {
    var _this = this;
    var string_array = str.split(' ');
    string_array = string_array.map(function(str) {
       return _this._capitalize(str);
    });
    return string_array.join(' ');
  }

};