/*
* Copyright (C) eZ Systems AS. All rights reserved.
* For full copyright and license information view LICENSE file distributed with this source code.
*/
YUI.add('ez-contenttypeeditserversideview', function (Y) {
"use strict";
/**
* Provides the content type edit server side view
*
* @module ez-contenttypeeditserversideview
*/
Y.namespace('eZ');
var events = {
'.ez-relation-pick-root-button': {
'tap': '_pickRoot'
},
'.ezselection-settings-option-add': {
'tap': '_addSelectionOption',
'keydown': '_addSelectionOption',
},
'.ezselection-settings-option-remove': {
'tap': '_removeSelectionOptions',
'keydown': '_removeSelectionOptions',
},
},
SELECTION_PROTOTYPE_CLASS = 'ezselection-settings-option-value-prototype',
PROTOTYPE_PLACEHOLDER = /__number__/g,
SPACE = 32, RETURN = 13;
/**
* The content type edit server side view.
*
* @namespace eZ
* @class ContentTypeEditServerSideView
* @constructor
* @extends eZ.ServerSideView
*/
Y.eZ.ContentTypeEditServerSideView = Y.Base.create('contentTypeEditServerSideView', Y.eZ.ServerSideView, [], {
initializer: function () {
this.containerTemplate = '<div class="ez-view-serversideview ez-view-contenttypeeditserversideview"/>';
this._addDOMEventHandlers(events);
},
/**
* Returns the Selection settings block for the given node.
*
* @method _getSelectionSettings
* @private
* @return {Node}
*/
_getSelectionSettings: function (node) {
return node.ancestor('.ezselection-settings');
},
/**
* Returns the node used as a *prototype* ie it contains a template for
* new Selection options.
*
* @method _getSelectionOptionPrototype
* @private
* @param {Node} settingsNode
* @return {Node}
*/
_getSelectionOptionPrototype: function (settingsNode) {
return settingsNode.one('.' + SELECTION_PROTOTYPE_CLASS);
},
/**
* Creates a new option node for the given Selection settings block.
*
* @method _createNewOptionNode
* @private
* @param {Node} settingsNode
* @return {Node}
*/
_createNewOptionNode: function (settingsNode) {
var newOptionTpl = this._getSelectionOptionPrototype(settingsNode).get('text'),
newOption;
newOption = Y.Node.create(newOptionTpl);
newOption.removeClass(SELECTION_PROTOTYPE_CLASS);
return newOption;
},
/**
* Checks if the event is a tap or a validate event e.g. the user hits
* enter or space on the button.
*
* @method _isTapOrValidateEvent
* @param {EventFacade} e
* @private
* @return {Boolean}
*/
_isTapOrValidateEvent: function (e) {
return ( !e.keyCode || e.keyCode === SPACE || e.keyCode === RETURN );
},
/**
* Reindexes Selection options in settingsNode. That way no matter how
* the user manipulates the option list, we make sure the options are
* indexed from 1 to n without gap.
*
* @method _reindexSelectionOptions
* @protected
* @param {Node} settingsNode
*/
_reindexSelectionOptions: function (settingsNode) {
var tplNode = this._getSelectionOptionPrototype(settingsNode),
inputIdTpl = tplNode.getData('ezselection-option-input-id'),
inputNameTpl = tplNode.getData('ezselection-option-input-name');
settingsNode.all('.ezselection-settings-option-value input[type=text]').each(function (input, i) {
input.set('name', inputNameTpl.replace(PROTOTYPE_PLACEHOLDER, i+1));
input.set('id', inputIdTpl.replace(PROTOTYPE_PLACEHOLDER, i+1));
});
},
/**
* `tap` event handler on the add option button for Selection settings.
* It creates a new option for the Selection based on a prototype
* generated by Repository Form.
*
* @method _addSelectionOption
* @protected
* @param {EventFacade} e
*/
_addSelectionOption: function (e) {
var settingsNode = this._getSelectionSettings(e.target),
options = settingsNode.one('.ezselection-settings-option-list');
if ( this._isTapOrValidateEvent(e) ) {
e.preventDefault();
options.append(this._createNewOptionNode(settingsNode));
this._reindexSelectionOptions(settingsNode);
this._focusLastSelectionOptionInput(settingsNode);
}
},
/**
* Gives the focus to the last Selection option input text
*
* @method _focusLastSelectionOptionInput
* @protected
* @param {Node} settingsNode
*/
_focusLastSelectionOptionInput: function (settingsNode) {
settingsNode.one('.ezselection-settings-option-value:last-of-type input[type=text]').focus();
},
/**
* `tap` event handler on the remove option button for Selection
* settings. It removes the checked options from the DOM.
*
* @method _removeSelectionOptions
* @protected
* @param {EventFacade} e
*/
_removeSelectionOptions: function (e) {
var settingsNode = this._getSelectionSettings(e.target),
selected = settingsNode.all('.ezselection-settings-option-checkbox:checked');
if ( this._isTapOrValidateEvent(e) ) {
e.preventDefault();
selected.each(function (checkbox) {
checkbox.ancestor('.ezselection-settings-option-value').remove(true);
});
this._reindexSelectionOptions(settingsNode);
this._uiEnableButtons(e.target);
}
},
/**
* tap event handler on the root item selection buttons. It launches the
* universal discovery widget so that the user can pick a content.
*
* @method _pickRoot
* @protected
* @param {EventFacade} e
*/
_pickRoot: function (e) {
var button = e.target;
e.preventDefault();
this.fire('contentDiscover', {
config: {
title: button.getAttribute('data-universaldiscovery-title'),
contentDiscoveredHandler: Y.bind(this._setRoot, this, button),
multiple: false
},
});
},
/**
* Puts picked location id into root selection input. Input is selected by selector
* provided in `data-relation-root-input-selector` attribute of button, for example
* <button data-relation-root-input-selector="#id_of_input"></button>
*
* @method _setRoot
* @protected
* @param {Y.Node} button
* @param {EventFacade} e
*/
_setRoot: function (button, e) {
var selectionRootInput = this.get('container').one(button.getAttribute('data-relation-root-input-selector')),
selectedRootName = this.get('container').one(button.getAttribute('data-relation-selected-root-name-selector'));
selectionRootInput.setAttribute('value', e.selection.location.get('locationId'));
selectedRootName.setHTML(e.selection.contentInfo.get('name'));
},
});
});