• Jump To … +
    <<< back to documentation base.js constraint.js defaults.js factory.js field.js form.js main.js multiple.js pubsub.js remote.js ui.js utils.js validator.js validator_registry.js
    • factory.js

    • ¶
      import $ from 'jquery';
      import Utils from './utils';
      import Base from './base';
      import Form from './form';
      import Field from './field';
      import Multiple from './multiple';
      
      var Factory = function (element, options, parsleyFormInstance) {
        this.element = element;
        this.$element = $(element);
    • ¶

      If the element has already been bound, returns its saved Parsley instance

        var savedparsleyFormInstance = this.$element.data('Parsley');
        if (savedparsleyFormInstance) {
    • ¶

      If the saved instance has been bound without a Form parent and there is one given in this call, add it

          if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
            savedparsleyFormInstance.parent = parsleyFormInstance;
            savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
          }
      
          if ('object' === typeof options) {
            Object.assign(savedparsleyFormInstance.options, options);
          }
      
          return savedparsleyFormInstance;
        }
    • ¶

      Parsley must be instantiated with a DOM element or jQuery $element

        if (!this.$element.length)
          throw new Error('You must bind Parsley on an existing element.');
      
        if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__)
          throw new Error('Parent instance must be a Form instance');
      
        this.parent = parsleyFormInstance || window.Parsley;
        return this.init(options);
      };
      
      Factory.prototype = {
        init: function (options) {
          this.__class__ = 'Parsley';
          this.__version__ = 'VERSION';
          this.__id__ = Utils.generateID();
    • ¶

      Pre-compute options

          this._resetOptions(options);
    • ¶

      A Form instance is obviously a <form> element but also every node that is not an input and has the data-parsley-validate attribute

          if (this.element.nodeName === 'FORM' || (Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))
            return this.bind('parsleyForm');
    • ¶

      Every other element is bound as a Field or FieldMultiple

          return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
        },
      
        isMultiple: function () {
          var type = Utils.getType(this.element);
          return ((type === 'radio' || type === 'checkbox') ||
            (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')));
        },
    • ¶

      Multiples fields are a real nightmare :( Maybe some refactoring would be appreciated here…

        handleMultiple: function () {
          var name;
          var multiple;
          var parsleyMultipleInstance;
    • ¶

      Handle multiple name

          this.options.multiple = this.options.multiple ||
            (name = this.element.getAttribute('name')) ||
            this.element.getAttribute('id');
    • ¶

      Special select multiple input

          if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
            this.options.multiple = this.options.multiple || this.__id__;
            return this.bind('parsleyFieldMultiple');
    • ¶

      Else for radio / checkboxes, we need a name or data-parsley-multiple to properly bind it

          } else if (!this.options.multiple) {
            Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
            return this;
          }
    • ¶

      Remove special chars

          this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
    • ¶

      Add proper data-parsley-multiple to siblings if we have a valid multiple name

          if (name) {
            $('input[name="' + name + '"]').each((i, input) => {
              var type = Utils.getType(input);
              if ((type === 'radio' || type === 'checkbox'))
                input.setAttribute(this.options.namespace + 'multiple', this.options.multiple);
            });
          }
    • ¶

      Check here if we don’t already have a related multiple instance saved

          var $previouslyRelated = this._findRelated();
          for (var i = 0; i < $previouslyRelated.length; i++) {
            parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
            if ('undefined' !== typeof parsleyMultipleInstance) {
      
              if (!this.$element.data('FieldMultiple')) {
                parsleyMultipleInstance.addElement(this.$element);
              }
      
              break;
            }
          }
    • ¶

      Create a secret Field instance for every multiple field. It will be stored in data('FieldMultiple') And will be useful later to access classic Field stuff while being in a FieldMultiple instance

          this.bind('parsleyField', true);
      
          return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
        },
    • ¶

      Return proper Form, Field or FieldMultiple

        bind: function (type, doNotStore) {
          var parsleyInstance;
      
          switch (type) {
            case 'parsleyForm':
              parsleyInstance = $.extend(
                new Form(this.element, this.domOptions, this.options),
                new Base(),
                window.ParsleyExtend
              )._bindFields();
              break;
            case 'parsleyField':
              parsleyInstance = $.extend(
                new Field(this.element, this.domOptions, this.options, this.parent),
                new Base(),
                window.ParsleyExtend
              );
              break;
            case 'parsleyFieldMultiple':
              parsleyInstance = $.extend(
                new Field(this.element, this.domOptions, this.options, this.parent),
                new Multiple(),
                new Base(),
                window.ParsleyExtend
              )._init();
              break;
            default:
              throw new Error(type + 'is not a supported Parsley type');
          }
      
          if (this.options.multiple)
            Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
      
          if ('undefined' !== typeof doNotStore) {
            this.$element.data('FieldMultiple', parsleyInstance);
      
            return parsleyInstance;
          }
    • ¶

      Store the freshly bound instance in a DOM element for later access using jQuery data()

          this.$element.data('Parsley', parsleyInstance);
    • ¶

      Tell the world we have a new Form or Field instance!

          parsleyInstance._actualizeTriggers();
          parsleyInstance._trigger('init');
      
          return parsleyInstance;
        }
      };
      
      export default Factory;