define('application/widgets/search/input', [
'application/widgets/search/inputfield',
'rofl/widgets/label',
'rofl/widgets/verticallist',
'application/widgets/search/multikbd',
'application/managers/search',
'application/widgets/search/lastsearched',
'rofl/widgets/horizontallist',
'rofl/lib/l10n',
'application/widgets/pointerfocusablebutton',
'rofl/lib/utils',
'antie/runtimecontext',
'rofl/widgets/container'
], function (
InputField,
Label,
VerticalList,
MultiKeyboard,
SearchManager,
LastSearched,
HorizontalList,
L10N,
PointerFocusableButton,
Utils,
RuntimeContext,
Container
) {
'use strict';
var Input,
searchManager = SearchManager.getInstance(),
application = RuntimeContext.getCurrentApplication(),
configuration = application.getConfiguration(),
searchLayout = application.getLayout().search,
lastSearchedFromRight = searchLayout.lastSearched.fromRight,
GRADIENT_CLASS = 'gradient-visible',
MAX_LAST_SEARCHED_ITEMS = configuration.search.maxLastSearchedItems;
Input = VerticalList.extend({
/**
* Initialises the input widget.
*
* @param {Object} config - The configuration.
* @param {Object} config.inputField - The inputfield options.
* @param {Object} [config.inputField.opts] - The options. Optional.
*/
init: function init (config) {
init.base.call(this);
this.addClass('input-container');
this._build(config);
this.addEventListener('selecteditemchange',
Utils.bind(this.onSelectedItemChange, this));
this.addEventListener('focus', Utils.bind(this.onFocus, this));
},
/**
* Builds the widget.
*
* @param {Object} config - The configuration.
* @param {Object} config.inputField - The inputfield options.
* @param {Object} [config.inputField.opts] - The options. Optional.
* @private
*/
_build: function (config) {
this._buildInputField(config.inputField);
this._buildKeyboard();
this._buildLastSearch();
},
/**
* Builds the input field.
*
* @param {Object} config - The inputfield options.
* @param {Object} [config.opts] - The options. Optional.
* @private
*/
_buildInputField: function (config) {
var inputField = this._inputField = new InputField(config);
this.appendChildWidget(inputField);
},
/**
* Build keyboard widget.
*
* @private
*/
_buildKeyboard: function () {
this._keyboard = new MultiKeyboard();
this._inputField.setKeyboard(this._keyboard);
this.appendChildWidget(this._keyboard);
},
/**
* Builds the last searched items list.
*
* @private
*/
_buildLastSearch: function () {
var searchedItems = searchManager.getLastSearchedItems(),
lastSearchedContainer = this._lastSearchedContainer = new Container('last-searched-container'),
lastSearchedList = this._lastSearchedList = new VerticalList(),
searchedItemsArray,
lastsearched,
i;
lastSearchedList.addClass('last-searched-list');
lastSearchedContainer.addClass('last-searched-container');
if (searchedItems) {
searchedItemsArray = searchedItems.split('~');
searchedItemsArray = searchedItemsArray.reverse();
// Limit the items to show.
searchedItemsArray.splice(MAX_LAST_SEARCHED_ITEMS);
for (i = 0; i < searchedItemsArray.length; i++) {
lastsearched = new LastSearched(searchedItemsArray[i]);
lastSearchedList.appendChildWidget(lastsearched);
}
}
lastSearchedContainer.appendChildWidget(lastSearchedList);
this.appendChildWidget(lastSearchedContainer);
},
/**
* Builds clear button.
*
* @private
*/
_buildClearButton: function () {
var clearButton,
clearLabel;
clearButton = this._clearButton = new PointerFocusableButton('clearbutton');
clearLabel = new Label({ text: '', classNames: ['icon', 'icon-delete-v2'] });
clearButton.addClass('clear-button');
clearButton.appendChildWidget(clearLabel);
},
/**
* Returns value of the input.
*
* @returns {string} - Value of the inupt.
*/
getValue: function () {
return this._inputField.getValue();
},
/**
* Returns inputfield object.
*
* @returns {Object} - Inputfield Object.
*/
getInputField: function () {
return this._inputField;
},
/**
* Focus this widget.
*/
focus: function () {
this._keyboard.focus();
},
/**
* Updates carousel object.
*/
updateLastSearchedList: function () {
var carousel = this._lastSearchedList,
searchedItems = searchManager.getLastSearchedItems(),
searchedItemsArray,
lastsearched,
i;
if (this._canUpdateFocusIndex) {
this._lastFocussedIndex = carousel.getActiveChildWidgetIndex();
this._canUpdateFocusIndex = false;
}
carousel.removeChildWidgets();
if (searchedItems) {
carousel.removeChildWidgets();
searchedItemsArray = searchedItems.split('~');
searchedItemsArray = searchedItemsArray.reverse();
// Limit the items to show.
searchedItemsArray.splice(MAX_LAST_SEARCHED_ITEMS);
for (i = 0; i < searchedItemsArray.length; i++) {
lastsearched = new LastSearched(searchedItemsArray[i]);
carousel.appendChildWidget(lastsearched);
}
}
},
/**
* Returns the keyboard.
*
* @returns {Object} - The keyboard.
*/
getKeyboard: function () {
return this._keyboard;
},
/**
* Reset input widget.
*/
reset: function () {
var keyboard = this._keyboard;
keyboard.reset();
keyboard._keyboard.focus();
if (this._lastSearchedList.getChildWidgetCount()) {
this._lastSearchedList.setActiveChildIndex(0);
}
},
/**
* Gets executed when item is focussed.
*
* @param {Object} e - The event data.
*/
onFocus: function (e) {
var target = e.target;
if (target.hasClass('last-searched')) {
this._lastIndex = target.parentWidget._selectedIndex;
}
},
/**
* Gets clear button.
*
* @returns {Object} Clear button.
*/
getClearButton: function () {
return this._clearButton;
},
/**
* Gets executed when the selected item changes.
*
* @param {Object} e - The event data.
*/
onSelectedItemChange: function (e) {
var item = e.item,
lastFocussedIndex = this._lastFocussedIndex || 0;
if (item.hasClass('top-list') && item.hasClass('focus')) {
this._lastSearchedList.getChildWidgetByIndex(lastFocussedIndex).focus();
this._canUpdateFocusIndex = true;
} else if (item.hasClass('last-searched')) {
this._positionLastSearched(item, e.index);
}
},
/**
* Positions the last searched row.
*
* @param {Object} element - The element.
* @param {number} index - The element index.
* @private
*/
_positionLastSearched: function (element, index) {
var position = this._getNewElementPosition(element),
lastSearchedContainer = this._lastSearchedContainer;
if (position) {
this._lastSearchedList.setStyleTo('left', position + 'px');
if (index === 0) {
lastSearchedContainer.removeClass(GRADIENT_CLASS);
} else {
if (!lastSearchedContainer.hasClass(GRADIENT_CLASS)) {
lastSearchedContainer.addClass(GRADIENT_CLASS);
}
}
}
},
/**
* Returns the new element position.
*
* @param {Object} element - The element to get the position for.
* @returns {number|null} - The new position or null.
* @private
*/
_getNewElementPosition: function (element) {
var listElement = this._lastSearchedList.outputElement,
currentPosition = parseInt((listElement.style.left || '0').replace('px', '')),
containerPosition = this._lastSearchedContainer.outputElement.getBoundingClientRect(),
position,
newPosition,
positionDifference;
if (!element.outputElement) {
return null;
}
position = element.outputElement.getBoundingClientRect();
if (position.right >= lastSearchedFromRight) {
// Row should move left.
positionDifference = position.right - lastSearchedFromRight;
newPosition = currentPosition - positionDifference;
return newPosition;
} else if (position.left < containerPosition.left) {
// Row should move right.
positionDifference = containerPosition.left - position.left;
newPosition = currentPosition + positionDifference;
return newPosition;
}
// Row should not move.
return null;
}
});
return Input;
});