You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iota.apache.org by no...@apache.org on 2016/05/11 11:34:27 UTC
[03/21] incubator-iota-site git commit: Website Upload
http://git-wip-us.apache.org/repos/asf/incubator-iota-site/blob/9b5251fe/js/mailform/jquery.rd-mailform.js
----------------------------------------------------------------------
diff --git a/js/mailform/jquery.rd-mailform.js b/js/mailform/jquery.rd-mailform.js
new file mode 100644
index 0000000..3040868
--- /dev/null
+++ b/js/mailform/jquery.rd-mailform.js
@@ -0,0 +1,1719 @@
+/**
+ * RD Mail Form
+ * @version 1.1.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ * @todo Time Picker
+ * @todo Date Picker
+ * @todo Checboxes
+ * @todo Radio Buttons
+ * @todo TextArea
+ * @todo InputMasks
+ * @todo Input File
+ */
+;
+(function ($, window, documen, undefined) {
+
+ var msg, e;
+
+ /**
+ * Template for some information status messages.
+ * @private
+ */
+ msg = {
+ 'MF000': 'Sent',
+ 'MF001': 'Recipients are not set!',
+ 'MF002': 'Form will not work locally!',
+ 'MF003': 'Please, define email field in your form!',
+ 'MF004': 'Please, define type of your form!',
+ 'MF254': 'Something went wrong with PHPMailer!',
+ 'MF255': 'Aw, snap! Something went wrong.'
+ };
+
+ /**
+ * Creates a form.
+ * @class The RD Mail Form.
+ * @public
+ * @param {HTMLElement|jQuery} element - The element to create the form for.
+ * @param {Object} [options] - The options
+ */
+ function RDMailForm(element, options) {
+
+ /**
+ * Current options set by the caller including defaults.
+ * @public
+ */
+ this.options = $.extend({}, RDMailForm.Defaults, options);
+
+ /**
+ * Plugin element.
+ * @public
+ */
+ this.$element = $(element);
+
+ /**
+ * References to the running plugins of this Mail Form.
+ * @protected
+ */
+ this._plugins = {};
+
+ /**
+ * All event handlers of Mail Form
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'mf.success mf.fail': $.proxy(this.update, this),
+ 'mf.process': $.proxy(this.process, this),
+ 'reset': $.proxy(this.reset, this)
+ };
+
+ /**
+ * Creates the instances of all attached plugins
+ * @protected
+ */
+ $.each(RDMailForm.Plugins, $.proxy(function (key, plugin) {
+ this._plugins[key[0].toLowerCase() + key.slice(1)]
+ = new plugin(this);
+ }, this));
+
+ this.initialize();
+ };
+
+ /**
+ * Default options for the Form.
+ * @public
+ */
+ RDMailForm.Defaults = {
+ baseClass: 'rd-mailform'
+ };
+
+ /**
+ * Contains all registered plugins.
+ * @public
+ */
+ RDMailForm.Plugins = {};
+
+ /**
+ * Initializes the Mail Form.
+ * @protected
+ */
+ RDMailForm.prototype.initialize = function () {
+ this.$element.trigger('mf.initialize');
+
+ this.$element
+ .addClass(this.options.baseClass)
+ .trigger('reset');
+
+ this.create();
+ this.watch();
+
+ this.$element.trigger('mf.initialized');
+ };
+
+ /**
+ * Creates additional DOM of Mail Form
+ * @protected
+ */
+ RDMailForm.prototype.create = function () {
+ var _self = this;
+
+ if (_self.$element.attr("data-type")) {
+ _self.$element
+ .prepend($("<input/>", {
+ "type": "hidden",
+ "name": "form-type",
+ "value": _self.$element.attr("data-type")
+ }));
+ }
+ };
+
+ /**
+ * Creates the events watchers of Mail Form
+ * @protected
+ */
+ RDMailForm.prototype.watch = function () {
+ var _self = this;
+ _self.$element
+ .ajaxForm({
+ beforeSubmit: function (e) {
+ _self.$element.trigger('mf.process');
+ },
+ error: function (result) {
+ _self.$element.trigger('mf.fail', {code: result, message: msg[result]});
+ },
+ success: function (result) {
+ console.log(result);
+
+ if (result == 'MF000') {
+ _self.$element.trigger('mf.success', {code: result, message: msg[result]});
+ } else {
+ result = result.length == 5 ? result : 'MF255';
+ _self.$element.trigger('mf.fail', {code: result, message: msg[result]});
+ }
+ }
+ })
+ .on(this._handlers);
+
+ };
+
+ /**
+ * Changes form status to process
+ * @protected
+ */
+ RDMailForm.prototype.process = function () {
+ this.$element.addClass('process');
+ };
+
+ /**
+ * Updates form status on sent
+ * @protected
+ */
+ RDMailForm.prototype.update = function (e, data) {
+ this.$element.removeClass('process');
+
+ if (data.code === 'MF000') {
+ this.$element.addClass('success');
+ } else {
+ this.$element.addClass('fail');
+ }
+
+ setTimeout($.proxy(function () {
+ this.$element.trigger('reset');
+ }, this), 3000);
+ };
+
+ /**
+ * Resets form status
+ * @protected
+ */
+ RDMailForm.prototype.reset = function () {
+ this.$element.removeClass('success');
+ this.$element.removeClass('fail');
+ this.$element.trigger('mf.reset');
+ };
+
+ /**
+ * The jQuery Plugin for the RD Mail Form
+ * @public
+ */
+ $.fn.rdMailForm = function (options) {
+ return this.each(function () {
+ if (!$(this).data('rdMailForm')) {
+ $(this).data('rdMailForm', new RDMailForm(this, options));
+ }
+ });
+ };
+
+ /**
+ * The constructor for the jQuery Plugin
+ * @public
+ */
+ $.fn.rdMailForm.Constructor = RDMailForm;
+})(window.jQuery, window, document);
+
+/**
+ * Validator Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+ /**
+ * Creates the validator plugin.
+ * @class The Validator Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Validator = $.fn.rdMailForm.Constructor.Plugins.Validator = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'mfValidator.validate': this.validate,
+ 'mfValidator.error': this.error,
+ 'mfValidator.valid': this.valid,
+ 'mfValidator.reset': this.reset,
+ 'mfValidator.click': $.noop()
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Validator.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Validator.Defaults = {
+ validator: {
+ 'applyTo': '[data-constraints]',
+ 'class': 'mfValidation',
+ 'constraints': {
+ '@LettersOnly': {
+ rule: '^([a-zA-Z\u0430-\u044f\u0410-\u042f\u0456\u0457\u0451\u0406\u0407\u0401\u0454\u0404\u0490\u0491\\s]{0,})$',
+ message: 'Please use letters only!'
+ },
+ '@NumbersOnly': {
+ rule: '^-?\\d*\\.?\\d*$',
+ message: 'Please use numbers only!'
+ },
+ '@NotEmpty': {
+ rule: '([^\\s])',
+ message: 'Field should not be empty!'
+ },
+ '@Email': {
+ rule: '^(([\\w-]+(?:\\.[\\w-]+)*)@((?:[\\w-]+\\.)*\\w[\\w-]{0,66})\\.([a-z]{2,6}(?:\\.[a-z]{2})?)){0,}$',
+ message: 'Enter valid e-mail address!'
+ },
+ '@Phone': {
+ rule: '^(\\+?\\d{0,3}\\s*\\(?\\d{1,3}\\)?\\s*\\d{3}\\s*\\d{4}){0,}$',
+ message: 'Enter valid phone number!'
+ },
+ '@Date': {
+ rule: function (o) {
+ if (!navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
+ return new RegExp('^($)|(((0[13578]|10|12)(-|\\/)((0[1-9])|([12])([0-9])|(3[01]?))(-|\\/)((19)([2-9])(\\d{1})|(20)([01])(\\d{1})|([8901])(\\d{1}))|(0?[2469]|11)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|\/)((19)([2-9])(\\d{1})|(20)([01])(\\d{1})|([8901])(\\d{1}))))$').test(o.val())
+ } else {
+ return true;
+ }
+ },
+ message: 'Use MM/DD/YYYY format!'
+ },
+ '@SelectRequired': {
+ rule: function (o) {
+ return o.find("option:selected").index() !== 0;
+ },
+ message: 'Please choose an option!'
+ }
+ }
+ }
+ };
+
+ /**
+ * Initializes validator for attached elements.
+ * @protected
+ */
+ Validator.prototype.initialize = function () {
+ this._core.$element.trigger('mfValidator.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfValidator.initialized');
+ };
+
+ /**
+ * Creates a necessary additional DOM for validating.
+ * @protected
+ */
+ Validator.prototype.create = function () {
+ var self = this;
+
+ this._core.$element
+ .find(this._core.options.validator.applyTo)
+ .each(function () {
+ $(this)
+ .parent()
+ .append($('<span/>', {
+ 'class': self._core.options.validator.class
+ }))
+ })
+ };
+
+ /**
+ * Creates all attached event handlers of validator.
+ * @protected
+ */
+ Validator.prototype.watch = function () {
+ var self = this;
+ this._core.$element
+ .find(this._core.options.validator.applyTo)
+ .on('keyup', function (e) {
+ if ($(this).is('input') || $(this).is('textarea')) {
+ $(this).parent().trigger('mfValidator.validate', {
+ options: self._core.options.validator
+ });
+ }
+ })
+ .on('change', function (e) {
+ $(this).parent().trigger('mfValidator.validate', {
+ options: self._core.options.validator
+ });
+ })
+ .parent()
+ .on(this._handlers)
+ .find('.' + this._core.options.validator.class)
+ .on('click', function (e) {
+ $(this)
+ .removeClass("error").removeClass("show").addClass("hide")
+ .parent()
+ .trigger('mfValidator.click')
+ .find(self._core.options.validator.applyTo)
+ .focus();
+ });
+
+ this._core.$element
+ .on('submit', $.proxy(function (e) {
+ this._core.$element.find(this._core.options.validator.applyTo).each(function () {
+ $(this).parent().trigger('mfValidator.validate', {
+ options: self._core.options.validator
+ });
+ });
+ if (this._core.$element.find('.error').length) {
+ e.preventDefault();
+ return false;
+ }
+ }, this))
+ .on('mf.reset', $.proxy(function (e) {
+ this._core.$element.find(this._core.options.validator.applyTo).each(function () {
+ $(this).parent().trigger('mfValidator.reset', {options: self._core.options.validator});
+ });
+ }, this));
+ };
+
+ /**
+ * Validates all attached elements.
+ * @protected
+ */
+ Validator.prototype.validate = function (e, data) {
+ var errors = [],
+ $this = $(this),
+ target = $this.find(data.options.applyTo),
+ ruleset = target.data('constraints').match(/\@\w+/g),
+ value = target.val();
+
+ for (var i in ruleset) {
+ if (data.options.constraints[ruleset[i]]) {
+ switch (typeof(data.options.constraints[ruleset[i]].rule)) {
+ case "function":
+ if (!data.options.constraints[ruleset[i]].rule(target)) {
+ errors.push(data.options.constraints[ruleset[i]].message);
+ }
+ break;
+ default :
+ if (!new RegExp(data.options.constraints[ruleset[i]].rule).test(value)) {
+ errors.push(data.options.constraints[ruleset[i]].message);
+ }
+ }
+ }
+ }
+
+ if (errors.length) {
+ $(this).trigger('mfValidator.error', {options: data.options, errors: errors});
+ } else {
+ $(this).trigger('mfValidator.valid', {options: data.options});
+ }
+ };
+
+ /**
+ * Notifies when element is not valid.
+ * @protected
+ */
+ Validator.prototype.error = function (e, data) {
+ $(this).find('.' + data.options.class).removeClass('valid').removeClass('hide').addClass('show').addClass('error').text(data.errors);
+ };
+
+ /**
+ * Notifies when element is valid.
+ * @protected
+ */
+ Validator.prototype.valid = function (e, data) {
+ var o = $(this).find('.' + data.options.class);
+ if (o.hasClass('error')) {
+ o.removeClass("error").addClass("hide");
+ }
+ o.find('.' + data.options.class).removeClass('show').addClass('valid').text(data.errors);
+ };
+
+ /**
+ * Resets the validation status
+ * @protected
+ */
+ Validator.prototype.reset = function (e, data) {
+ var o = $(this).find('.' + data.options.class);
+ if (o.hasClass('error')) {
+ o.removeClass("error").addClass("hide");
+ }
+ $(this).find('.' + data.options.class).removeClass('show');
+ };
+
+
+})(window.jQuery, window, document);
+
+/**
+ * Input Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+
+ /**
+ * Creates the input plugin.
+ * @class The Input Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Input = $.fn.rdMailForm.Constructor.Plugins.Input = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'mfInput.focus': this.focus,
+ 'mfInput.blur': this.blur,
+ 'mfInput.type': this.type,
+ 'mfInput.delete': this.delete,
+ 'mfInput.fill': this.fill,
+ 'mfInput.empty': this.empty,
+ 'mfInput.idle': this.idle,
+ 'mfInput.reset': this.reset,
+ 'click': function (e) {
+ e.preventDefault();
+ return false;
+ }
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Input.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Input.Defaults = {
+ input: {
+ 'applyto': 'input[type="text"], input[type="date"], textarea',
+ 'class': 'mfInput'
+ }
+ };
+
+ /**
+ * Initializes all inputs in the Mail Form.
+ * @protected
+ */
+ Input.prototype.initialize = function () {
+ this._core.$element.trigger('mfInput.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfInput.initialized');
+ };
+
+ /**
+ * Creates a necessary additional DOM of input.
+ * @protected
+ */
+ Input.prototype.create = function () {
+ this._core.$element
+ .find(this._core.options.input.applyto)
+ .parent()
+ .addClass(this._core.options.input.class);
+ };
+
+ /**
+ * Creates all attached event handlers of input.
+ * @protected
+ */
+ Input.prototype.watch = function () {
+ this._core.$element
+ .find(this._core.options.input.applyto)
+ .on('focus', function () {
+ $(this).parent().trigger('mfInput.focus');
+ })
+ .on('blur', function () {
+ $(this).parent().trigger('mfInput.blur');
+ if ($(this).val() === '') {
+ $(this).parent().trigger('mfInput.void');
+ }
+ })
+ .on('keydown', this, function (e) {
+ if (e.data.ignore(e)) {
+ return;
+ }
+ if (e.keyCode === 8 || e.keyCode === 46) {
+ $(this).parent().trigger('mfInput.delete');
+ }
+ if (e.keyCode === 32 || e.keyCode > 46) {
+ $(this).parent().trigger('mfInput.type');
+ }
+ })
+ .on('keyup', this, function (e) {
+ var _this = $(this);
+ if (e.data.ignore(e)) {
+ return;
+ }
+ if (_this.val() === '') {
+ _this.parent().trigger('mfInput.empty');
+ }
+ if (e.keyCode === 8 || e.keyCode === 46) {
+ if (self.timer) {
+ clearTimeout(self.timer);
+ }
+ self.timer = setTimeout(function () {
+ _this.parent().trigger('mfInput.idle');
+ }, 1000);
+ }
+ else {
+ _this.parent().trigger('mfInput.fill');
+ _this.parent().trigger('mfInput.type');
+ if (self.timer) {
+ clearTimeout(self.timer);
+ }
+ self.timer = setTimeout(function () {
+ _this.parent().trigger('mfInput.idle');
+ }, 1000);
+ }
+ })
+ .on('keypress', this, function (e) {
+ if (e.data.ignore(e.keyCode)) {
+ return;
+ }
+ var _this = $(this);
+ if (self.timer) {
+ clearTimeout(self.timer);
+ }
+ self.timer = setTimeout(function () {
+ _this.parent().trigger('mfInput.idle');
+ }, 1000);
+ })
+ .parent()
+ .on(this._handlers);
+
+ this._core.$element.on('mf.reset', this, function (e) {
+ $(this).find('.' + e.data._core.options.input.class).each(function () {
+ $(this).trigger('mfInput.reset');
+ });
+ })
+ };
+
+ /**
+ * Notify when input is in focus.
+ * @protected
+ */
+ Input.prototype.focus = function () {
+ $(this).addClass('focused');
+ };
+
+ /**
+ * Notify when input was blured.
+ * @protected
+ */
+ Input.prototype.blur = function () {
+ $(this).removeClass('focused');
+ };
+
+ /**
+ * Notify when writing in input.
+ * @protected
+ */
+ Input.prototype.type = function () {
+ $(this).removeClass('deleting');
+ $(this).addClass('typing');
+ };
+
+ /**
+ * Notify when deleting in input.
+ * @protected
+ */
+ Input.prototype.delete = function () {
+ $(this).removeClass('typing');
+ $(this).addClass('deleting');
+ };
+
+ /**
+ * Notify when input is not empty.
+ * @protected
+ */
+ Input.prototype.fill = function () {
+ $(this).addClass('filled');
+ };
+
+ /**
+ * Notify when input is empty.
+ * @protected
+ */
+ Input.prototype.empty = function () {
+ $(this).removeClass('filled');
+ };
+
+ /**
+ * Notify when input is idling.
+ * @protected
+ */
+ Input.prototype.idle = function () {
+ $(this).removeClass('typing');
+ $(this).removeClass('deleting');
+ };
+
+ /**
+ * Resets the input status.
+ * @protected
+ */
+ Input.prototype.reset = function () {
+ $(this).removeClass('focused');
+ $(this).removeClass('deleting');
+ $(this).removeClass('filled');
+ $(this).removeClass('typing');
+ $(this).removeClass('error');
+ };
+
+ /**
+ * Checks the keycode for deprecated value.
+ * @protected
+ */
+ Input.prototype.ignore = function (e) {
+ if (e.keyCode === 144 || e.keyCode === 20 || e.keyCode === 17 || e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39
+ || e.keyCode === 40 || e.keyCode === 112 || e.keyCode === 113 || e.keyCode === 114 || e.keyCode === 115 || e.keyCode === 116
+ || e.keyCode === 117 || e.keyCode === 118 || e.keyCode === 119 || e.keyCode === 120 || e.keyCode === 121 || e.keyCode === 122
+ || e.keyCode === 123 || e.keyCode === 9 || e.ctrlKey) {
+ return true;
+ }
+ return false;
+ }
+
+})(window.jQuery, window, document);
+
+/**
+ * Select Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+
+ /**
+ * Creates the select plugin.
+ * @class The Select Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Select = $.fn.rdMailForm.Constructor.Plugins.Select = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ /**
+ * Element event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ "mfSelect.close": this.close,
+ "mfSelect.open": this.open,
+ "mfSelect.select": this.select,
+ "click": function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Select.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Select.Defaults = {
+ select: {
+ 'applyTo': 'select',
+ 'class': 'mfSelect'
+ }
+ };
+
+ /**
+ * Initializes all selects in the Mail Form.
+ * @protected
+ */
+ Select.prototype.initialize = function () {
+ this._core.$element.trigger('mfSelect.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfSelect.initialized');
+ };
+
+ /**
+ * Creates a necessary pseudo DOM of select.
+ * @protected
+ */
+ Select.prototype.create = function () {
+ this._core.$element
+ .find(this._core.options.select.applyTo)
+ .each(function () {
+ var $this = $(this);
+
+ $this
+ .css({
+ "position": "absolute",
+ "left": "50%",
+ "width": "0",
+ "height": "0",
+ "overflow": "hidden",
+ "opacity": "0"
+ })
+ .parent()
+ .append($('<div/>', {
+ 'class': 'value',
+ 'text': $this.find('option:selected').text()
+ }))
+ .append($('<ul/>', {'class': 'dropdown'}))
+ .end()
+ .find('option').each(function (i) {
+ if (i == 0) {
+ return;
+ }
+
+ var o = $(this);
+ o.parent().parent().find('.dropdown')
+ .append($('<li/>', {
+ 'class': 'option',
+ 'text': o.text()
+ }).addClass(o.is(':selected') ? 'selected' : ''));
+ })
+
+ })
+ .parent()
+ .addClass(this._core.options.select.class);
+ };
+
+ /**
+ * Creates all attached event handlers of select.
+ * @protected
+ */
+ Select.prototype.watch = function () {
+ var self = this;
+ this._core.$element
+ .find(self._core.options.select.applyTo)
+ .on('focus', this.focus)
+ .on('blur', function (e) {
+ $(this).parent()
+ .trigger('mfSelect.close')
+ .removeClass('focus')
+ })
+ .on('keydown', function (e) {
+ if (e.keyCode == 38) {
+ $(this)
+ .val($(this).find('option').eq($(this).find('option:selected').index() > 0 ? $(this).find('option:selected').index() - 1 : 0).text())
+ .trigger('change');
+ }
+
+ if (e.keyCode == 40) {
+ $(this)
+ .val($(this).find('option').eq($(this).find('option:selected').index() < $(this).find('option').length - 1 ? $(this).find('option:selected').index() + 1 : $(this).find('option').length - 1).text())
+ .trigger('change');
+ }
+
+ if (e.keyCode == 13) {
+ if ($(this).parent().hasClass('show')) {
+ $(this).parent().trigger('mfSelect.close');
+ } else {
+ $(this).parent().trigger('mfSelect.open');
+ }
+ }
+
+ if (e.keyCode == 32 || e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40 || e.keyCode == 13) {
+ e.preventDefault();
+ }
+ })
+ .on('change', function (e) {
+ $(this).parent()
+ .trigger('mfSelect.open')
+ .find('.value').text($(this).val());
+
+ var i = $(this).find('option:selected').index(),
+ $option = $(this).parent().find('.option').removeClass('selected');
+
+ if (i > 0) {
+ $option.eq(i - 1).addClass('selected');
+ }
+ })
+ .parent()
+ .on(this._handlers)
+ .find('.value')
+ .on('click', function (e) {
+ var $value = $(this),
+ $select = $value.parent().find('select'),
+ option = $select.find('option').eq(0).text();
+
+ $value.text(option);
+
+ $select
+ .trigger('focus')
+ .off('focus', self.focus);
+
+ if (!$(this).parent().hasClass('show')) {
+ $select.on('focus', self.focus);
+ var value = $(this).parent().find('.option.selected');
+ if (value.length) {
+ $value.text(value.text());
+ }
+ }
+ })
+ .parent()
+ .find('.option')
+ .on('click', function () {
+ $(this).parent().find('.option').removeClass('selected');
+ $(this).addClass('selected');
+ $(this).parent().parent()
+ .find('select')
+ .focus()
+ .on('focus', self.focus);
+ $(this).parent().parent()
+ .trigger('mfSelect.select', {
+ options: self._core.options.select,
+ value: $(this).text()
+ })
+
+ })
+ .parents('body')
+ .on('click', function (e) {
+ var o = self._core.$element.find('.' + self._core.options.select.class);
+
+ if (o.length) {
+ if (!o.is(e.target) && o.has(e.target).length === 0) {
+ o.find('select')
+ .each(function () {
+ var value = $(this).parent().find('.option.selected');
+ if (value.length) {
+ $(this).parent().find('.value').text(value.text());
+ }
+ })
+ .on('focus', self.focus);
+ }
+ }
+ });
+
+ this._core.$element
+ .on('mf.reset', function () {
+ $(this)
+ .find(self._core.options.select.applyTo).each(function () {
+ $(this).parent()
+ .find('.value').text($(this).prop('selectedIndex', 0).val());
+ $(this).parent().find('.option').removeClass('selected');
+ });
+ });
+ };
+
+ Select.prototype.focus = function () {
+ $(this).parent().trigger('mfSelect.open').addClass('focus');
+ };
+
+ Select.prototype.close = function () {
+ if (!navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
+ if ($(this).hasClass("show")) {
+ $(this).removeClass("show");
+ }
+ }
+ };
+
+ Select.prototype.open = function () {
+ if (!navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
+ if (!$(this).hasClass("show")) {
+ $(this).addClass("show");
+ }
+ }
+ };
+
+ Select.prototype.select = function (e, data) {
+ $(this)
+ .find(data.options.applyTo).val(data.value)
+ .trigger('change');
+
+ $(this)
+ .trigger('mfSelect.close');
+
+ };
+
+
+})(window.jQuery, window, document);
+
+/**
+ * DatePicker Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+ /**
+ * Creates Icon plugin.
+ * @class The Icon Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var DatePicker = $.fn.rdMailForm.Constructor.Plugins.DatePicker = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ this._handlers = {
+ 'mfDatePicker.close': this.close,
+ 'mfDatePicker.open': this.open,
+ 'mfDatePicker.next': this.next,
+ 'mfDatePicker.prev': this.prev,
+ 'mfDatePicker.update': this.update,
+ 'mfDatePicker.refresh': this.refresh,
+ 'mfDatePicker.pick': this.pick
+ };
+
+ // set default options
+ this._core.options = $.extend({}, DatePicker.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ DatePicker.Defaults = {
+ "datepicker": {
+ "applyTo": 'input[type="date"]',
+ "class": 'mfDatePicker',
+ "days": ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
+ "months": ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ "format": 'MM-DD-YYYY',
+ "prevMonth": '',
+ "nextMonth": ''
+ }
+ };
+
+ /**
+ * Initializes the Datepicker plugin.
+ * @protected
+ */
+ DatePicker.prototype.initialize = function () {
+ this._core.$element.trigger('mfDatePicker.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfDatePicker.initialized');
+ };
+
+ /**
+ * Creates a necessary DOM for datepicker plugin.
+ * @protected
+ */
+ DatePicker.prototype.create = function () {
+ var self = this;
+ self._core.$element
+ .find(self._core.options.datepicker.applyTo)
+ .each(function () {
+ $(this)
+ .attr({
+ 'type': !navigator.userAgent.match(/(iPod|iPhone|iPad)/) ? 'text' : 'date',
+ 'data-type': 'date'
+ })
+ .after($('<div/>', {
+ 'class': self._core.options.datepicker.class
+ })
+ .data('date', new Date())
+ );
+ })
+ .parent()
+ .find('.' + self._core.options.datepicker.class)
+ .each(function () {
+ $.proxy(self.update, this, {}, self._core.options.datepicker).call();
+ $.proxy(self.refresh, this, {}, self._core.options.datepicker).call();
+ });
+ };
+
+ /**
+ * Creates all attached event handlers of datepicker plugin.
+ * @protected
+ */
+ DatePicker.prototype.watch = function () {
+ var self = this;
+
+ self._core.$element
+ .find('.' + self._core.options.datepicker.class)
+ .on('click', '.' + self._core.options.datepicker.class + '_next', function () {
+ var $this = $(this).parents('.' + self._core.options.datepicker.class);
+
+ $this.trigger('mfDatePicker.next');
+ $this.trigger('mfDatePicker.update', self._core.options.datepicker);
+ $this.trigger('mfDatePicker.refresh', self._core.options.datepicker);
+ })
+ .on('click', '.' + self._core.options.datepicker.class + '_prev', function () {
+ var $this = $(this).parents('.' + self._core.options.datepicker.class);
+
+ $this.trigger('mfDatePicker.prev');
+ $this.trigger('mfDatePicker.update', self._core.options.datepicker);
+ $this.trigger('mfDatePicker.refresh', self._core.options.datepicker);
+ })
+ .on('click', '.dp-day', function () {
+ var $this = $(this).parents('.' + self._core.options.datepicker.class);
+
+ $this.trigger('mfDatePicker.pick', {opt: self._core.options.datepicker, day: $(this)});
+ $this.parent()
+ .find('input')
+ .on('blur', self.blur)
+ .trigger('blur')
+ .trigger('keyup');
+
+ })
+ .on('click', function () {
+
+ })
+ .on(this._handlers)
+ .parent()
+ .on('click', function (e) {
+ e.preventDefault();
+ return false;
+ })
+ .find('input')
+ .on('focus', function () {
+ $(this).parent().find('.' + self._core.options.datepicker.class)
+ .trigger('mfDatePicker.open');
+ })
+ .on('blur', this.blur)
+ .on('keydown', function (e) {
+ if (e.keyCode == 9 || (e.shiftKey && e.keyCode == 9)) {
+ $(this)
+ .on('blur', self.blur);
+ }
+ })
+ .parents('body')
+ .on('mousedown', function (e) {
+ var o = self._core.$element.find('.' + self._core.options.datepicker.class).parent();
+
+ if (o.length) {
+ if (!o.is(e.target) && o.has(e.target).length === 0) {
+ o.find('input')
+ .on('blur', self.blur)
+ .trigger('blur');
+ } else {
+ o.find('input')
+ .off('blur', self.blur)
+ }
+ }
+ });
+
+ self._core.$element
+ .on('mf.reset', function () {
+ $(this)
+ .find('.' + self._core.options.datepicker.class).each(function () {
+ $(this).trigger("mfDatePicker.close")
+ });
+ });
+
+
+ };
+
+ /**
+ * Blur the datepickers input
+ * @protected
+ */
+ DatePicker.prototype.blur = function () {
+ $(this).parent().find('.mfDatePicker')
+ .trigger('mfDatePicker.close');
+ };
+
+
+ /**
+ * Closes the datepicker
+ * @protected
+ */
+ DatePicker.prototype.close = function () {
+ if (!navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
+ if ($(this).hasClass("open")) {
+ $(this).removeClass("open");
+ }
+ }
+ };
+
+ /**
+ * Opens the datepicker
+ * @protected
+ */
+ DatePicker.prototype.open = function () {
+ if (!navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
+ if (!$(this).hasClass("open")) {
+ $(this).addClass("open");
+ }
+ }
+ };
+
+ /**
+ * Goto next month of picker
+ * @protected
+ */
+ DatePicker.prototype.next = function (e) {
+ var $this = $(this),
+ date = $this.data('date');
+
+ if (date.getMonth() == 11) {
+ date = new Date(date.getFullYear() + 1, 0, 1);
+ } else {
+ date = new Date(date.getFullYear(), date.getMonth() + 1, 1);
+ }
+
+ $this.data('date', date);
+ };
+
+ /**
+ * Goto previous month of picker
+ * @protected
+ */
+ DatePicker.prototype.prev = function (e) {
+ var $this = $(this),
+ date = $this.data('date');
+
+ if (date.getMonth() == 0) {
+ date = new Date(date.getFullYear() - 1, 11, 1);
+ } else {
+ date = new Date(date.getFullYear(), date.getMonth() - 1, 1);
+ }
+
+ $this.data('date', date);
+ };
+
+ /**
+ * Goto target date
+ * @protected
+ */
+ DatePicker.prototype.pick = function (e, o) {
+ var $this = $(this);
+
+ $this.data('pickedDate', o.day.addClass("dp-selected").data('date'));
+ $this
+ .find('.dp-day')
+ .not(o.day)
+ .removeClass('dp-selected');
+ $this
+ .parent()
+ .find('input')
+ .val(
+ ($this.data('pickedDate').getMonth() + 1 < 10 ? "0" + ($this.data('pickedDate').getMonth() + 1) : $this.data('pickedDate').getMonth() + 1 ) + '/' +
+ ($this.data('pickedDate').getDate() < 10 ? "0" + ($this.data('pickedDate').getDate()) : $this.data('pickedDate').getDate()) + '/' +
+ $this.data('pickedDate').getFullYear()
+ )
+
+ };
+
+ /**
+ * Refreshes the DOM of picker according to current picked date.
+ * @protected
+ */
+ DatePicker.prototype.update = function (e, opt) {
+ var $this = $(this),
+ $panel = $('<div/>', {"class": opt.class + '_panel'});
+
+ $panel.append($('<a/>', {
+ 'class': opt.class + '_prev',
+ 'text': opt.prevMonth
+ }));
+ $panel.append($('<a/>', {
+ 'class': opt.class + '_next',
+ 'text': opt.nextMonth
+ }));
+ $panel.append($('<div/>', {
+ 'class': opt.class + '_title',
+ 'text': opt.months[$this.data("date").getMonth()] + " " + $this.data("date").getFullYear()
+ }));
+
+
+ var $target = $this.find('.' + opt.class + '_panel');
+ if ($target.length) {
+ $target.replaceWith($panel);
+ } else {
+ $panel.appendTo($this);
+ }
+ };
+
+ /**
+ * Refreshes the DOM of picker according to current picked date.
+ * @protected
+ */
+ DatePicker.prototype.refresh = function (e, opt) {
+ var $this = $(this),
+ $calendar = $('<table/>');
+
+ var $week = $('<tr/>');
+ for (var i = 0; i < opt.days.length; i++) {
+ $week.append($('<th/>', {
+ 'class': 'dp-weekday',
+ 'text': opt.days[i]
+ }));
+ }
+ $calendar.append($week);
+
+ var date = $this.data("date"),
+ pickedDate = $this.data("pickedDate"),
+ monthLength = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate(),
+ prevMonthLength = new Date(date.getFullYear(), date.getMonth(), 0).getDate(),
+ firstDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay(),
+ counter = 1;
+
+ for (var i = 0; i < 7; i++) {
+ $week = $('<tr/>');
+ for (var j = 0; j < 7; j++) {
+ var day = 7 * i + j + 1,
+ currentDate,
+ currentDay = $('<td/>', {'class': 'dp-day'}),
+ today = new Date();
+
+ today.setHours(0);
+ today.setMinutes(0);
+ today.setSeconds(0);
+ today.setMilliseconds(0);
+
+ // If Month had ended and new week started
+ if (j == 0 && day > monthLength + firstDay) {
+ break;
+ }
+
+ // If the day belongs to previous month
+ if (day - firstDay < 1) {
+ currentDay.text(prevMonthLength + (day - firstDay)).addClass("dp-offset");
+ currentDate = new Date(date.getFullYear(), date.getMonth() - 1, prevMonthLength + (day - firstDay));
+ }
+ // If the day belongs to current month
+ else if (day <= monthLength + firstDay) {
+ currentDay.text(day - firstDay);
+ currentDate = new Date(date.getFullYear(), date.getMonth(), day - firstDay);
+ }
+ // If the day belongs to next month
+ else {
+ currentDay.text(counter).addClass("dp-offset");
+ currentDate = new Date(date.getFullYear(), date.getMonth() + 1, counter++);
+ }
+
+ // If current day is today
+ if (currentDate.valueOf() == today.valueOf()) {
+ currentDay.addClass('dp-today');
+ }
+
+ // If current day was selected
+ if (pickedDate) {
+ if (currentDate.valueOf() == pickedDate.valueOf()) {
+ currentDay.addClass('dp-selected');
+ }
+ }
+
+ $week.append(currentDay.data('date', currentDate));
+ }
+
+ if ($week.html() != '') {
+ $calendar.append($week);
+ }
+ }
+
+ var $target = $this.find('table');
+ if ($target.length) {
+ $target.replaceWith($calendar);
+ } else {
+ $calendar.appendTo($this);
+ }
+ };
+
+
+})(window.jQuery, window, document);
+
+/**
+ * Icon Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+ /**
+ * Creates Icon plugin.
+ * @class The Icon Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Icon = $.fn.rdMailForm.Constructor.Plugins.Icon = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ // set default options
+ this._core.options = $.extend({}, Icon.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Element event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ "mfIcon.change": this.change
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Icon.Defaults = {
+ "icon": {
+ "applyTo": "[data-add-icon]",
+ "class": "mfIcon",
+ "states": {
+ '.mfInput': {
+ 'mfIcon.default': ['mfInput.blur', 'mfInput.idle', 'mfInput.reset'],
+ 'mfIcon.state-1': ['mfInput.type'],
+ 'mfIcon.state-2': ['mfInput.delete']
+ }
+ }
+ }
+ };
+
+ /**
+ * Initializes the Icon plugin.
+ * @protected
+ */
+ Icon.prototype.initialize = function () {
+ this._core.$element.trigger('mfIcon.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfIcon.initialized');
+ };
+
+ /**
+ * Creates a necessary DOM for Icon plugin.
+ * @protected
+ */
+ Icon.prototype.create = function () {
+ var self = this;
+ self._core.$element
+ .find(self._core.options.icon.applyTo)
+ .each(function () {
+ var o = $(this);
+ o.append(
+ $('<span/>', {
+ 'class': self._core.options.icon.class
+ }).append($("<span/>"))
+ );
+ });
+ };
+
+ /**
+ * Creates all attached event handlers of Icon plugin.
+ * @protected
+ */
+ Icon.prototype.watch = function () {
+ var self = this;
+
+ self._core.$element
+ .find('.' + self._core.options.icon.class)
+ .on(self._handlers);
+
+ for (var component in self._core.options.icon.states) {
+ var $target = self._core.$element.find(component);
+
+ for (var state in self._core.options.icon.states[component]) {
+ for (var event in self._core.options.icon.states[component][state]) {
+ $target.on(self._core.options.icon.states[component][state][event], {state: state}, function (e) {
+ $(this).find('.' + self._core.options.icon.class)
+ .attr('class', e.data.state.replace('.', ' '));
+ })
+ }
+ }
+ }
+ };
+})(window.jQuery, window, document);
+
+/**
+ * PlaceHolder Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+ /**
+ * Creates Placeholder plugin.
+ * @class The Placeholder Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Placeholder = $.fn.rdMailForm.Constructor.Plugins.Placeholder = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ // set default options
+ this._core.options = $.extend({}, Placeholder.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Element event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ "mfIcon.change": this.change,
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Placeholder.Defaults = {
+ "placeholder": {
+ "applyTo": "[data-add-placeholder]",
+ "class": "mfPlaceHolder",
+ "states": {
+ '.mfInput': {
+ 'mfPlaceHolder.default': ['mfInput.void', 'mfInput.reset'],
+ 'mfPlaceHolder.state-1': ['mfInput.fill', 'mfInput.focus']
+ }
+ }
+ }
+ };
+
+ /**
+ * Initializes the Placeholder plugin.
+ * @protected
+ */
+ Placeholder.prototype.initialize = function () {
+ this._core.$element.trigger('mfPlaceHolder.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfPlaceHolder.initialized');
+ };
+
+ /**
+ * Creates a necessary DOM for Placeholder plugin.
+ * @protected
+ */
+ Placeholder.prototype.create = function () {
+ var self = this;
+ self._core.$element
+ .find(self._core.options.placeholder.applyTo)
+ .each(function () {
+ var o = $(this), inp, lab;
+
+ if (o.find('[placeholder]').length) {
+ o.append(
+ $('<span/>', {
+ 'class': self._core.options.placeholder.class,
+ 'text': o.find('[placeholder]').attr('placeholder') ? o.find('[placeholder]').attr('placeholder') : o.find('[data-placeholder]').attr('data-placeholder')
+ }))
+ .find('[placeholder]').removeAttr('placeholder').removeAttr('data-placeholder');
+ }
+ else if ((inp = o.find('input, textarea')).length) {
+ if (inp.attr("id")){
+ if ((lab = o.find('label[for="' + inp.attr("id") + '"]')).length){
+ lab.addClass(self._core.options.placeholder.class)
+ }
+ }
+ }
+ });
+ };
+
+ /**
+ * Creates all attached event handlers of Placeholder plugin.
+ * @protected
+ */
+ Placeholder.prototype.watch = function () {
+ var self = this;
+
+ self._core.$element
+ .find('.' + self._core.options.placeholder.class)
+ .on('click', function (e) {
+ $(this).parent().find('input, textarea').trigger('focus');
+ })
+ .on(self._handlers);
+
+ for (var component in self._core.options.icon.states) {
+ var $target = self._core.$element.find(component);
+
+ for (var state in self._core.options.placeholder.states[component]) {
+ for (var event in self._core.options.placeholder.states[component][state]) {
+ $target.on(self._core.options.placeholder.states[component][state][event], {state: state}, function (e) {
+ $(this).find('.' + self._core.options.placeholder.class)
+ .attr('class', e.data.state.replace('.', ' '));
+ })
+ }
+ }
+ }
+ };
+})(window.jQuery, window, document);
+
+/**
+ * Progress Plugin
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (Stmechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document, undefined) {
+
+ /**
+ * Creates Progress plugin.
+ * @class The Progress Plugin
+ * @param {RDMailForm} form - The Mail Form
+ */
+ var Progress = $.fn.rdMailForm.Constructor.Plugins.Progress = function (form) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {RDMailForm}
+ */
+ this._core = form;
+
+ // set default options
+ this._core.options = $.extend({}, Progress.Defaults, this._core.options);
+
+ this.initialize();
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Progress.Defaults = {
+ "progress": {
+ "applyTo": ".mfInfo",
+ "class": "mfProgress"
+ }
+ };
+
+ /**
+ * Initializes the Progress plugin.
+ * @protected
+ */
+ Progress.prototype.initialize = function () {
+ this._core.$element.trigger('mfProgress.initialize');
+
+ this.create();
+ this.watch();
+
+ this._core.$element.trigger('mfProgress.initialized');
+ };
+
+ /**
+ * Creates a necessary DOM for Progress plugin.
+ * @protected
+ */
+ Progress.prototype.create = function () {
+ var self = this;
+ self._core.$element
+ .append($("<div/>", {
+ "class": self._core.options.progress.applyTo.replace(/^\./i, "")
+ })
+ .each(function () {
+ var button = $(this);
+ button
+ .addClass(self._core.options.progress.class)
+ .wrapInner($('<span/>', {'class': 'cnt'}))
+ .append($('<span/>', {'class': 'loader'}))
+ .append($('<span/>', {'class': 'msg'}))
+ }));
+ };
+
+ /**
+ * Creates all attached event handlers of Progress plugin.
+ * @protected
+ */
+ Progress.prototype.watch = function () {
+ var self = this;
+
+ self._core.$element
+ .on('mf.process', function () {
+ $(this).find('.' + self._core.options.progress.class).removeClass('hide').addClass('sending').find('.msg').text('Loading...');
+ })
+ .on('mf.fail', function (e, data) {
+ $(this).find('.' + self._core.options.progress.class)
+ .removeClass('sending')
+ .addClass('fail')
+ .find('.msg')
+ .text(data.message);
+ setTimeout($.proxy(function () {
+ $(this).find('.' + self._core.options.progress.class).removeClass('fail').addClass('hide').find('.msg');
+ }, this), 3000);
+ })
+ .on('mf.success', function (e, data) {
+ $(this).find('.' + self._core.options.progress.class)
+ .removeClass('sending')
+ .addClass('success')
+ .find('.msg')
+ .text(data.message);
+
+ setTimeout($.proxy(function () {
+ $(this).find('.' + self._core.options.progress.class).removeClass('success').addClass('hide').find('.msg');
+ }, this), 1500);
+ })
+ .on('mf.reset', function (e, data) {
+ $(this).find('.' + self._core.options.progress.class).removeClass('sending').removeClass('fail').removeClass('success').find('.msg');
+ });
+ };
+})(window.jQuery, window, document);
+
+
+/**
+ * Auto Initializer
+ * @version 1.0.0
+ * @author Evgeniy Gusarov (StMechanus | Diversant)
+ * @license The MIT License (MIT)
+ */
+;
+(function ($, window, document) {
+ $(document).ready(function () {
+ var o = $('.mailform');
+
+ if (o.length) {
+ o.rdMailForm();
+ }
+ });
+})(window.jQuery, window, document);
+
+
+
http://git-wip-us.apache.org/repos/asf/incubator-iota-site/blob/9b5251fe/js/mailform/jquery.rd-mailform.min.js
----------------------------------------------------------------------
diff --git a/js/mailform/jquery.rd-mailform.min.js b/js/mailform/jquery.rd-mailform.min.js
new file mode 100644
index 0000000..a93ac57
--- /dev/null
+++ b/js/mailform/jquery.rd-mailform.min.js
@@ -0,0 +1,508 @@
+/**
+ * @module RD Mail Form
+ * @version 1.1.0
+ * @author Evgeniy Gusarov
+ * @see https://ua.linkedin.com/pub/evgeniy-gusarov/8a/a40/54a
+ */
+!function (e) {
+ function t(o, s, n) {
+ i = e.extend(!0, {}, i, n), this.options = e.extend(!0, {}, t.Defaults, s), this.$element = e(o), this._plugins = {}, this._handlers = {
+ "mf.success mf.fail": e.proxy(this.update, this),
+ "mf.process": e.proxy(this.process, this),
+ reset: e.proxy(this.reset, this)
+ }, e.each(t.Plugins, e.proxy(function (e, t) {
+ this._plugins[e[0].toLowerCase() + e.slice(1)] = new t(this)
+ }, this)), this.initialize()
+ }
+
+ var i;
+ i = {
+ MF000: "Sent",
+ MF001: "Recipients are not set!",
+ MF002: "Form will not work locally!",
+ MF003: "Please, define email field in your form!",
+ MF004: "Please, define type of your form!",
+ MF254: "Something went wrong with PHPMailer!",
+ MF255: "Aw, snap! Something went wrong."
+ }, t.Defaults = {baseClass: "rd-mailform"}, t.Plugins = {}, t.prototype.initialize = function () {
+ this.$element.trigger("mf.initialize"), this.$element.addClass(this.options.baseClass).trigger("reset"), this.create(), this.watch(), this.$element.trigger("mf.initialized")
+ }, t.prototype.create = function () {
+ }, t.prototype.watch = function () {
+ var e = this;
+ e.$element.ajaxForm({
+ beforeSubmit: function () {
+ e.$element.trigger("mf.process")
+ }, error: function (t) {
+ e.$element.trigger("mf.fail", {code: t, message: i[t]})
+ }, success: function (t) {
+ console.log(t), "MF000" == t ? e.$element.trigger("mf.success", {
+ code: t,
+ message: i[t]
+ }) : (t = 5 == t.length ? t : "MF255", e.$element.trigger("mf.fail", {code: t, message: i[t]}))
+ }
+ }).on(this._handlers)
+ }, t.prototype.process = function () {
+ this.$element.addClass("process")
+ }, t.prototype.update = function (t, i) {
+ this.$element.removeClass("process"), this.$element.addClass("MF000" === i.code ? "success" : "fail"), setTimeout(e.proxy(function () {
+ this.$element.trigger("reset")
+ }, this), 3e3)
+ }, t.prototype.reset = function () {
+ this.$element.removeClass("success"), this.$element.removeClass("fail"), this.$element.trigger("mf.reset")
+ }, e.fn.rdMailForm = function (i, o) {
+ return this.each(function () {
+ e(this).data("rdMailForm") || e(this).data("rdMailForm", new t(this, i, o))
+ })
+ }, e.fn.rdMailForm.Constructor = t
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Validator = function (i) {
+ this._core = i, this._handlers = {
+ "mfValidator.validate": this.validate,
+ "mfValidator.error": this.error,
+ "mfValidator.valid": this.valid,
+ "mfValidator.reset": this.reset,
+ "mfValidator.click": e.noop()
+ }, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ t.Defaults = {
+ validator: {
+ applyTo: "[data-constraints]",
+ "class": "mfValidation",
+ constraints: {
+ "@LettersOnly": {
+ rule: "^([a-zA-Z\u0430-\u044f\u0410-\u042f\u0456\u0457\u0451\u0406\u0407\u0401\u0454\u0404\u0490\u0491\\s]{0,})$",
+ message: "Please use letters only!"
+ },
+ "@NumbersOnly": {rule: "^-?\\d*\\.?\\d*$", message: "Please use numbers only!"},
+ "@NotEmpty": {rule: "([^\\s])", message: "Field should not be empty!"},
+ "@Email": {
+ rule: "^(([\\w-]+(?:\\.[\\w-]+)*)@((?:[\\w-]+\\.)*\\w[\\w-]{0,66})\\.([a-z]{2,6}(?:\\.[a-z]{2})?)){0,}$",
+ message: "Enter valid e-mail address!"
+ },
+ "@Phone": {
+ rule: "^(\\+?\\d{0,3}\\s*\\(?\\d{1,3}\\)?\\s*\\d{3}\\s*\\d{4}){0,}$",
+ message: "Enter valid phone number!"
+ },
+ "@Date": {
+ rule: function (e) {
+ return navigator.userAgent.match(/(iPod|iPhone|iPad)/) ? !0 : new RegExp("^($)|(((0[13578]|10|12)(-|\\/)((0[1-9])|([12])([0-9])|(3[01]?))(-|\\/)((19)([2-9])(\\d{1})|(20)([01])(\\d{1})|([8901])(\\d{1}))|(0?[2469]|11)(-|/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|/)((19)([2-9])(\\d{1})|(20)([01])(\\d{1})|([8901])(\\d{1}))))$").test(e.val())
+ }, message: "Use MM/DD/YYYY format!"
+ },
+ "@SelectRequired": {
+ rule: function (e) {
+ return 0 !== e.find("option:selected").index()
+ }, message: "Please choose an option!"
+ }
+ }
+ }
+ }, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfValidator.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfValidator.initialized")
+ }, t.prototype.create = function () {
+ var t = this;
+ this._core.$element.find(this._core.options.validator.applyTo).each(function () {
+ e(this).parent().append(e("<span/>", {"class": t._core.options.validator["class"]}))
+ })
+ }, t.prototype.watch = function () {
+ var t = this;
+ this._core.$element.find(this._core.options.validator.applyTo).on("keyup", function () {
+ (e(this).is("input") || e(this).is("textarea")) && e(this).parent().find(".mfValidation").hasClass("error") && e(this).parent().trigger("mfValidator.validate", {options: t._core.options.validator})
+ }).on("blur", function () {
+ (e(this).is("input") || e(this).is("textarea")) && e(this).parent().trigger("mfValidator.validate", {options: t._core.options.validator})
+ }).on("change", function () {
+ e(this).is("select") && e(this).parent().trigger("mfValidator.validate", {options: t._core.options.validator})
+ }).parent().on(this._handlers).find("." + this._core.options.validator["class"]).on("click", function () {
+ e(this).removeClass("error").removeClass("show").addClass("hide").parent().trigger("mfValidator.click").find(t._core.options.validator.applyTo).focus()
+ }), this._core.$element.on("submit", e.proxy(function (i) {
+ return this._core.$element.find(this._core.options.validator.applyTo).each(function () {
+ e(this).parent().trigger("mfValidator.validate", {options: t._core.options.validator})
+ }), this._core.$element.find(".error").length ? (i.preventDefault(), !1) : void 0
+ }, this)).on("mf.reset", e.proxy(function () {
+ this._core.$element.find(this._core.options.validator.applyTo).each(function () {
+ e(this).parent().trigger("mfValidator.reset", {options: t._core.options.validator})
+ })
+ }, this))
+ }, t.prototype.validate = function (t, i) {
+ var o, s = [], n = [], a = e(this), r = a.find(i.options.applyTo), l = r.data("constraints").match(/\@\w+/g), c = r.val();
+ for (var d in l)if (i.options.constraints[l[d]]) {
+ switch (typeof i.options.constraints[l[d]].rule) {
+ case"function":
+ i.options.constraints[l[d]].rule(r) ? a.find(".mfValidation") && a.find(".mfValidation").attr("data-index") === d && (o = !0, a.find(".mfValidation").attr("data-index", -1)) : (s.push(i.options.constraints[l[d]].message), n.push(d), o = !0);
+ break;
+ default:
+ new RegExp(i.options.constraints[l[d]].rule).test(c) ? a.find(".mfValidation").attr("data-index") && a.find(".mfValidation").attr("data-index") == d && (o = !0, a.find(".mfValidation").attr("data-index", -1)) : (s.push(i.options.constraints[l[d]].message), n.push(d), o = !0)
+ }
+ if (o)break
+ }
+ s.length ? e(this).trigger("mfValidator.error", {
+ options: i.options,
+ errors: s,
+ indexes: n
+ }) : e(this).trigger("mfValidator.valid", {options: i.options})
+ }, t.prototype.error = function (t, i) {
+ e(this).find("." + i.options["class"]).removeClass("valid").removeClass("hide").addClass("show").addClass("error").attr("data-index", i.indexes[0]).text(i.errors)
+ }, t.prototype.valid = function (t, i) {
+ var o = e(this).find("." + i.options["class"]);
+ o.hasClass("error") && o.removeClass("error").addClass("hide"), o.find("." + i.options["class"]).removeClass("show").addClass("valid").text(i.errors)
+ }, t.prototype.reset = function (t, i) {
+ var o = e(this).find("." + i.options["class"]);
+ o.hasClass("error") && o.removeClass("error").addClass("hide"), e(this).find("." + i.options["class"]).removeClass("show")
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Input = function (i) {
+ this._core = i, this._handlers = {
+ "mfInput.focus": this.focus,
+ "mfInput.blur": this.blur,
+ "mfInput.type": this.type,
+ "mfInput.delete": this["delete"],
+ "mfInput.fill": this.fill,
+ "mfInput.empty": this.empty,
+ "mfInput.idle": this.idle,
+ "mfInput.reset": this.reset,
+ click: function (e) {
+ return e.preventDefault(), !1
+ }
+ }, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ t.Defaults = {
+ input: {
+ applyto: 'input[type="text"], input[type="date"], textarea',
+ "class": "mfInput"
+ }
+ }, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfInput.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfInput.initialized")
+ }, t.prototype.create = function () {
+ this._core.$element.find(this._core.options.input.applyto).parent().addClass(this._core.options.input["class"])
+ }, t.prototype.watch = function () {
+ this._core.$element.find(this._core.options.input.applyto).on("focus", function () {
+ e(this).parent().trigger("mfInput.focus")
+ }).on("blur", function () {
+ e(this).parent().trigger("mfInput.blur"), "" === e(this).val() && e(this).parent().trigger("mfInput.void")
+ }).on("keydown", this, function (t) {
+ t.data.ignore(t) || ((8 === t.keyCode || 46 === t.keyCode) && e(this).parent().trigger("mfInput.delete"), (32 === t.keyCode || t.keyCode > 46) && e(this).parent().trigger("mfInput.type"))
+ }).on("keyup", this, function (t) {
+ var i = e(this);
+ t.data.ignore(t) || ("" === i.val() && i.parent().trigger("mfInput.empty"), 8 === t.keyCode || 46 === t.keyCode ? (self.timer && clearTimeout(self.timer), self.timer = setTimeout(function () {
+ i.parent().trigger("mfInput.idle")
+ }, 1e3)) : (i.parent().trigger("mfInput.fill"), i.parent().trigger("mfInput.type"), self.timer && clearTimeout(self.timer), self.timer = setTimeout(function () {
+ i.parent().trigger("mfInput.idle")
+ }, 1e3)))
+ }).on("keypress", this, function (t) {
+ if (!t.data.ignore(t.keyCode)) {
+ var i = e(this);
+ self.timer && clearTimeout(self.timer), self.timer = setTimeout(function () {
+ i.parent().trigger("mfInput.idle")
+ }, 1e3)
+ }
+ }).parent().on(this._handlers), this._core.$element.on("mf.reset", this, function (t) {
+ e(this).find("." + t.data._core.options.input["class"]).each(function () {
+ e(this).trigger("mfInput.reset")
+ })
+ })
+ }, t.prototype.focus = function () {
+ e(this).addClass("focused")
+ }, t.prototype.blur = function () {
+ e(this).removeClass("focused")
+ }, t.prototype.type = function () {
+ e(this).removeClass("deleting"), e(this).addClass("typing")
+ }, t.prototype["delete"] = function () {
+ e(this).removeClass("typing"), e(this).addClass("deleting")
+ }, t.prototype.fill = function () {
+ e(this).addClass("filled")
+ }, t.prototype.empty = function () {
+ e(this).removeClass("filled")
+ }, t.prototype.idle = function () {
+ e(this).removeClass("typing"), e(this).removeClass("deleting")
+ }, t.prototype.reset = function () {
+ e(this).removeClass("focused"), e(this).removeClass("deleting"), e(this).removeClass("filled"), e(this).removeClass("typing"), e(this).removeClass("error")
+ }, t.prototype.ignore = function (e) {
+ return 144 === e.keyCode || 20 === e.keyCode || 17 === e.keyCode || 37 === e.keyCode || 38 === e.keyCode || 39 === e.keyCode || 40 === e.keyCode || 112 === e.keyCode || 113 === e.keyCode || 114 === e.keyCode || 115 === e.keyCode || 116 === e.keyCode || 117 === e.keyCode || 118 === e.keyCode || 119 === e.keyCode || 120 === e.keyCode || 121 === e.keyCode || 122 === e.keyCode || 123 === e.keyCode || 9 === e.keyCode || e.ctrlKey ? !0 : !1
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Select = function (i) {
+ this._core = i, this._handlers = {
+ "mfSelect.close": this.close,
+ "mfSelect.open": this.open,
+ "mfSelect.select": this.select,
+ click: function (e) {
+ e.preventDefault(), e.stopPropagation()
+ }
+ }, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ t.Defaults = {select: {applyTo: "select", "class": "mfSelect"}}, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfSelect.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfSelect.initialized")
+ }, t.prototype.create = function () {
+ this._core.$element.find(this._core.options.select.applyTo).each(function () {
+ var t = e(this);
+ t.css({
+ position: "absolute",
+ left: "50%",
+ width: "0",
+ height: "0",
+ overflow: "hidden",
+ opacity: "0"
+ }).parent().append(e("<div/>", {
+ "class": "value",
+ text: t.find("option:selected").text()
+ })).append(e("<ul/>", {"class": "dropdown"})).end().find("option").each(function (t) {
+ if (0 != t) {
+ var i = e(this);
+ i.parent().parent().find(".dropdown").append(e("<li/>", {
+ "class": "option",
+ text: i.text()
+ }).addClass(i.is(":selected") ? "selected" : ""))
+ }
+ })
+ }).parent().addClass(this._core.options.select["class"])
+ }, t.prototype.watch = function () {
+ var t = this;
+ this._core.$element.find(t._core.options.select.applyTo).on("focus", this.focus).on("blur", function () {
+ e(this).parent().trigger("mfSelect.close").removeClass("focus")
+ }).on("keydown", function (t) {
+ 38 == t.keyCode && e(this).val(e(this).find("option").eq(e(this).find("option:selected").index() > 0 ? e(this).find("option:selected").index() - 1 : 0).text()).trigger("change"), 40 == t.keyCode && e(this).val(e(this).find("option").eq(e(this).find("option:selected").index() < e(this).find("option").length - 1 ? e(this).find("option:selected").index() + 1 : e(this).find("option").length - 1).text()).trigger("change"), 13 == t.keyCode && e(this).parent().trigger(e(this).parent().hasClass("show") ? "mfSelect.close" : "mfSelect.open"), (32 == t.keyCode || 37 == t.keyCode || 38 == t.keyCode || 39 == t.keyCode || 40 == t.keyCode || 13 == t.keyCode) && t.preventDefault()
+ }).on("change", function () {
+ e(this).parent().trigger("mfSelect.open").find(".value").text(e(this).val());
+ var t = e(this).find("option:selected").index(), i = e(this).parent().find(".option").removeClass("selected");
+ t > 0 && i.eq(t - 1).addClass("selected")
+ }).parent().on(this._handlers).find(".value").on("click", function () {
+ var i = e(this), o = i.parent().find("select"), s = o.find("option").eq(0).text();
+ if (i.text(s), o.trigger("focus").off("focus", t.focus), !e(this).parent().hasClass("show")) {
+ o.on("focus", t.focus);
+ var n = e(this).parent().find(".option.selected");
+ n.length && i.text(n.text())
+ }
+ }).parent().find(".option").on("click", function () {
+ e(this).parent().find(".option").removeClass("selected"), e(this).addClass("selected"), e(this).parent().parent().find("select").focus().on("focus", t.focus), e(this).parent().parent().trigger("mfSelect.select", {
+ options: t._core.options.select,
+ value: e(this).text()
+ })
+ }).parents("body").on("click", function (i) {
+ var o = t._core.$element.find("." + t._core.options.select["class"]);
+ o.length && (o.is(i.target) || 0 !== o.has(i.target).length || o.find("select").each(function () {
+ var t = e(this).parent().find(".option.selected");
+ t.length && e(this).parent().find(".value").text(t.text())
+ }).on("focus", t.focus))
+ }), this._core.$element.on("mf.reset", function () {
+ e(this).find(t._core.options.select.applyTo).each(function () {
+ e(this).parent().find(".value").text(e(this).prop("selectedIndex", 0).val()), e(this).parent().find(".option").removeClass("selected")
+ })
+ })
+ }, t.prototype.focus = function () {
+ e(this).parent().trigger("mfSelect.open").addClass("focus")
+ }, t.prototype.close = function () {
+ navigator.userAgent.match(/(iPod|iPhone|iPad)/) || e(this).hasClass("show") && e(this).removeClass("show")
+ }, t.prototype.open = function () {
+ navigator.userAgent.match(/(iPod|iPhone|iPad)/) || e(this).hasClass("show") || e(this).addClass("show")
+ }, t.prototype.select = function (t, i) {
+ e(this).find(i.options.applyTo).val(i.value).trigger("change"), e(this).trigger("mfSelect.close")
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.DatePicker = function (i) {
+ this._core = i, this._handlers = {
+ "mfDatePicker.close": this.close,
+ "mfDatePicker.open": this.open,
+ "mfDatePicker.next": this.next,
+ "mfDatePicker.prev": this.prev,
+ "mfDatePicker.update": this.update,
+ "mfDatePicker.refresh": this.refresh,
+ "mfDatePicker.pick": this.pick
+ }, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ t.Defaults = {
+ datepicker: {
+ applyTo: 'input[type="date"]',
+ "class": "mfDatePicker",
+ days: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ format: "MM-DD-YYYY",
+ prevMonth: "",
+ nextMonth: ""
+ }
+ }, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfDatePicker.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfDatePicker.initialized")
+ }, t.prototype.create = function () {
+ var t = this;
+ t._core.$element.find(t._core.options.datepicker.applyTo).each(function () {
+ e(this).attr({
+ type: navigator.userAgent.match(/(iPod|iPhone|iPad)/) ? "date" : "text",
+ "data-type": "date"
+ }).after(e("<div/>", {"class": t._core.options.datepicker["class"]}).data("date", new Date))
+ }).parent().find("." + t._core.options.datepicker["class"]).each(function () {
+ e.proxy(t.update, this, {}, t._core.options.datepicker).call(), e.proxy(t.refresh, this, {}, t._core.options.datepicker).call()
+ })
+ }, t.prototype.watch = function () {
+ var t = this;
+ t._core.$element.find("." + t._core.options.datepicker["class"]).on("click", "." + t._core.options.datepicker["class"] + "_next", function () {
+ var i = e(this).parents("." + t._core.options.datepicker["class"]);
+ i.trigger("mfDatePicker.next"), i.trigger("mfDatePicker.update", t._core.options.datepicker), i.trigger("mfDatePicker.refresh", t._core.options.datepicker)
+ }).on("click", "." + t._core.options.datepicker["class"] + "_prev", function () {
+ var i = e(this).parents("." + t._core.options.datepicker["class"]);
+ i.trigger("mfDatePicker.prev"), i.trigger("mfDatePicker.update", t._core.options.datepicker), i.trigger("mfDatePicker.refresh", t._core.options.datepicker)
+ }).on("click", ".dp-day", function () {
+ var i = e(this).parents("." + t._core.options.datepicker["class"]);
+ i.trigger("mfDatePicker.pick", {
+ opt: t._core.options.datepicker,
+ day: e(this)
+ }), i.parent().find("input").on("blur", t.blur).trigger("blur").trigger("keyup")
+ }).on("click", function () {
+ }).on(this._handlers).parent().on("click", function (e) {
+ return e.preventDefault(), !1
+ }).find("input").on("focus", function () {
+ e(this).parent().find("." + t._core.options.datepicker["class"]).trigger("mfDatePicker.open")
+ }).on("blur", this.blur).on("keydown", function (i) {
+ (9 == i.keyCode || i.shiftKey && 9 == i.keyCode) && e(this).on("blur", t.blur)
+ }).parents("body").on("mousedown", function (e) {
+ var i = t._core.$element.find("." + t._core.options.datepicker["class"]).parent();
+ i.length && (i.is(e.target) || 0 !== i.has(e.target).length ? i.find("input").off("blur", t.blur) : i.find("input").on("blur", t.blur).trigger("blur"))
+ }), t._core.$element.on("mf.reset", function () {
+ e(this).find("." + t._core.options.datepicker["class"]).each(function () {
+ e(this).trigger("mfDatePicker.close")
+ })
+ })
+ }, t.prototype.blur = function () {
+ e(this).parent().find(".mfDatePicker").trigger("mfDatePicker.close")
+ }, t.prototype.close = function () {
+ navigator.userAgent.match(/(iPod|iPhone|iPad)/) || e(this).hasClass("open") && e(this).removeClass("open")
+ }, t.prototype.open = function () {
+ navigator.userAgent.match(/(iPod|iPhone|iPad)/) || e(this).hasClass("open") || e(this).addClass("open")
+ }, t.prototype.next = function () {
+ var t = e(this), i = t.data("date");
+ i = 11 == i.getMonth() ? new Date(i.getFullYear() + 1, 0, 1) : new Date(i.getFullYear(), i.getMonth() + 1, 1), t.data("date", i)
+ }, t.prototype.prev = function () {
+ var t = e(this), i = t.data("date");
+ i = 0 == i.getMonth() ? new Date(i.getFullYear() - 1, 11, 1) : new Date(i.getFullYear(), i.getMonth() - 1, 1), t.data("date", i)
+ }, t.prototype.pick = function (t, i) {
+ var o = e(this);
+ o.data("pickedDate", i.day.addClass("dp-selected").data("date")), o.find(".dp-day").not(i.day).removeClass("dp-selected"), o.parent().find("input").val((o.data("pickedDate").getMonth() + 1 < 10 ? "0" + (o.data("pickedDate").getMonth() + 1) : o.data("pickedDate").getMonth() + 1) + "/" + (o.data("pickedDate").getDate() < 10 ? "0" + o.data("pickedDate").getDate() : o.data("pickedDate").getDate()) + "/" + o.data("pickedDate").getFullYear())
+ }, t.prototype.update = function (t, i) {
+ var o = e(this), s = e("<div/>", {"class": i["class"] + "_panel"});
+ s.append(e("<a/>", {
+ "class": i["class"] + "_prev",
+ text: i.prevMonth
+ })), s.append(e("<a/>", {
+ "class": i["class"] + "_next",
+ text: i.nextMonth
+ })), s.append(e("<div/>", {
+ "class": i["class"] + "_title",
+ text: i.months[o.data("date").getMonth()] + " " + o.data("date").getFullYear()
+ }));
+ var n = o.find("." + i["class"] + "_panel");
+ n.length ? n.replaceWith(s) : s.appendTo(o)
+ }, t.prototype.refresh = function (t, i) {
+ for (var o = e(this), s = e("<table/>"), n = e("<tr/>"), a = 0; a < i.days.length; a++)n.append(e("<th/>", {
+ "class": "dp-weekday",
+ text: i.days[a]
+ }));
+ s.append(n);
+ for (var r = o.data("date"), l = o.data("pickedDate"), c = new Date(r.getFullYear(), r.getMonth() + 1, 0).getDate(), d = new Date(r.getFullYear(), r.getMonth(), 0).getDate(), p = new Date(r.getFullYear(), r.getMonth(), 1).getDay(), f = 1, a = 0; 7 > a; a++) {
+ n = e("<tr/>");
+ for (var h = 0; 7 > h; h++) {
+ var u, m = 7 * a + h + 1, g = e("<td/>", {"class": "dp-day"}), y = new Date;
+ if (y.setHours(0), y.setMinutes(0), y.setSeconds(0), y.setMilliseconds(0), 0 == h && m > c + p)break;
+ 1 > m - p ? (g.text(d + (m - p)).addClass("dp-offset"), u = new Date(r.getFullYear(), r.getMonth() - 1, d + (m - p))) : c + p >= m ? (g.text(m - p), u = new Date(r.getFullYear(), r.getMonth(), m - p)) : (g.text(f).addClass("dp-offset"), u = new Date(r.getFullYear(), r.getMonth() + 1, f++)), u.valueOf() == y.valueOf() && g.addClass("dp-today"), l && u.valueOf() == l.valueOf() && g.addClass("dp-selected"), n.append(g.data("date", u))
+ }
+ "" != n.html() && s.append(n)
+ }
+ var v = o.find("table");
+ v.length ? v.replaceWith(s) : s.appendTo(o)
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Icon = function (i) {
+ this._core = i, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ this._handlers = {"mfIcon.change": this.change}, t.Defaults = {
+ icon: {
+ applyTo: "[data-add-icon]",
+ "class": "mfIcon",
+ states: {
+ ".mfInput": {
+ "mfIcon.default": ["mfInput.blur", "mfInput.idle", "mfInput.reset"],
+ "mfIcon.state-1": ["mfInput.type"],
+ "mfIcon.state-2": ["mfInput.delete"]
+ }
+ }
+ }
+ }, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfIcon.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfIcon.initialized")
+ }, t.prototype.create = function () {
+ var t = this;
+ t._core.$element.find(t._core.options.icon.applyTo).each(function () {
+ var i = e(this);
+ i.append(e("<span/>", {"class": t._core.options.icon["class"]}).append(e("<span/>")))
+ })
+ }, t.prototype.watch = function () {
+ var t = this;
+ t._core.$element.find("." + t._core.options.icon["class"]).on(t._handlers);
+ for (var i in t._core.options.icon.states) {
+ var o = t._core.$element.find(i);
+ for (var s in t._core.options.icon.states[i])for (var n in t._core.options.icon.states[i][s])o.on(t._core.options.icon.states[i][s][n], {state: s}, function (i) {
+ e(this).find("." + t._core.options.icon["class"]).attr("class", i.data.state.replace(".", " "))
+ })
+ }
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Placeholder = function (i) {
+ this._core = i, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ this._handlers = {"mfIcon.change": this.change}, t.Defaults = {
+ placeholder: {
+ applyTo: "[data-add-placeholder]",
+ "class": "mfPlaceHolder",
+ states: {
+ ".mfInput": {
+ "mfPlaceHolder.default": ["mfInput.void", "mfInput.reset"],
+ "mfPlaceHolder.state-1": ["mfInput.fill", "mfInput.focus"]
+ }
+ }
+ }
+ }, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfPlaceHolder.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfPlaceHolder.initialized")
+ }, t.prototype.create = function () {
+ var t = this;
+ t._core.$element.find(t._core.options.placeholder.applyTo).each(function () {
+ var i = e(this);
+ i.append(e("<span/>", {
+ "class": t._core.options.placeholder["class"],
+ text: i.find("[placeholder]").attr("placeholder") ? i.find("[placeholder]").attr("placeholder") : i.find("[data-placeholder]").attr("data-placeholder")
+ })).find("[placeholder]").removeAttr("placeholder").removeAttr("data-placeholder")
+ })
+ }, t.prototype.watch = function () {
+ var t = this;
+ t._core.$element.find("." + t._core.options.placeholder["class"]).on("click", function () {
+ e(this).parent().find("input, textarea").trigger("focus")
+ }).on(t._handlers);
+ for (var i in t._core.options.icon.states) {
+ var o = t._core.$element.find(i);
+ for (var s in t._core.options.placeholder.states[i])for (var n in t._core.options.placeholder.states[i][s])o.on(t._core.options.placeholder.states[i][s][n], {state: s}, function (i) {
+ e(this).find("." + t._core.options.placeholder["class"]).attr("class", i.data.state.replace(".", " "))
+ })
+ }
+ }
+}(window.jQuery, window, document), function (e) {
+ var t = e.fn.rdMailForm.Constructor.Plugins.Progress = function (i) {
+ this._core = i, this._core.options = e.extend(!0, {}, t.Defaults, this._core.options), this.initialize()
+ };
+ t.Defaults = {progress: {applyTo: ".mfInfo", "class": "mfProgress"}}, t.prototype.initialize = function () {
+ this._core.$element.trigger("mfProgress.initialize"), this.create(), this.watch(), this._core.$element.trigger("mfProgress.initialized")
+ }, t.prototype.create = function () {
+ var t = this;
+ t._core.$element.find(t._core.options.progress.applyTo).each(function () {
+ var i = e(this);
+ i.addClass(t._core.options.progress["class"]).wrapInner(e("<span/>", {"class": "cnt"})).append(e("<span/>", {"class": "loader"})).append(e("<span/>", {"class": "msg"}))
+ })
+ }, t.prototype.watch = function () {
+ var t = this;
+ t._core.$element.on("mf.process", function () {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("hide").addClass("sending").find(".msg").text("Loading...")
+ }).on("mf.fail", function (i, o) {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("sending").addClass("fail").find(".msg").text(o.message), setTimeout(e.proxy(function () {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("fail").addClass("hide").find(".msg")
+ }, this), 3e3)
+ }).on("mf.success", function (i, o) {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("sending").addClass("success").find(".msg").text(o.message), setTimeout(e.proxy(function () {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("success").addClass("hide").find(".msg")
+ }, this), 1500)
+ }).on("mf.reset", function () {
+ e(this).find("." + t._core.options.progress["class"]).removeClass("sending").removeClass("fail").removeClass("success").find(".msg")
+ })
+ }
+}(window.jQuery, window, document);
\ No newline at end of file