ExtJS5 - FieldLabelをResponsiveにするTips

この記事は[Sencha Advent Calendar 2014](http://www.adventar.org/calendars/490) 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: '電話番号'
            }


        ]

        // }}}


    });


![スクリーンショット 2014-12-11 12.39.01.png](https://qiita-image-store.s3.amazonaws.com/0/30646/a3ff6672-94cd-8f03-f7e3-f677b754aade.png "スクリーンショット 2014-12-11 12.39.01.png")

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: '電話番号'
            }


        ]

        // }}}

結果

![スクリーンショット 2014-12-11 12.51.56.png](https://qiita-image-store.s3.amazonaws.com/0/30646/a0d2c867-c7c0-8835-fe46-c248f11a6589.png "スクリーンショット 2014-12-11 12.51.56.png")

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'
                }
            }

        },

        // }}}

結果
![スクリーンショット 2014-12-11 12.57.42.png](https://qiita-image-store.s3.amazonaws.com/0/30646/6ab2854c-f9d8-3e61-9f05-84c824627735.png "スクリーンショット 2014-12-11 12.57.42.png")

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

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'
                }
            }

        },

        // }}}

![スクリーンショット 2014-12-11 12.57.42.png](https://qiita-image-store.s3.amazonaws.com/0/30646/79476544-16c8-2f3d-2d3a-655667c7066f.png "スクリーンショット 2014-12-11 12.57.42.png")


![スクリーンショット 2014-12-11 13.10.58.png](https://qiita-image-store.s3.amazonaws.com/0/30646/becf3f2e-e521-2173-f295-46516ee581aa.png "スクリーンショット 2014-12-11 13.10.58.png")

無理矢理感が強いですが、なんとかなりました。  
responsiveプラグインにより、画面サイズの変更でsetLabelAlignが呼ばれ、
その中でlabelの位置を変更させています。


### まとめ

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

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

明日は sugaimasaruさんです。