(function (global, $, _, Backbone) { 'use strict'; var FieldView, FieldFormModel; FieldFormModel = AMOFORMS.core.form.Model.extend({ url: ajaxurl, toJSON: function () { var attrs = {}; _.each(this.attributes, function (value, key) { attrs[key.replace(/(field\d+)/gi, 'field')] = value; }); return attrs; }, toFullJSON: function () { var attrs = { field: {} }; _.each(this.attributes, function (value, key) { if (key.match(/\[enums\]/)) { if (!attrs.field.enums) { attrs.field.enums = []; } attrs.field.enums[key.replace(/field(\d+)?\[enums\]\[(\d+)\]/gi, '$2')] = value; } else { attrs.field[key.replace(/field(\d+)?\[(\w+)\]/gi, '$2')] = AMOFORMS.core.fn.isNumeric(value) ? parseInt(value, 10) : value; } }); return attrs; }, save: function (options) { $.ajax({ url: ajaxurl, data: _.extend({ action: AMOFORMS.ajax_action_prefix + 'edit_field', form: { id: this.form_id }, }, this.toJSON()), dataType: 'json', type: 'POST' }) .done(_.bind(function (res) { if (res.result) { (options.success || function () {})(res, this); } else { (options.error || function () {})(res, this); } }, this)) .fail(_.bind(function () { (options.error || function () {})(res, this); })); }, destroy: function (options) { options = options || {}; $.ajax({ url: ajaxurl, data: { action: AMOFORMS.ajax_action_prefix + 'delete_field', form: { id: this.form_id }, field: { id: this.getByCode('id') } }, dataType: 'json', type: 'POST' }) .done(_.bind(function (res) { if (res.result) { options.success(res, this); } else { (options.fail || function () {})(res, this); } }, this)) .fail(_.bind(function () { (options.fail || function () {})(res, this); }, this)); }, getByCode: function (code) { return _.find(this.attributes, function (value, key) { return new RegExp('field[\\d]{0,}?\\[' + code + '\\]', 'gi').exec(key) !== null; }); } }); FieldView = Backbone.View.extend({ selectors: { inner: '.amoforms__fields__row__inner', name: '.amoforms__fields__row__inner__name', control: '.amoforms__fields__row__inner__control', description: '.amoforms__fields__row__inner__descr', form: '.amoforms__fields__edit', save: '.js-amoforms-field-save', cancel: '.js-amoforms-field-cancel', date: '.amoforms__date .amoforms__text-input', enums: '.amoforms__fields__edit__row__options', enum: '.amoforms__fields__edit__row__options__item', enum_handle: '.amoforms__fields__edit__row__options__item__move', enum_add: '.amoforms__fields__edit__row__options__add', mask: '.js-mask', edit_input: 'input[name="field[default_value]"]', placeholder_input: 'input[name="field[placeholder]"]', file_label: '.amoforms__file-input__title' }, events: { 'click .amoforms__fields__editor__row__actions__action-edit': 'setEdit', 'click .amoforms__fields__editor__row__actions__action-delete': 'confirmDelete', 'click .amoforms__fields__editor__row__actions__action-duplicate': 'duplicateField', 'click .js-amoforms-field-save': 'submitEdit', 'click .js-amoforms-field-cancel': 'cancelEdit', 'click .amoforms__fields__edit__row__options__item__trash': 'deleteEnum', 'click .amoforms__fields__edit__row__options__add': 'addEnum', 'input .js-is-number': 'validateNumber', 'change .js-is-date': 'validateDate', 'change .js-is-email': 'validateEmail', 'change .js-is-url': 'validateUrl', 'change .js-is-required': 'validateRequired', 'blur .js-is-extensions': 'validateExtensions', 'change .js-is-filesize': 'validateFilesize', 'mouseover': 'setHover', 'mouseout': 'removeHover' }, setHover: function () { this.$el.addClass('hover'); }, removeHover: function () { this.$el.removeClass('hover'); }, initialize: function (options) { options = options || {}; this.enumsSortUpdate(); this.form = new AMOFORMS.core.form.View({ el: this.$(this.selectors['form']), Model: FieldFormModel }); this.form.model.form_id = options.form_id; this.ns = '.amoforms:field:ns' + this.form.model.getByCode('id'); this.form.model.on('change', _.bind(function (model) { this.renderChange(_.map(model.changed, function (value, key) { return { key: /field[\d]{0,}?\[([\w\d]+)\]/gi.exec(key)[1] || '', value: value }; })); }, this)); this.$('.js-is-date').pickmeup(_.extend({}, AMOFORMS.core.fn.pickmeup_options, { change: function () { $(this) .trigger('input') .trigger('change'); } })); $(document).on('amoforms:field:render' + this.ns, _.bind(this.render, this)); }, remove: function () { $(document).off(this.ns); this.form.remove(); Backbone.View.prototype.remove.apply(this, arguments); }, render: function (e, name_position) { var $description_before; this.$el.removeClass('amoforms-field-name-position-before amoforms-field-name-position-above amoforms-field-name-position-inside'); this.$el.addClass('amoforms-field-name-position-' + name_position); this.$(this.selectors['name'])[(name_position == 'inside') && (_.indexOf(['checkbox', 'radio'], this.form.model.getByCode('type')) === -1) ? 'hide' : 'show'](); if (this.form.model.getByCode('description_position') == 'before') { $description_before = name_position == 'before' ? this.$(this.selectors['inner']) : this.$(this.selectors['control']); if ((this.form.model.getByCode('type') == 'radio') && (name_position == 'inside')) { $description_before = this.$(this.selectors['inner']); } $description_before.before(this.$(this.selectors['description'])); } this.$('.js-edit-placeholder-wrapper')[name_position == 'inside' ? 'hide' : 'show'](); this.$(this.selectors['control'] + ' .amoforms__text-input, ' + this.selectors['control'] + ' .amoforms__select__input') .attr('placeholder', this.form.model.getByCode(name_position == 'inside' ? 'name' : 'placeholder')); }, /* DOM-events */ validateRequired: function (e) { var $this = $(e.currentTarget); $this[$this.val() ? 'removeClass' : 'addClass']('error'); // $(e.currentTarget). }, validateDate: function (e) { this.validateByType($(e.currentTarget), 'validDate'); }, validateUrl: function (e) { this.validateByType($(e.currentTarget), 'validUrl'); }, validateEmail: function (e) { this.validateByType($(e.currentTarget), 'validEmail'); }, validateExtensions: function (e) { this.validateByType($(e.currentTarget), 'validExtensions'); }, validateFilesize: function (e) { this.validateByType($(e.currentTarget), 'validFilesize'); }, validateByType: function ($this, type) { var val = $.trim($this.val()); $this[!val || AMOFORMS.core.fn[type](val) ? 'removeClass' : 'addClass']('error'); }, validateNumber: function (e, no_validate) { var $this, cleaned_value; if (no_validate === true) { return; } $this = $(e.currentTarget); cleaned_value = $this.val().replace(/[^0-9]+/, ''); if ($this.val() !== cleaned_value) { $this.val(cleaned_value).trigger('input', [true]); return false; } }, duplicateField: function (e) { if ($(e.target).parent().prev().hasClass('amoforms__captcha')) { return; } AMOFORMS.app.duplicateField(this.$el, this.form.model.getByCode('id')); }, addEnum: function () { var $last_enum = this.$(this.selectors['enums']).find(this.selectors['enum'] + ':last'), $new_enum; if (!$last_enum.find('input').val()) { $last_enum.find('input').focus(); return; } $new_enum = $last_enum.clone(); this.$(this.selectors['enums']).append($new_enum); $new_enum.find('input').val('').focus(); this.enumsSortUpdate(); }, deleteEnum: function (e) { if (this.$(this.selectors['enum']).length == 2) { return; } $(e.currentTarget).closest(this.selectors['enum']).remove(); this.form.checkDeleted(); }, setEdit: function () { this.form.show(); this.$el.addClass('in-edit').find('.amoforms__fields__edit__textarea').css('height', '').trigger('textarea:resize:manual'); this.makeSortable(true); $('html, body').animate({ scrollTop: this.$el.offset().top - 40 }, 300); }, confirmDelete: function () { new AMOFORMS.core.confirm({ template_params: { caption: 'Are you sure you want to delete «' + (this.form.model.getByCode('name') || '') + '»?', accept_btn: 'Yes', decline_btn: 'No' }, accept: _.bind(function (confirm) { this.form.model.destroy({ success: _.bind(function () { if (this.$el.find('.amoforms__captcha').length > 0) { $('[data-type="captcha"]').attr('data-active', 'true'); } this.remove(); confirm.done(); }, this), fail: _.bind(function () { confirm.failed(); }, this), }); }, this), }); }, submitEdit: function () { var $submit_btn; if (this.form.$el.find('input.error').length) { $submit_btn = this.form.$el.find(this.selectors['save']).addClass('animated shake'); _.delay(function () { $submit_btn.removeClass('animated shake'); }, 800); return; } this.form.save({ success: _.bind(function () { this.cancelEdit(); }, this), error: _.bind(function () { this.$(this.selectors['actions']).addClass('animated shake'); _.delay(_.bind(function () { this.$(this.selectors['actions']).removeClass('shake'); }, this), 800); }, this), }); }, cancelEdit: function (e) { if (e && e.preventDefault) { e.preventDefault(); } this.makeSortable(false); this.$el.removeClass('in-edit'); this.form.model.set(this.form.model.defaults); this.form.revert(); this.form.hide(); this.renderChange([{ key: 'enums', value: '' }]); }, /* endof DOM-events */ renderChange: function (changed_values) { _.each(changed_values, function (changed) { switch (changed.key) { case 'name': if (this.form.model.getByCode('type') == 'heading') { this.$(this.selectors['control'] + ' h1').text(changed.value); } else { if (this.$el.hasClass('amoforms-field-name-position-inside')) { this.$(this.selectors['control'] + ' .amoforms__text-input, ' + this.selectors['control'] + ' .amoforms__select__input').attr('placeholder', changed.value); } else { this.$(this.selectors['name'] + ' > span').text(changed.value).parent()[changed.value ? 'show' : 'hide'](); } } break; case 'required': this.$(this.selectors['name'] + ' > b').remove(); if (parseInt(changed.value) === 1) { this.$(this.selectors['name'] + ' > span').after('*'); } break; case 'default_value': this.$(this.selectors['control'] + ' :input').val(changed.value).trigger('change'); break; case 'placeholder': this.$(this.selectors['control'] + ' :input').attr('placeholder', changed.value); break; case 'description': if (this.form.model.getByCode('type') == 'instructions') { this.$('.amoforms__control-instructions').text(changed.value); } else { this.$(this.selectors['description']).text(changed.value)[changed.value ? 'show' : 'hide'](); } break; case 'description_position': if (!changed.value) { return; } if (this.form.model.getByCode('type') == 'checkbox') { if (this.$el.hasClass('amoforms-field-name-position-before')) { this.$(this.selectors['inner'])[changed.value](this.$(this.selectors['description'])) } else { this.$(this.selectors['control'])[changed.value](this.$(this.selectors['description'])); } } else { if (changed.value == 'after') { this.$(this.selectors['inner']).after(this.$(this.selectors['description'])); } else { // для name-position before if (this.$el.hasClass('amoforms-field-name-position-before') || ((this.form.model.getByCode('type') == 'radio') && this.$el.hasClass('amoforms-field-name-position-inside')) ) { this.$(this.selectors['inner']).before(this.$(this.selectors['description'])) } else { this.$(this.selectors['name']).after(this.$(this.selectors['description'])); } } } break; case 'options': if (this.$(this.selectors['mask']).children().find('input:checked')) { if (this.$(this.selectors['mask']).children().find('input:checked').val() == 1) { if (void 0 === this.$(this.selectors['edit_input']).attr('disabled')) { // Не понятно в чём проблема. this.$(this.selectors['edit_input']).val(''); this.$(this.selectors['placeholder_input']).val(''); this.$(this.selectors['edit_input']).attr("value", ""); this.$(this.selectors['control'] + ' :input').val(''); this.$(this.selectors['control'] + ' :input').removeAttr('placeholder'); // this.$(this.selectors['edit_input']).attr("disabled", "disabled"); this.$(this.selectors['placeholder_input']).attr("disabled", "disabled"); } } else { if ('disabled' === this.$(this.selectors['edit_input']).attr('disabled')) { this.$(this.selectors['edit_input']).removeAttr('disabled'); this.$(this.selectors['placeholder_input']).removeAttr('disabled'); } } } break; case 'layout': if (changed.value) { this.$('.amoforms__radio-control')[changed.value == AMOFORMS.consts.layout_inline ? 'removeClass' : 'addClass']('amoforms__radio-control-block'); } break; case 'enums': if (changed.value !== undefined) { if (this.form.model.getByCode('type') == 'radio') { this.$('.amoforms__radio-control').html( $.makeArray( this.$(this.selectors['enum']).map(function () { if (!$(this).find('input').val()) { return ''; } return ''; }) ).join('') ); } else { this.$('select').html( $.makeArray( this.$(this.selectors['enum']).map(function () { if (!$(this).find('input').val()) { return ''; } return ''; }) ).join('') ); } } break; case 'label': this.$(this.selectors['file_label']).text(changed.value); break; } }, this); }, makeSortable: function (active) { if (!this.$(this.selectors['enums'])[0]) { return; } if (active) { this.options_sortable = new Sortable(this.$(this.selectors['enums'])[0], { handle: this.selectors['enum_handle'], draggable: this.selectors['enum'], animation: 150, onEnd: _.bind(function () { this.enumsSortUpdate(); }, this) }); } else { if (this.options_sortable) { this.options_sortable.destroy(); } } }, enumsSortUpdate: function () { var $input, name; this.$(this.selectors['enum']).each(function (key, value) { $input = $(this).find('input'); name = $input.attr('name'); $input.attr('name', name.replace(/(field\[enums\]\[)(.*)(\])/gi, '$1' + key + '$3')); }); if (this.form) { this.form.initModelFromForm(); this.renderChange([{ key: 'enums', value: '' }]); } } }); global.AMOFORMS = $.extend(true, global.AMOFORMS || {}, { views: { field: FieldView } }); }(window, jQuery, _, Backbone));