(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));