/**
* 内部的に使われる{@link Ext.form.field.ComboBox ComboBox}のデータビュー。
*/
Ext.define('Ext.view.BoundList', {
extend: 'Ext.view.View',
alias: 'widget.boundlist',
alternateClassName: 'Ext.BoundList',
requires: ['Ext.layout.component.BoundList', 'Ext.toolbar.Paging'],
mixins: [
'Ext.mixin.Queryable'
],
/**
* @cfg {Number} [pageSize=0]
* `0`より大きい場合には、リストの下部に{@link Ext.toolbar.Paging}が表示され、ストアクエリはページ{@link Ext.data.operation.Read#start start}および{@link Ext.data.operation.Read#limit limit}のパラメータと共に実行されます。
*/
pageSize: 0,
/**
* @cfg {String} [displayField=""]
* ストアからビューに表示するフィールド。
*/
/**
* @property {Ext.toolbar.Paging} pagingToolbar
* このviewのPagingToolbarインスタンスへの参照。設定されるのは、{@link #pageSize}がゼロより大きく、BoundList がレンダリングされている場合だけです。
*/
// private overrides
baseCls: Ext.baseCSSPrefix + 'boundlist',
itemCls: Ext.baseCSSPrefix + 'boundlist-item',
listItemCls: '',
shadow: false,
trackOver: true,
// This flag indicates to any floaters shown above it that they should focus themselves when taking over topmost position.
// ZIndexManager#onCollectionSort decides whether to focus the new front component depending on whether the oldFront
// had focusOnToFront set. Even though this class is in fact not focusable.
//focusOnToFront: true,
preserveScrollOnRefresh: true,
enableInitialSelection: false,
componentLayout: 'boundlist',
navigationModel: 'boundlist',
autoScroll: true,
childEls: [
'listWrap', 'listEl'
],
renderTpl: [
'<div id="{id}-listWrap" data-ref="listWrap" role="presentation" class="{baseCls}-list-ct ', Ext.dom.Element.unselectableCls, '">',
'<ul id="{id}-listEl" data-ref="listEl" class="' + Ext.plainListCls + '">',
'</ul>',
'</div>',
'{%',
'var pagingToolbar=values.$comp.pagingToolbar;',
'if (pagingToolbar) {',
'Ext.DomHelper.generateMarkup(pagingToolbar.getRenderTree(), out);',
'}',
'%}',
{
disableFormats: true
}
],
/**
* @cfg {String/Ext.XTemplate} tpl
* 内部のテンプレートに適用するStringもしくはExt.XTemplateのインスタンス。
*
* {@link Ext.view.BoundList}は、{@link Ext.form.field.ComboBox}のドロップダウンリストに使われます。以下のようにすれば、テンプレートをカスタマイズできます。
*
* Ext.create('Ext.form.field.ComboBox', {
* fieldLabel : 'State',
* queryMode : 'local',
* displayField : 'text',
* valueField : 'abbr',
* store : Ext.create('StateStore', {
* fields : ['abbr', 'text'],
* data : [
* {"abbr":"AL", "name":"Alabama"},
* {"abbr":"AK", "name":"Alaska"},
* {"abbr":"AZ", "name":"Arizona"}
* //...
* ]
* }),
* listConfig : {
* tpl : '<tpl for="."><div class="x-boundlist-item">{abbr}</div></tpl>'
* }
* });
*
* デフォルト値:
*
* Ext.create('Ext.XTemplate',
* '<ul><tpl for=".">',
* '<li role="option" class="' + itemCls + '">' + me.getInnerTpl(me.displayField) + '</li>',
* '</tpl></ul>'
* );
*
*/
focusable: false,
initComponent: function() {
var me = this,
baseCls = me.baseCls,
itemCls = me.itemCls;
me.selectedItemCls = baseCls + '-selected';
if (me.trackOver) {
me.overItemCls = baseCls + '-item-over';
}
me.itemSelector = "." + itemCls;
me.scrollerSelector = 'ul.' + Ext.plainListCls;
if (me.floating) {
me.addCls(baseCls + '-floating');
}
if (!me.tpl) {
// should be setting aria-posinset based on entire set of data
// not filtered set
me.tpl = new Ext.XTemplate(
'<tpl for=".">',
'<li role="option" unselectable="on" class="' + itemCls + '">' + me.getInnerTpl(me.displayField) + '</li>',
'</tpl>'
);
} else if (!me.tpl.isTemplate) {
me.tpl = new Ext.XTemplate(me.tpl);
}
if (me.pageSize) {
me.pagingToolbar = me.createPagingToolbar();
}
me.callParent();
// The dropdown is never focused. Key navigation events flow through the input field.
me.getSelectionModel().preventFocus = true;
},
getRefOwner: function() {
return this.pickerField || this.callParent();
},
getRefItems: function() {
var result = this.callParent(),
toolbar = this.pagingToolbar;
if (toolbar) {
result.push(toolbar);
}
return result;
},
createPagingToolbar: function() {
return Ext.widget('pagingtoolbar', {
id: this.id + '-paging-toolbar',
pageSize: this.pageSize,
store: this.dataSource,
border: false,
ownerCt: this,
ownerLayout: this.getComponentLayout()
});
},
getNodeContainer: function() {
return this.listEl;
},
refresh: function(){
var me = this,
tpl = me.tpl,
toolbar = me.pagingToolbar,
rendered = me.rendered;
// Allow access to the context for XTemplate scriptlets
tpl.field = me.pickerField;
tpl.store = me.store;
me.callParent();
tpl.field = tpl.store = null;
// The view removes the targetEl from the DOM before updating the template
// Ensure the toolbar goes to the end
if (rendered && toolbar && toolbar.rendered && !me.preserveScrollOnRefresh) {
me.el.appendChild(toolbar.el, true);
}
},
bindStore : function(store, initial) {
var toolbar = this.pagingToolbar;
this.callParent(arguments);
if (toolbar) {
toolbar.bindStore(store, initial);
}
},
/**
* リスト内のアイテムを表示するために、内部のテンプレートを返すメソッド。このメソッドは、テキストと一緒にアイコンを挿入するなど、より複雑な表示値を使用する場合に上書きするのに便利です。
*
* XTemplateの作成時には、コンテキストへのアクセスを提供するため、`field`プロパティの中の所有するフォームフィールドへの参照を渡します。例えば、現在入力中の値を強調表示するには、ComboBoxの{@link Ext.form.field.ComboBox#listConfig listConfig}の一部としてgetInnerTplを設定します。
*
* listConfig:{ getInnerTpl: function() { return '{[values.name.replace(this.field.getRawValue(), "<b>" + this.field.getRawValue() + "</b>")]}'; } }
* @param {String} displayField BoundListの{@link #displayField}。
* @return {String} 内部テンプレート。
*/
getInnerTpl: function(displayField) {
return '{' + displayField + '}';
},
onDestroy: function() {
this.callParent();
Ext.destroyMembers(this, 'pagingToolbar', 'listWrap', 'listEl');
},
privates: {
getTargetEl: function() {
return this.listEl;
},
getOverflowEl: function() {
return this.listWrap;
},
// Do the job of a container layout at this point even though we are not a Container.
finishRenderChildren: function () {
var toolbar = this.pagingToolbar;
this.callParent(arguments);
if (toolbar) {
toolbar.finishRender();
}
}
}
});