Show:
                            /**
                             * The Form Builder Field Base Component
                             *
                             * @module aui-form-builder
                             * @submodule aui-form-builder-field-base
                             */
                            
                            var CSS_FIELD = A.getClassName('form', 'builder', 'field'),
                                CSS_FIELD_CONTENT = A.getClassName('form', 'builder', 'field', 'content'),
                                CSS_FIELD_CONTENT_FOOTER = A.getClassName('form', 'builder', 'field', 'content', 'footer'),
                                CSS_FIELD_CONTENT_TOOLBAR = A.getClassName('form', 'builder', 'field', 'content', 'toolbar'),
                                CSS_FIELD_FOOTER_CONTENT = A.getClassName('form', 'builder', 'field', 'footer', 'content'),
                                CSS_FIELD_MOVE_BUTTON = A.getClassName('form', 'builder', 'field', 'move', 'button'),
                                CSS_FIELD_MOVE_TARGET = A.getClassName('form', 'builder', 'field', 'move', 'target'),
                                CSS_FIELD_MOVE_TARGET_LABEL = A.getClassName('form', 'builder', 'field', 'move', 'target', 'label'),
                                CSS_FIELD_NESTED = A.getClassName('form', 'builder', 'field', 'nested'),
                                CSS_FIELD_OVERLAY = A.getClassName('form', 'builder', 'field', 'overlay'),
                                CSS_FIELD_SETTINGS_PANEL = A.getClassName('form', 'builder', 'field', 'settings', 'panel'),
                                CSS_FIELD_SETTINGS_PANEL_ADVANCED = A.getClassName('form', 'builder', 'field', 'settings', 'panel', 'advanced'),
                                CSS_FIELD_SETTINGS_PANEL_ADVANCED_CONTENT =
                                    A.getClassName('form', 'builder', 'field', 'settings', 'panel', 'advanced', 'content'),
                                CSS_FIELD_SETTINGS_PANEL_CONTENT = A.getClassName('form', 'builder', 'field', 'settings', 'panel', 'content'),
                                CSS_FIELD_SETTINGS_PANEL_TOGGLER_ADVANCED =
                                    A.getClassName('form', 'builder', 'field', 'settings', 'panel', 'toggler', 'advanced'),
                                CSS_FIELD_TOOLBAR_CONTAINER = A.getClassName('form', 'builder', 'field', 'toolbar', 'container'),
                                CSS_HIDE = A.getClassName('hide');
                            
                            /**
                             * Fired when toggle the modal content.
                             *
                             * @event contentToggle
                             */
                            
                            /**
                             * An augmentation class which adds some editing funcionality to form builder
                             * fields.
                             *
                             * @class A.FormBuilderFieldBase
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            A.FormBuilderFieldBase = function() {};
                            
                            A.FormBuilderFieldBase.prototype = {
                                TPL_FIELD: '<div class="' + CSS_FIELD + ' form-field">' +
                                    '<div class="' + CSS_FIELD_CONTENT_TOOLBAR + '">' +
                                    '<div class="' + CSS_FIELD_CONTENT + ' form-field-content"></div>' +
                                    '<div class="' + CSS_FIELD_MOVE_BUTTON + ' layout-builder-move-cut-button"></div>' +
                                    '<div class="' + CSS_FIELD_TOOLBAR_CONTAINER + '"></div></div>' +
                                    '<div class="' + CSS_FIELD_NESTED + ' form-field-nested"></div>' +
                                    '<div class="' + CSS_FIELD_OVERLAY + '"></div>' +
                                    '<div class="' + CSS_FIELD_CONTENT_FOOTER + '"></div>' +
                                    '</div>',
                                TPL_FIELD_MOVE_TARGET: '<button type="button" class="' + CSS_FIELD_MOVE_TARGET +
                                    ' layout-builder-move-target layout-builder-move-col-target">' +
                                    ' <label class="' + CSS_FIELD_MOVE_TARGET_LABEL + '">{subquestion}</label></button>',
                                TPL_FIELD_SETTINGS_PANEL: '<div class="' + CSS_FIELD_SETTINGS_PANEL + ' clearfix">' +
                                    '<div class="' + CSS_FIELD_SETTINGS_PANEL_CONTENT + '">' +
                                    '</div>' +
                                    '<div class="' + CSS_FIELD_SETTINGS_PANEL_ADVANCED + '">' +
                                    '<a class="' + CSS_FIELD_SETTINGS_PANEL_TOGGLER_ADVANCED +
                                    '" href="javascript:void(0)">{advancedOptions}</a>' +
                                    '<div class="' + CSS_FIELD_SETTINGS_PANEL_ADVANCED_CONTENT + '"></div>' +
                                    '</div>' +
                                    '</div>',
                                TPL_FIELD_FOOTER_CONTENT: '<div class="' + CSS_FIELD_FOOTER_CONTENT + '"></div>',
                            
                                /**
                                 * Constructor for the `A.FormBuilderFieldBase` component. Lifecycle.
                                 *
                                 * @method initializer
                                 * @protected
                                 */
                                initializer: function() {
                                    var advancedSettings,
                                        i;
                            
                                    this._fieldSettingsPanel = A.Node.create(A.Lang.sub(this.TPL_FIELD_SETTINGS_PANEL, {
                                        advancedOptions: this.get('strings').advancedOptions
                                    }));
                            
                                    advancedSettings = this._getAdvancedSettings();
                            
                                    for (i = 0; i < advancedSettings.length; i++) {
                                        if (advancedSettings[i].footerLabel) {
                                            this.after(advancedSettings[i].attrName + 'Change', this._afterAdvancedSettingsChange);
                                        }
                                    }
                            
                                    this._updateAdvancedSettingsChange();
                                },
                            
                                /**
                                 * Collapse Advanced Settings Content.
                                 *
                                 * @method collapseModalContent
                                 */
                                collapseModalContent: function() {
                                    this._advancedSettingsToggler.set('expanded', false);
                                },
                            
                                /**
                                 * Renders the advanced settings on panel.
                                 *
                                 * @method renderAdvancedSettings
                                 */
                                renderAdvancedSettings: function() {
                                    var advancedSettings = this._getAdvancedSettings(),
                                        currentNode,
                                        i;
                            
                                    if (advancedSettings.length) {
                                        currentNode = this._fieldSettingsPanel.one('.' + CSS_FIELD_SETTINGS_PANEL_ADVANCED_CONTENT);
                            
                                        for (i = 0; i < advancedSettings.length; i++) {
                                            this.renderSetting(advancedSettings[i], currentNode);
                                        }
                                    }
                                    else {
                                        this._fieldSettingsPanel.one('.' + CSS_FIELD_SETTINGS_PANEL_ADVANCED).addClass(CSS_HIDE);
                                    }
                                },
                            
                                /**
                                 * Renders the basic settings on panel.
                                 *
                                 * @method renderBasicSettings
                                 */
                                renderBasicSettings: function() {
                                    var currentNode = this._fieldSettingsPanel.one('.' + CSS_FIELD_SETTINGS_PANEL_CONTENT),
                                        i,
                                        settings = this._getSettings();
                            
                                    for (i = 0; i < settings.length; i++) {
                                        this.renderSetting(settings[i], currentNode);
                                    }
                                },
                            
                                /**
                                 * Renders a single field setting to be edited.
                                 *
                                 * @method renderSetting
                                 * @param {Object} setting
                                 * @param {Node} targetNode
                                 * @protected
                                 */
                                renderSetting: function(setting, targetNode) {
                                    var attrValue = this.get(setting.attrName);
                            
                                    setting.editor.get('node').removeClass('has-error');
                                    setting.editor.set('originalValue', attrValue);
                                    setting.editor.set('editedValue', attrValue);
                                    targetNode.append(setting.editor.get('node'));
                                },
                            
                                /**
                                 * Renders the settings panel.
                                 *
                                 * @method renderSettingsPanel
                                 * @param {Node} container The container where the panel should be rendered.
                                 */
                                renderSettingsPanel: function(container) {
                                    this.renderBasicSettings();
                            
                                    this.renderAdvancedSettings();
                            
                                    container.setHTML(this._fieldSettingsPanel);
                            
                                    if (!this._advancedSettingsToggler) {
                                        this._createAdvancedSettingsToggler();
                                    }
                                },
                            
                                /**
                                 * Saves the edited settings.
                                 *
                                 * @method saveSettings
                                 */
                                saveSettings: function() {
                                    var advancedSettings = this._getAdvancedSettings(),
                                        i,
                                        settings = this._getSettings();
                            
                                    for (i = 0; i < settings.length; i++) {
                                        this.set(settings[i].attrName, settings[i].editor.get('editedValue'));
                                    }
                            
                                    for (i = 0; i < advancedSettings.length; i++) {
                                        this.set(advancedSettings[i].attrName, advancedSettings[i].editor.get('editedValue'));
                                    }
                                },
                            
                                /**
                                 * Validates all data editors used by this field's settings.
                                 *
                                 * @method validateSettings
                                 * @return {Boolean}
                                 */
                                validateSettings: function() {
                                    var i,
                                        result = true,
                                        settings = this._getSettings();
                            
                                    for (i = 0; i < settings.length; i++) {
                                        if (!settings[i].editor.isValid()) {
                                            settings[i].editor.get('node').addClass('has-error');
                                            result = false;
                                        }
                                    }
                            
                                    return result;
                                },
                            
                                /**
                                 * Fired after the a advanced settings change.
                                 *
                                 * @method _afterAdvancedSettingsChange
                                 * @protected
                                 */
                                _afterAdvancedSettingsChange: function() {
                                    this._updateAdvancedSettingsChange();
                                },
                            
                                /**
                                 * Fired after the a Toggler of Advanced Settings change.
                                 *
                                 * @method _afterExpandedChange
                                 * @param {EventFacade} event
                                 * @protected
                                 */
                                _afterExpandedChange: function(event) {
                                    this._toggleVisibilityOfModalContent(event.newVal);
                                },
                            
                                /**
                                 * Create a Toggler with the advanced settings.
                                 *
                                 * @method _createAdvancedSettingsToggler
                                 * @protected
                                 */
                                _createAdvancedSettingsToggler: function() {
                                    this._advancedSettingsToggler = new A.Toggler({
                                        animated: true,
                                        content: '.' + CSS_FIELD_SETTINGS_PANEL_ADVANCED_CONTENT,
                                        header: '.' + CSS_FIELD_SETTINGS_PANEL_TOGGLER_ADVANCED,
                                        expanded: this.get('content').one('.' + CSS_FIELD_CONTENT_FOOTER).hasChildNodes(),
                                        toggleEvent: 'click'
                                    });
                            
                                    this._advancedSettingsToggler.after('expandedChange', A.bind(this._afterExpandedChange, this));
                                },
                            
                                /**
                                 * Creates a move target node.
                                 *
                                 * @method _createMoveTarget
                                 * @param {Number} position The position where the moved field will be added
                                 *   if this is the chosen target.
                                 * @return {Node}
                                 * @protected
                                 */
                                _createMoveTarget: function(position) {
                                    var targetNode;
                            
                                    targetNode = A.Node.create(A.Lang.sub(this.TPL_FIELD_MOVE_TARGET, {
                                        subquestion: this.get('strings').subquestion
                                    }));
                            
                                    targetNode.setData('nested-field-index', position);
                                    targetNode.setData('nested-field-parent', this);
                            
                                    return targetNode;
                                },
                            
                                /**
                                 * Gets the list of advanced settings for this field.
                                 *
                                 * @method _getAdvancedSettings
                                 * @return {Array}
                                 * @protected
                                 */
                                _getAdvancedSettings: function() {
                                    if (!this._advancedSettings) {
                                        this._advancedSettings = [];
                            
                                        if (this._fillAdvancedSettings) {
                                            this._fillAdvancedSettings();
                                        }
                                    }
                            
                                    return this._advancedSettings;
                                },
                            
                                /**
                                 * Gets the list of settings for this field. Safer then calling the property
                                 * directly, as this will lazy load the settings if they're not ready yet.
                                 * Each setting should be an object with the following keys: attrName and
                                 * editor.
                                 *
                                 * @method _getSettings
                                 * @return {Array}
                                 * @protected
                                 */
                                _getSettings: function() {
                                    if (!this._settings) {
                                        this._settings = [
                                            {
                                                attrName: 'title',
                                                editor: new A.TextDataEditor({
                                                    label: 'Question',
                                                    placeholder: 'Type your question here',
                                                    required: true
                                                })
                                            },
                                            {
                                                attrName: 'help',
                                                editor: new A.TextDataEditor({
                                                    label: 'Help text'
                                                })
                                            }
                                        ];
                            
                                        if (this._fillSettings) {
                                            this._fillSettings();
                                        }
                                    }
                            
                                    return this._settings;
                                },
                            
                                /**
                                 * Updates the UI according to the values of the Advanced Settings.
                                 *
                                 * @method _updateAdvancedSettingsChange
                                 * @protected
                                 */
                                _updateAdvancedSettingsChange: function() {
                                    var advancedSettings = this._getAdvancedSettings(),
                                        footerNode,
                                        i;
                            
                                    this.get('content').one('.' + CSS_FIELD_CONTENT_FOOTER).empty();
                            
                                    for (i = 0; i < advancedSettings.length; i++) {
                                        if (advancedSettings[i].footerLabel && this.get(advancedSettings[i].attrName)) {
                                            footerNode = A.Node.create(this.TPL_FIELD_FOOTER_CONTENT);
                                            footerNode.set('text', advancedSettings[i].footerLabel +
                                                ': ' + this.get(advancedSettings[i].attrName));
                                            this.get('content').one('.' + CSS_FIELD_CONTENT_FOOTER).append(footerNode);
                                        }
                                    }
                                },
                            
                                /**
                                 * Toggle visibility classes on Modal Content.
                                 *
                                 * @method _toggleVisibilityOfModalContent
                                 * @protected
                                 */
                                _toggleVisibilityOfModalContent: function() {
                                    this.fire('contentToggle');
                                },
                            
                                /**
                                 * Updates the UI according to the value of the `nestedFields` attribute.
                                 *
                                 * @method _uiSetNestedFields
                                 * @param  {Array} nestedFields
                                 * @protected
                                 */
                                _uiSetNestedFields: function(nestedFields) {
                                    var instance = this,
                                        nestedFieldsNode = this.get('content').one('.' + CSS_FIELD_NESTED);
                            
                                    nestedFieldsNode.empty();
                                    nestedFieldsNode.append(this._createMoveTarget(0));
                                    A.Array.each(nestedFields, function(nestedField, index) {
                                        nestedFieldsNode.append(nestedField.get('content'));
                                        nestedFieldsNode.append(instance._createMoveTarget(index + 1));
                                    });
                                }
                            };
                            
                            A.FormBuilderFieldBase.ATTRS = {
                            	/**
                                 * Collection of strings used to label elements of the UI.
                                 *
                                 * @attribute strings
                                 * @type {Object}
                                 */
                                strings: {
                                    value: {
                                        advancedOptions: 'Advanced options',
                                        subquestion: 'Paste as subquestion'
                                    },
                                    writeOnce: true
                                }
                            };