\n';
return __p
}
var TableView = Marionette.ItemView.extend({
tagName: 'table',
className: 'table_view',
template: template$2,
ui: {
headRow: 'thead tr',
body: 'tbody'
},
onRender: function onRender() {
var view = this;
_(this.options.columns).each(function (column) {
this.ui.headRow.append(this.subview(new TableHeaderCellView({
column: column,
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
})).el);
}, this);
this.subview(new CollectionView({
el: this.ui.body,
collection: this.collection,
itemViewConstructor: TableRowView,
itemViewOptions: {
columns: this.options.columns,
selection: this.options.selection,
selectionAttribute: this.options.selectionAttribute,
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
},
blankSlateViewConstructor: Marionette.ItemView.extend({
tagName: 'tr',
className: 'blank_slate',
template: blankSlateTemplate,
serializeData: function serializeData() {
return {
blankSlateText: view.options.blankSlateText,
colSpan: view.options.columns.length
};
}
})
}));
}
});
function template$3(data) {
var __p = '';
__p += '\n\n';
return __p
}
var TooltipView = Marionette.ItemView.extend({
template: template$3,
className: 'tooltip',
ui: {
label: '.label'
},
hide: function hide() {
this.visible = false;
clearTimeout(this.timeout);
this.$el.removeClass('visible');
},
show: function show(text, position, options) {
options = options || {};
this.visible = true;
clearTimeout(this.timeout);
this.timeout = setTimeout(_.bind(function () {
var offsetTop;
var offsetLeft;
this.ui.label.text(text);
this.$el.toggleClass('align_bottom_right', options.align === 'bottom right');
this.$el.toggleClass('align_bottom_left', options.align === 'bottom left');
this.$el.toggleClass('align_top_center', options.align === 'top center');
if (options.align === 'bottom right' || options.align === 'bottom left') {
offsetTop = 10;
offsetLeft = 0;
} else if (options.align === 'top center') {
offsetTop = -10;
offsetLeft = 0;
} else {
offsetTop = -17;
offsetLeft = 10;
}
this.$el.css({
top: position.top + offsetTop + 'px',
left: position.left + offsetLeft + 'px'
});
this.$el.addClass('visible');
}, this), 200);
}
});
/**
* Mixin for input views handling common concerns like labels,
* inline help, visiblity and disabling.
*
* ## Label and Inline Help Translations
*
* By default `#labelText` and `#inlineHelpText` are defined through
* translations. If no `attributeTranslationKeyPrefixes` are given,
* translation keys for labels and inline help are constructed from
* the `i18nKey` of the model and the given `propertyName`
* option. Suppose the model's `i18nKey` is "page" and the
* `propertyName` option is "title". Then the key
*
* activerecord.attributes.page.title
*
* will be used for the label. And the key
*
* pageflow.ui.inline_help.page.title_html
* pageflow.ui.inline_help.page.title
*
* will be used for the inline help.
*
* ### Attribute Translation Key Prefixes
*
* The `attributeTranslationKeyPrefixes` option can be used to supply
* an array of scopes in which label and inline help translations
* shall be looked up based on the `propertyName` option.
*
* Suppose the array `['some.attributes', 'fallback.attributes']` is
* given as `attributeTranslationKeyPrefixes` option. Then, in the
* example above, the first existing translation key is used as label:
*
* some.attributes.title.label
* fallback.attributes.title.label
* activerecord.attributes.post.title
*
* Accordingly, for the inline help:
*
* some.attributes.title.inline_help_html
* some.attributes.title.inline_help
* fallback.attributes.title.inline_help_html
* fallback.attributes.title.inline_help
* pageflow.ui.inline_help.post.title_html
* pageflow.ui.inline_help.post.title
*
* This setup allows to keep all translation keys for an attribute
* to share a common prefix:
*
* some:
* attributes:
* title:
* label: "Label"
* inline_help: "..."
* inline_help_disabled: "..."
*
* ### Inline Help for Disabled Inputs
*
* For each inline help translation key, a separate key with an
* `"_disabled"` suffix can be supplied, which provides a help string
* that shall be displayed when the input is disabled. More specific
* attribute translation key prefixes take precedence over suffixed
* keys:
*
* some.attributes.title.inline_help_html
* some.attributes.title.inline_help
* some.attributes.title.inline_help_disabled_html
* some.attributes.title.inline_help_disabled
* fallback.attributes.title.inline_help_html
* fallback.attributes.title.inline_help
* fallback.attributes.title.inline_help_disabled_html
* fallback.attributes.title.inline_help_disabled
* pageflow.ui.inline_help.post.title_html
* pageflow.ui.inline_help.post.title
* pageflow.ui.inline_help.post.title_disabled_html
* pageflow.ui.inline_help.post.title_disabled
*
* @param {string} options
* Common constructor options for all views that include this mixin.
*
* @param {string} options.propertyName
* Name of the attribute on the model to display and edit.
*
* @param {string} [options.label]
* Label text for the input.
*
* @param {string[]} [options.attributeTranslationKeyPrefixes]
* An array of prefixes to lookup translations for labels and
* inline help texts based on attribute names.
*
* @param {string} [options.additionalInlineHelpText]
* A text that will be appended to the translation based inline
* text.
*
* @param {string|string[]} [options.disabledBinding]
* Name of an attribute to control whether the input is disabled. If
* the `disabled` and `disabledBinding` options are not set,
* input will be disabled whenever this attribute has a truthy value.
* When multiple attribute names are passed, the function passed to
* the `disabled` option will receive an array of values in the same
* order.
*
* @param {function|boolean} [options.disabled]
* Render input as disabled. A Function taking the value of the
* `disabledBinding` attribute as parameter. Input will be disabled
* only if function returns `true`.
*
* @param {any} [options.disabledBindingValue]
* Input will be disabled whenever the value of the `disabledBinding`
* attribute equals the value of this option.
*
* @param {string|string[]} [options.visibleBinding]
* Name of an attribute to control whether the input is visible. If
* the `visible` and `visibleBindingValue` options are not set,
* input will be visible whenever this attribute has a truthy value.
* When multiple attribute names are passed, the function passed to
* the `visible` option will receive an array of values in the same
* order.
*
* @param {function|boolean} [options.visible]
* A Function taking the value of the `visibleBinding` attribute as
* parameter. Input will be visible only if function returns `true`.
*
* @param {any} [options.visibleBindingValue]
* Input will be visible whenever the value of the `visibleBinding`
* attribute equals the value of this option.
*
* @mixin
*/
var inputView = {
ui: {
label: 'label',
labelText: 'label .name',
inlineHelp: 'label .inline_help'
},
/**
* Returns an array of translation keys based on the
* `attributeTranslationKeyPrefixes` option and the given keyName.
*
* Combined with {@link #i18nutils
* i18nUtils.findTranslation}, this can be used inside input views
* to obtain additional translations with the same logic as for
* labels and inline help texts.
*
* findTranslation(this.attributeTranslationKeys('default_value'));
*
* @param {string} keyName
* Suffix to append to prefixes.
*
* @param {string} [options.fallbackPrefix]
* Optional additional prefix to form a model based translation
* key of the form `prefix.modelI18nKey.propertyName.keyName
*
* @return {string[]}
* @since 0.9
* @member
*/
attributeTranslationKeys: function attributeTranslationKeys$1(keyName, options) {
return attributeTranslationKeys(this.options.propertyName, keyName, _.extend({
prefixes: this.options.attributeTranslationKeyPrefixes,
fallbackModelI18nKey: this.model.i18nKey
}, options || {}));
},
onRender: function onRender() {
this.$el.addClass('input');
this.$el.addClass(this.model.modelName + '_' + this.options.propertyName);
this.$el.data('inputPropertyName', this.options.propertyName);
this.$el.data('labelText', this.labelText());
this.$el.data('inlineHelpText', this.inlineHelpText());
this.ui.labelText.text(this.labelText());
this.updateInlineHelp();
this.setLabelFor();
this.setupAttributeBinding('disabled', this.updateDisabled);
this.setupAttributeBinding('visible', this.updateVisible);
},
/**
* The label to display in the form.
* @return {string}
*/
labelText: function labelText() {
return this.options.label || this.localizedAttributeName();
},
localizedAttributeName: function localizedAttributeName() {
return findTranslation(this.attributeTranslationKeys('label', {
fallbackPrefix: 'activerecord.attributes'
}));
},
updateInlineHelp: function updateInlineHelp() {
this.ui.inlineHelp.html(this.inlineHelpText());
if (!this.inlineHelpText()) {
this.ui.inlineHelp.hide();
}
},
/**
* The inline help text for the form field.
* @return {string}
*/
inlineHelpText: function inlineHelpText() {
var keys = this.attributeTranslationKeys('inline_help', {
fallbackPrefix: 'pageflow.ui.inline_help'
});
if (this.isDisabled()) {
keys = translationKeysWithSuffix(keys, 'disabled');
}
return _.compact([findTranslation(keys, {
defaultValue: '',
html: true
}), this.options.additionalInlineHelpText]).join(' ');
},
setLabelFor: function setLabelFor() {
if (this.ui.input && this.ui.label.length === 1 && !this.ui.input.attr('id')) {
var id = 'input_' + this.model.modelName + '_' + this.options.propertyName;
this.ui.input.attr('id', id);
this.ui.label.attr('for', id);
}
},
isDisabled: function isDisabled() {
return this.getAttributeBoundOption('disabled');
},
updateDisabled: function updateDisabled() {
this.updateInlineHelp();
if (this.ui.input) {
this.updateDisabledAttribute(this.ui.input);
}
},
updateDisabledAttribute: function updateDisabledAttribute(element) {
if (this.isDisabled()) {
element.attr('disabled', true);
} else {
element.removeAttr('disabled');
}
},
updateVisible: function updateVisible() {
this.$el.toggleClass('input-hidden_via_binding', this.getAttributeBoundOption('visible') === false);
},
setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
var _this = this;
var binding = this.options["".concat(optionName, "Binding")];
var view = this;
if (binding) {
_.flatten([binding]).forEach(function (attribute) {
_this.listenTo(_this.model, 'change:' + attribute, update);
});
}
update();
function update() {
updateMethod.call(view, view.getAttributeBoundOption(optionName));
}
},
getAttributeBoundOption: function getAttributeBoundOption(optionName) {
var _this2 = this;
var binding = this.options["".concat(optionName, "Binding")];
var bindingValueOptionName = "".concat(optionName, "BindingValue");
var value = Array.isArray(binding) ? binding.map(function (attribute) {
return _this2.model.get(attribute);
}) : this.model.get(binding);
if (bindingValueOptionName in this.options) {
return value === this.options[bindingValueOptionName];
} else if (typeof this.options[optionName] === 'function') {
return !!this.options[optionName](value);
} else if (optionName in this.options) {
return !!this.options[optionName];
} else if (binding) {
return !!value;
}
}
};
function template$4(data) {
var __p = '';
__p += '\n\n';
return __p
}
/**
* Input view for attributes storing configuration hashes with boolean values.
* See {@link inputView} for further options.
*
* @param {Object} [options]
*
* @class
*/
var CheckBoxGroupInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$4,
className: 'check_box_group_input',
events: {
'change': 'save'
},
ui: {
label: 'label',
container: '.check_boxes_container'
},
initialize: function initialize() {
if (!this.options.texts) {
if (!this.options.translationKeys) {
var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
fallbackPrefix: 'activerecord.values'
}));
this.options.translationKeys = _.map(this.options.values, function (value) {
return translationKeyPrefix + '.' + value;
}, this);
}
this.options.texts = _.map(this.options.translationKeys, function (key) {
return I18n$1.t(key);
});
}
},
onRender: function onRender() {
this.ui.label.attr('for', this.cid);
this.appendOptions();
this.load();
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
},
appendOptions: function appendOptions() {
_.each(this.options.values, function (value, index) {
var option = '
' + '
';
this.ui.container.append($(option));
}, this);
},
save: function save() {
var configured = {};
_.each(this.ui.container.find('input'), function (input) {
configured[$(input).attr('name')] = $(input).prop('checked');
});
this.model.set(this.options.propertyName, configured);
},
load: function load() {
if (!this.isClosed) {
_.each(this.options.values, function (value) {
this.ui.container.find('input[name="' + value + '"]').prop('checked', this.model.get(this.options.propertyName)[value]);
}, this);
}
}
});
function template$5(data) {
var __t, __p = '';
__p += '\n\n ' +
((__t = ( I18n.t('pageflow.ui.templates.inputs.url_display.link_text') )) == null ? '' : __t) +
'\n\n';
return __p
}
/**
* Display view for a link to a URL, to be used like an input view.
* See {@link inputView} for further options
*
* @param {Object} [options]
*
* @param {string} [options.propertyName]
* Target URL for link
*
* @class
*/
var UrlDisplayView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$5,
ui: {
link: 'a'
},
modelEvents: {
'change': 'update'
},
events: {
'click a': function clickA(event) {
// Ensure default is not prevented by parent event listener.
event.stopPropagation();
}
},
onRender: function onRender() {
this.update();
},
update: function update() {
var url = this.model.get('original_url');
this.$el.toggle(this.model.isUploaded() && !_.isEmpty(url));
this.ui.link.attr('href', url);
}
});
/**
* Text based input view that can display a placeholder.
*
* @param {Object} [options]
*
* @param {string|function} [options.placeholder]
* Display a placeholder string if the input is blank. Either a
* string or a function taking the model as a first parameter and
* returning a string.
*
* @param {string} [options.placeholderBinding]
* Name of an attribute. Recompute the placeholder function whenever
* this attribute changes.
*
* @param {boolean} [options.hidePlaceholderIfDisabled]
* Do not display the placeholder if the input is disabled.
*
* @param {Backbone.Model} [options.placeholderModel]
* Obtain placeholder by looking up the configured `propertyName`
* inside a given model.
*/
var inputWithPlaceholderText = {
onRender: function onRender() {
this.updatePlaceholder();
if (this.options.placeholderBinding) {
this.listenTo(this.model, 'change:' + this.options.placeholderBinding, this.updatePlaceholder);
}
},
updateDisabled: function updateDisabled() {
this.updatePlaceholder();
},
updatePlaceholder: function updatePlaceholder() {
this.ui.input.attr('placeholder', this.placeholderText());
},
placeholderText: function placeholderText() {
if (!this.isDisabled() || !this.options.hidePlaceholderIfDisabled) {
if (this.options.placeholder) {
if (typeof this.options.placeholder == 'function') {
return this.options.placeholder(this.model);
} else {
return this.options.placeholder;
}
} else {
return this.placeholderModelValue();
}
}
return '';
},
placeholderModelValue: function placeholderModelValue() {
return this.options.placeholderModel && this.options.placeholderModel.get(this.options.propertyName);
}
};
function template$6(data) {
var __p = '';
__p += '\n\n';
return __p
}
/**
* Input view for a single line of text.
*
* See {@link inputWithPlaceholderText} for placeholder related
* further options. See {@link inputView} for further options.
*
* @param {Object} [options]
*
* @param {boolean} [options.required=false]
* Display an error if the input is blank.
*
* @param {number} [options.maxLength=255]
* Maximum length of characters for this input. To support legacy
* data which consists of more characters than the specified
* maxLength, the option will only take effect for data which is
* shorter than the specified maxLength.
*
* @class
*/
var TextInputView = Marionette.ItemView.extend({
mixins: [inputView, inputWithPlaceholderText],
template: template$6,
ui: {
input: 'input'
},
events: {
'change': 'onChange'
},
onRender: function onRender() {
this.load();
this.validate();
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
},
onChange: function onChange() {
if (this.validate()) {
this.save();
}
},
onClose: function onClose() {
if (this.validate()) {
this.save();
}
},
save: function save() {
this.model.set(this.options.propertyName, this.ui.input.val());
},
load: function load() {
var input = this.ui.input;
input.val(this.model.get(this.options.propertyName)); // set mysql varchar length as default for non-legacy data
this.options.maxLength = this.options.maxLength || 255; // do not validate legacy data which length exceeds the specified maximum
// for new and maxLength-conforming data: add validation
this.validateMaxLength = input.val().length <= this.options.maxLength;
},
validate: function validate() {
var input = this.ui.input;
if (this.options.required && !input.val()) {
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.required_field'));
return false;
}
if (this.validateMaxLength && input.val().length > this.options.maxLength) {
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.max_characters_exceeded', {
max_length: this.options.maxLength
}));
return false;
} else {
this.resetValidationError();
return true;
}
},
displayValidationError: function displayValidationError(message) {
this.$el.addClass('invalid');
this.ui.input.attr('title', message);
},
resetValidationError: function resetValidationError(message) {
this.$el.removeClass('invalid');
this.ui.input.attr('title', '');
}
});
/**
* Input view for a color value in hex representation.
* See {@link inputView} for further options
*
* @param {Object} [options]
*
* @param {string|function} [options.defaultValue]
* Color value to display by default. The corresponding value is not
* stored in the model. Selecting the default value when a different
* value was set before, unsets the attribute in the model.
*
* @param {string} [options.defaultValueBinding]
* Name of an attribute the default value depends on. If a function
* is used as defaultValue option, it will be passed the value of the
* defaultValueBinding attribute each time it changes. If no
* defaultValue option is set, the value of the defaultValueBinding
* attribute will be used as default value.
*
* @param {string[]} [options.swatches]
* Preset color values to be displayed inside the picker drop
* down. The default value, if present, is always used as the
* first swatch automatically.
*
* @class
*/
var ColorInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$6,
className: 'color_input',
ui: {
input: 'input'
},
events: {
'mousedown': 'refreshPicker'
},
onRender: function onRender() {
this.ui.input.minicolors({
changeDelay: 200,
change: _.bind(function (color) {
if (color === this.defaultValue()) {
this.model.unset(this.options.propertyName);
} else {
this.model.set(this.options.propertyName, color);
}
}, this)
});
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
if (this.options.defaultValueBinding) {
this.listenTo(this.model, 'change:' + this.options.defaultValueBinding, this.updateSettings);
}
this.updateSettings();
},
updateSettings: function updateSettings() {
this.resetSwatchesInStoredSettings();
this.ui.input.minicolors('settings', {
defaultValue: this.defaultValue(),
swatches: this.getSwatches()
});
this.load();
},
// see https://github.com/claviska/jquery-minicolors/issues/287
resetSwatchesInStoredSettings: function resetSwatchesInStoredSettings() {
var settings = this.ui.input.data('minicolors-settings');
if (settings) {
delete settings.swatches;
this.ui.input.data('minicolors-settings', settings);
}
},
load: function load() {
this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
},
refreshPicker: function refreshPicker() {
this.ui.input.minicolors('value', {});
},
getSwatches: function getSwatches() {
return _.chain([this.defaultValue(), this.options.swatches]).flatten().uniq().compact().value();
},
defaultValue: function defaultValue() {
var bindingValue;
if (this.options.defaultValueBinding) {
bindingValue = this.model.get(this.options.defaultValueBinding);
}
if (typeof this.options.defaultValue === 'function') {
return this.options.defaultValue(bindingValue);
} else if ('defaultValue' in this.options) {
return this.options.defaultValue;
} else {
return bindingValue;
}
}
});
function template$7(data) {
var __p = '';
__p += '\n';
return __p
}
/**
* A drop down with support for grouped items.
* See {@link inputView} for further options
*
* @param {Object} [options]
*
* @param {string[]} [options.values]
* List of possible values to persist in the attribute.
*
* @param {string[]} [options.texts]
* List of display texts for drop down items.
*
* @param {string[]} [options.translationKeys]
* Translation keys to obtain item texts from.
*
* @param {string[]} [options.translationKeyPrefix]
* Obtain texts for items from translations by appending the item
* value to this prefix separated by a dot. By default the
* [`attributeTranslationKeyPrefixes` option]{@link inputView}
* is used by appending the suffix `.values` to each candidate.
*
* @param {string[]} [options.groups]
* Array of same length as `values` array, containing the display
* name of a group header each item shall be grouped under.
*
* @param {Backbone.Model[]} [options.collection]
* Create items for each model in the collection. Use the
* `*Property` options to extract values and texts for each items
* from the models.
*
* @param {string} [options.valueProperty]
* Attribute to use as item value.
*
* @param {string} [options.textProperty]
* Attribute to use as item display text.
*
* @param {string} [options.groupProperty]
* Attribute to use as item group name.
*
* @param {string} [options.translationKeyProperty]
* Attribute to use as translation key to obtain display text.
*
* @param {string} [options.groupTranslationKeyProperty]
* Attribute to use as translation key to obtain group name.
*
* @param {boolean} [options.ensureValueDefined]
* Set the attribute to the first value on view creation.
*
* @param {boolean} [options.includeBlank]
* Include an item that sets the value of the attribute to a blank
* string.
*
* @param {string} [options.blankText]
* Display text for the blank item.
*
* @param {string} [options.blankTranslationKey]
* Translation key to obtain display text for blank item.
*
* @param {string} [options.placeholderValue]
* Include an item that sets the value of the attribute to a blank
* string and indicate that the attribute is set to a default
* value. Include the display name of the given value, in the
* text. This option can be used if a fallback to the
* `placeholderValue` occurs whenever the attribute is blank.
*
* @param {Backbone.Model} [options.placeholderModel]
* Behaves like `placeholderValue`, but obtains the value by looking
* up the `propertyName` attribute inside the given model. This
* option can be used if a fallback to the corresponding attribute
* value of the `placeholderModel` occurs whenever the attribute is
* blank.
*
* @param {function} [options.optionDisabled]
* Receives value and has to return boolean indicating whether
* option is disabled.
*
* @class
*/
var SelectInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$7,
events: {
'change': 'save'
},
ui: {
select: 'select',
input: 'select'
},
initialize: function initialize() {
if (this.options.collection) {
this.options.values = _.pluck(this.options.collection, this.options.valueProperty);
if (this.options.textProperty) {
this.options.texts = _.pluck(this.options.collection, this.options.textProperty);
} else if (this.options.translationKeyProperty) {
this.options.translationKeys = _.pluck(this.options.collection, this.options.translationKeyProperty);
}
if (this.options.groupProperty) {
this.options.groups = _.pluck(this.options.collection, this.options.groupProperty);
} else if (this.options.groupTranslationKeyProperty) {
this.options.groupTanslationKeys = _.pluck(this.options.collection, this.options.groupTranslationKeyProperty);
}
}
if (!this.options.texts) {
if (!this.options.translationKeys) {
var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
fallbackPrefix: 'activerecord.values'
}));
this.options.translationKeys = _.map(this.options.values, function (value) {
return translationKeyPrefix + '.' + value;
}, this);
}
this.options.texts = _.map(this.options.translationKeys, function (key) {
return I18n$1.t(key);
});
}
if (!this.options.groups) {
this.options.groups = _.map(this.options.groupTanslationKeys, function (key) {
return I18n$1.t(key);
});
}
this.optGroups = {};
},
onRender: function onRender() {
this.appendBlank();
this.appendPlaceholder();
this.appendOptions();
this.load();
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
if (this.options.ensureValueDefined && !this.model.has(this.options.propertyName)) {
this.save();
}
},
appendBlank: function appendBlank() {
if (!this.options.includeBlank) {
return;
}
if (this.options.blankTranslationKey) {
this.options.blankText = I18n$1.t(this.options.blankTranslationKey);
}
var option = document.createElement('option');
option.value = '';
option.text = this.options.blankText || I18n$1.t('pageflow.ui.views.inputs.select_input_view.none');
this.ui.select.append(option);
},
appendPlaceholder: function appendPlaceholder() {
if (!this.options.placeholderModel && !this.options.placeholderValue) {
return;
}
var placeholderValue = this.options.placeholderValue || this.options.placeholderModel.get(this.options.propertyName);
var placeholderIndex = this.options.values.indexOf(placeholderValue);
if (placeholderIndex >= 0) {
var option = document.createElement('option');
option.value = '';
option.text = I18n$1.t('pageflow.ui.views.inputs.select_input_view.placeholder', {
text: this.options.texts[placeholderIndex]
});
this.ui.select.append(option);
}
},
appendOptions: function appendOptions() {
_.each(this.options.values, function (value, index) {
var option = document.createElement('option');
var group = this.options.groups[index];
option.value = value;
option.text = this.options.texts[index];
if (this.options.optionDisabled && this.options.optionDisabled(value)) {
option.setAttribute('disabled', true);
}
if (group) {
option.setAttribute('data-group', group);
this.findOrCreateOptGroup(group).append(option);
} else {
this.ui.select.append(option);
}
}, this);
},
findOrCreateOptGroup: function findOrCreateOptGroup(label) {
if (!this.optGroups[label]) {
this.optGroups[label] = $('', {
label: label
}).appendTo(this.ui.select);
}
return this.optGroups[label];
},
save: function save() {
this.model.set(this.options.propertyName, this.ui.select.val());
},
load: function load() {
if (!this.isClosed) {
var value = this.model.get(this.options.propertyName);
if (this.model.has(this.options.propertyName) && this.ui.select.find('option[value="' + value + '"]:not([disabled])').length) {
this.ui.select.val(value);
} else {
this.ui.select.val(this.ui.select.find('option:not([disabled]):first').val());
}
}
}
});
var ExtendedSelectInputView = SelectInputView.extend({
className: 'extended_select_input',
initialize: function initialize() {
SelectInputView.prototype.initialize.apply(this, arguments);
if (this.options.collection) {
if (this.options.descriptionProperty) {
this.options.descriptions = _.pluck(this.options.collection, this.options.descriptionProperty);
} else if (this.options.descriptionTranslationKeyProperty) {
this.options.descriptionTanslationKeys = _.pluck(this.options.collection, this.options.descriptionTranslationKeyProperty);
}
}
if (!this.options.descriptions) {
this.options.descriptions = _.map(this.options.descriptionTanslationKeys, function (key) {
return I18n$1.t(key);
});
}
},
onRender: function onRender() {
var view = this,
options = this.options;
SelectInputView.prototype.onRender.apply(this, arguments);
$.widget("custom.extendedselectmenu", $.ui.selectmenu, {
_renderItem: function _renderItem(ul, item) {
var widget = this;
var li = $('
', {
"class": item.value
});
var container = $('
', {
"class": 'text-container'
}).appendTo(li);
var index = options.values.indexOf(item.value);
if (item.disabled) {
li.addClass('ui-state-disabled');
}
if (options.pictogramClass) {
$('', {
"class": options.pictogramClass
}).prependTo(li);
}
$('