hifive / hifivemain

main repository
http://www.htmlhifive.com/
Other
40 stars 10 forks source link

単一プロパティに同期・非同期のチェックルールが混在する場合、エラーメッセージが正しく表示されない #598

Closed meganetaaan closed 5 years ago

meganetaaan commented 5 years ago

事象

FormControllerによる入力チェック機能において、

場合、同期のチェックに失敗しているにもかかわらず非同期のエラーメッセージのみが表示されてしまう。

環境

事象が再現するコード

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="jquery-2.2.4.js"></script>
    <script src="h5-1.3.1.dev.js"></script><!-- v2.3.2 -->
    <script src="SampleController.js"></script>
</head>

<body>
    <div class="root">
        <div class="msg" action="#"></div>
        <form id="form1">
            <div>
                <input name="userName" type="text" class="form-control" placeholder="ユーザ名" />
            </div>
            <button type="submit">送信</button>
        </form>
    </div>
</body>

</html>
//SampleController.js
(function ($) {
    function validateAsync() {
        var dfd = h5.async.deferred();
        setTimeout(function() {
            dfd.reject({
                valid: false,
                userId: 'value'
            });
        }, 0);
        return dfd.promise();
    }
    var rules = {
        userName: {
            size: [3, 10], // 同期バリデーション
            customFunc: validateAsync,
        }
    };

    var sampleController = {
        __name: 'SampleController',
        _formController: h5.ui.FormController,
        __meta: {
            _formController: {
                rootElement: '#form1'
            }
        },
        __ready: function() {
            this._formController.addOutput(['composition']);
            this._formController.addRule(rules);
            this._formController.setSetting({
                output: {
                    composition: {
                        container: this.$find('.msg'),
                        wrapper: 'div'
                    },
                }
            })
        },
        '#form1 submit': function (context) {
            context.event.stopPropagation();
            context.event.preventDefault();
        }
    };

    $(function() {
        h5.core.controller('.root', sampleController);
    });
})(jQuery);

スクリーンショット

size(同期), customFunc(非同期)両方のルールに違反しているので両方のエラーメッセージ(「userNameは3以上10以下の長さでなければいけません。」「userNameは条件を満たしません」)が出てほしいが、customFunc(非同期)のみ出ている

image

simdy commented 5 years ago

同期・非同期が混在しており同期バリデーションでエラーがあった場合、 誤ってvalidatingPropertiesに分類してしまい、同期バリデーションのエラー内容が含まれていなかった。 これを修正し、同期バリデーションでエラーがあった場合は (結果待ちの非同期バリデーションエラーがあった場合でも)ただちにinvalidPropertiesに分類するようにした。

また、この修正に伴い発生した下記のバグも修正した。
FormController側では「非同期結果待ちかどうか」をvalidatingPropertiesで見ていたが、 上記修正により同期エラーがあった場合invalidPropertiesに分類された状態でValidationResultが返ってくるようになったため 同期エラーがあったプロパティについて後からさらに非同期バリデーションエラーが発生した場合にその非同期バリデーションエラーが表示されなかった。 そこで、ValidationResultに内部的に_asyncWaitingPropertiesを用意し、これを見て判定するようにした。