Posted at

ExtJS5 - FieldLabelをResponsiveにするTips

More than 3 years have passed since last update.

この記事はSencha Advent Calendar 2014 11日目の記事です。

ExtJS5にてResponsiveプラグインが導入されました。

このResponsiveを利用してフォームのフィールドラベルの位置を変えてみたい

と思います。


やりたいこと

画面幅が狭ければ、フィールドラベルの位置をTOPに、広ければLEFTにすることで

十分な幅の入力フィールドを保つ。


実装

1 - Formの作成

Ext.define("Adventer.view.form.Form",{

// {{{ extend

extend: "Ext.form.Panel",

// }}}
// {{{ alias

alias: 'widget.form-form',

// }}}
// {{{ controller

controller: "form-form",

// }}}
// {{{ viewmodel

viewModel: {
type: "form-form"
},

// }}}
// {{{ title

title: 'AdventCalendar 2014',

// }}}
// {{{ bodypadding

bodyPadding: 10,

// }}}
// {{{ items

items: [

{
xtype: 'textfield',
fieldLabel: '氏名'
},
{
xtype: 'textfield',
fieldLabel: '電話番号'
}

]

// }}}

});

2 - レスポンシブプラグインを導入

それぞれのfieldにresponsiveプラグインを導入するため、defaults設定を用意しました。


responsiveConfigは、ひとまず縦長であればlabelAlignをtopに、横長であればleftにするように書きました。

    // {{{ defaults

defaults: {
labelWidth: 100,
plugins: 'responsive',
responsiveConfig: {
'tall': {
labelAlign: 'top'
},
'wide': {
labelAlign: 'left'
}
}

},

// }}}
// {{{ items

items: [

{
xtype: 'textfield',
fieldLabel: '氏名'
},
{
xtype: 'textfield',
fieldLabel: '電話番号'
}

]

// }}}

結果

textfieldのlabelAlignにはsetterがないとのことです。

3 - アクセサーメソッドを作成

ないなら作ろうと、アクセサーメソッドを作ります。

    // {{{ defaults

defaults: {
labelWidth: 100,
plugins: 'responsive',
// setter
setLabelAlign: function(align) {
this.labelALign = align;
},
// getter
getLabelAlign: function () {
return this.labelAlign;
},
responsiveConfig: {
'tall': {
labelAlign: 'top'
},
'wide': {
labelAlign: 'left'
}
}

},

// }}}

結果

エラーは出なくなりましたが、表示は変わりませんでした。

4 - CSSでなんとか……

labelのpositionはcssでやっていたので、クラスのつけ替えで対応してみようと思います。

    // {{{ defaults

defaults: {
labelWidth: 100,
plugins: 'responsive',
// setter
setLabelAlign: function(align) {
var me = this,
labelEl = Ext.get(me.labelEl);

me.labelAlign = align;

// ラベルがありません
if (!labelEl) return;

if (align === 'top') {
labelEl.addCls('x-form-item-label-top');
} else {
labelEl.removeCls('x-form-item-label-top');
// left時は幅の設定が必要
labelEl.setWidth(me.labelWidth);
}

},
// getter
getLabelAlign: function () {
return this.labelAlign;
},
responsiveConfig: {
'tall': {
labelAlign: 'top'
},
'wide': {
labelAlign: 'left'
}
}

},

// }}}

無理矢理感が強いですが、なんとかなりました。


responsiveプラグインにより、画面サイズの変更でsetLabelAlignが呼ばれ、

その中でlabelの位置を変更させています。


まとめ


  • Responsiveはアクセサーメソッドがないと使えない

  • アクセサーメソッドを作っても、レイアウトは簡単には変えられない。

もっと上手なやり方がありそうな気もしますが、なんとか目的は果たせました。

明日は sugaimasaruさんです。