2012年7月27日金曜日

show_errorsの表示をちょっと変えてHTML5風に

題名はかなり大げさなこと書いてますが、jQueryのプラグインを久しぶりに作ってみようと思っていま勉強中のFuelPHPと合わせて適当にいじってみました。

※下に書いてあることは別にプラグインを作らなくてもCSSだけでどうにでもなります・・・ただプラグインを作ってみたかっただけです。


HTML5を使って input に required 属性を付けると

こんなかんじで格好いいです。
でもこれは HTML5 を使ってるんで validation したあとのエラーメッセージとか至って普通に表示されます。(Email アドレスの記述が間違っている場合のエラー)


これを HTML5 風に変えてみよう・・・
(いろいろめんどくさくなってきたんで途中でやめましたが・・・)

簡単にやったこと

  • Formクラスを使って input を生成
  • Validationクラスをちょっとだけ修正
  • ConfigのValidationにopen_errorを追加
  • jQueryプラグイン作って埋め込む

まず、input の生成。これは普通。(required属性はつけません)
<?php echo Form::input('name', '名前'); ?>

次に、fuel/core/classes/validation.php と fuel/core/classes/validation.error.php を修正します。

fuel/core/classes/validation.php 行560
// $output .= $options['open_error'].$e->get_message().$options['close_error'];
$output .= $e->_replace_tags($options['open_error']).$e->get_message().$options['close_error'];

open_error のタグをエラーメッセージと同じように置換するようにメソッドを呼び出します。が、_replace_tagsは protected なんで public に変更しました。

fuel/core/classes/validation/error.php 行113
// protected function _replace_tags($msg)
public function _replace_tags($msg)

これでOK。
つぎに、fuel/app/config/config.php の validation に open_error を以下のように追加。
'validation' = array(
    'open_error' => '<li class="error_:field">',
);

上の :field の部分は validation や input で指定している id になります。

これであとはjQueryのプラグインを埋め込んで実装するだけです。
jquery.validation.js を作って中身は以下
(function($){
    function Validation() {
        this._defaults = {
            form_identifier: 'form_',
            error_identifier: 'error_',
        };
        this._target = null;
        
        this.errors = {};
    }
    
    $.extend(Validation.prototype, {
        _attach: function(element) {
            this._target = element;
            this._target.css('display', 'none');
            
            this._errors = this._get_errors();
            for (i = 0; i < this._errors.length; i++) {
                this._create_message(this._errors[i]);
            }
        },
        _get_errors: function() {
            errors = [];
            
            $("li", this._target).each(function(idx, val) {
                error = {};
                error['id'] = $(val).attr('id')
                                .replace($.validation._get('error_identifier'), '');
                error['text'] = $(val).text();
                
                errors.push(error);
            });
            
            return errors;
        },
        _create_message: function(error) {
            e = $('<div>')
                    .addClass('validation_message')
                    .text(error.text)
                    .css('display', 'none');
            
            t = $('#'+this._get('form_identifier')+error.id);
            t.after(e);
            
            e.css({
                'display': 'inline',
                'position': 'absolute',
                'top': t.position().top + (t.outerHeight() - e.outerHeight()),
                'left': t.position().left + t.outerWidth() + 10,
            });
        },
        _get: function(key) {
            return this._defaults[key];
        },
    });
    
    $.fn.validation = function(options) {
        $.extend($.validation._defaults, options);
        $.validation._attach(this);
        return this;
    }
    
    $.validation= new Validation();
    window.VALIDATION = $;
    
})(jQuery);

コメントも何もないですがshow_errors()で表示している内容をとってきてそれぞれのinputの横に出してるだけです。(汚いソースですみません)

使うときはこんなかんじ。
<div class="error">
    <?php echo $validation->show_errors(); ?>
</div>

<?php echo Asset::js('jquery-1.7.2.min.js') ?>
<?php echo Asset::js('jquery.validation.js') ?>
<script type="text/javascript">
    $(document).ready(function() {
        $('div.error').validation();
    });
<script>


こんなかんじで表示されます。


最初にも言った通り、べつにプラグインの必要はないです。
それぞれの項目の場所で
<?php echo $valication->error('name'); ?>

とかしてこれにスタイルをつければ同じことできます・・・



0 件のコメント:

コメントを投稿