11

Web サイトへのログインに問題があり、モバイル クローム ブラウザーで表示されるように見えます (ただし、一部の携帯電話で提供されている Web キット ブラウザーでは機能します)。私はタブレットで「開発者モード」に入ろうとしていますが、他の誰かがこの問題に遭遇し、実際にこれをデバッグする方法を見つけている間、正しい方向に向けることができることを願っています.

UIとしてのJSF2アプリケーション(Bootstrap2.2上のPrimefaces)。

私のフォームは次のようになります (「onblur」呼び出しの 2 番目のセットは、それが役に立ったかどうかを確認するために意図的に行われましたが、役に立ちませんでした):

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:composite="http://java.sun.com/jsf/composite" 
>
    <composite:interface>
        <composite:attribute name="user" />
        <composite:attribute name="pass" />
        <composite:attribute name="error" />
        <composite:attribute name="loggedIn" />
        <composite:attribute 
            name="loginAction" 
            method-signature="void actionListener(javax.faces.event.ActionEvent)"
        />
        <composite:attribute 
            name="logoutAction" 
            method-signature="void actionListener(javax.faces.event.ActionEvent)"
        />
    </composite:interface>

    <composite:implementation>
        <script type="text/javascript">
        function copyValue(sourceId, targetId){
            var source = '#{cc.attrs.id}:' + sourceId;
            var target = '#{cc.attrs.id}:' + targetId;

            var sourceEl = document.getElementById(source);
            var targetEl = document.getElementById(target); 

            targetEl.value = sourceEl.value; 
        };
        </script>
        <h:form class="navbar-form pull-right" id="login" prependId="false" rendered="#{not cc.attrs.error and !cc.attrs.loggedIn}">
            <h:panelGroup rendered="#{!cc.attrs.loggedIn}" layout="span">
                <h:inputHidden value="#{cc.attrs.user}" id="userText"/>
                <h:inputHidden value="#{cc.attrs.pass}" id="passValue"/>

                <input 
                    class="span2" 
                    type="text" 
                    placeholder="Username" 
                    id="#{cc.attrs.id}:userText_a"
                >
                </input>
                <input 
                    class="span2" 
                    type="password" 
                    placeholder="Password"
                    id="#{cc.attrs.id}:passValue_a"
                >
                </input>

                <h:commandButton 
                    class="btn" 
                    value="Sign in"
                    onclick="copyValue('userText_a', 'userText'); copyValue('passValue_a', 'passValue');"
                    actionListener="#{cc.attrs.loginAction}"
                />
                <!-- onblur="copyValue('userText_a', 'userText'); copyValue('passValue_a', passValue);" -->
            </h:panelGroup>
        </h:form>

        <h:form class="navbar-form pull-right" id="login_error" prependId="false" rendered="#{cc.attrs.error and !cc.attrs.loggedIn}">
            <h:panelGroup rendered="#{!cc.attrs.loggedIn}" layout="span" styleClass="control-group error" style="display:inline-block;">
                <h:inputHidden value="#{cc.attrs.user}" id="userText_e"/>
                <h:inputHidden value="#{cc.attrs.pass}" id="passValue_e"/>

                <input 
                    class="span2" 
                    type="text" 
                    placeholder="Username" 
                    id="#{cc.attrs.id}:userText_b"
                    onblur="document.getElementById('#{cc.attrs.id}:userText_e').value = this.value;"
                >
                </input>
                <input 
                    class="span2" 
                    type="password" 
                    placeholder="Password"
                    id="#{cc.attrs.id}:passValue_b"
                    onblur="document.getElementById('#{cc.attrs.id}:passValue_e').value = this.value;"
                >
                </input>

                <h:commandButton 
                    class="btn" 
                    value="Sign in"
                    actionListener="#{cc.attrs.loginAction}"
                    onclick="copyValue('userText_b', 'userText_e'); copyValue('passValue_b', 'passValue_e');"
                />
                <br />
                <span style="color:orange;">Login failed: Invalid username or password</span>               
            </h:panelGroup>
        </h:form>

        <h:form class="navbar-form pull-right" rendered="#{cc.attrs.loggedIn}"> 
            <h:panelGroup class="span2" style="display: inline-block;">
                <h:commandLink 
                    value="#{cc.attrs.user} | Sign Out" 
                    class="btn btn-primary"
                    actionListener="#{cc.attrs.logoutAction}"
                />
            </h:panelGroup>
        </h:form>
    </composite:implementation>
</html>

明確にするために、Chrome/IE8+/Firefox/Opera を使用してデスクトップにログインできます。モバイルでは Chrome のみに問題があります (iOS ブラウザーはまだ試していません)。パスワードの送信は、投稿前の隠し入力の値にコピーされません。

これは最良のデザインではないかもしれません。私は提案を受け付けています。コンポーネントをドラッグすると<h:inputText />、スタイリングが複雑になります。私はすでに Primefaces/Bootstrap に大量に返信しており、レイアウトを台無しにしてしまうため、この「回避策」があります。

4

1 に答える 1

1

それ以外の

            <input 
                class="span2" 
                type="text" 
                placeholder="Username" 
                id="#{cc.attrs.id}:userText_b"
                onblur="document.getElementById('#{cc.attrs.id}:userText_e').value = this.value;"
            >
            </input>
            <input 
                class="span2" 
                type="password" 
                placeholder="Password"
                id="#{cc.attrs.id}:passValue_b"
                onblur="document.getElementById('#{cc.attrs.id}:passValue_e').value = this.value;"
            >
            </input>

            <h:commandButton 
                class="btn" 
                value="Sign in"
                actionListener="#{cc.attrs.loginAction}"
                onclick="copyValue('userText_b', 'userText_e'); copyValue('passValue_b', 'passValue_e');"
            />

ユーザー名とパスワードの入力で onblur プロパティを設定しないようにしてください。携帯電話では onBlur プロパティが扱いにくくなる可能性があるためです。

代わりに、onClick イベント内ですべてを実行してみてください。私は1つの関数内ですべてを行います:

            <h:commandButton 
                class="btn" 
                value="Sign in"
                actionListener="#{cc.attrs.loginAction}"
                onclick="submitForm()"
            />

そして関数内:

function submitForm()
{
    var objUserText_e = document.getElementById('#{cc.attrs.id}:userText_e');
    var objUserText_b = document.getElementById('#{cc.attrs.id}:userText_b');

    var passValue_e = document.getElementById('#{cc.attrs.id}:userText_e');
    var passValue_b = document.getElementById('#{cc.attrs.id}:userText_b');

    objUserText_e.value = objUserText_b.value;
    passValue_e.value = passValue_b.value;

    /*
    copyValue('userText_b', 'userText_e'); copyValue('passValue_b', 'passValue_e');
    */

    // remove any return false
    // it will prevent the default event to be triggered (actionListener in this case)

}

これでモバイル版でも問題なく値が送信されると思います。

ところで、なぜ _e 変数の入力の値を複製するのでしょうか? 元の _b のものを使用できませんか? 重複がたくさんあります。理由がわからない場合は申し訳ありません。

サイドノート:

ID「login」の他の形式についても同じことが言えます

onClick イベントでは、アクションを 1 つ実行するだけです。一部のブラウザでは複数のアクションが実行されないため、以下を挿入します。

            <h:commandButton 
                class="btn" 
                value="Sign in"
                onclick="copyValue('userText_a', 'userText'); copyValue('passValue_a', 'passValue');"
                actionListener="#{cc.attrs.loginAction}"
            />

これを行う:

            <h:commandButton 
                class="btn" 
                value="Sign in"
                onclick="submit()"
                actionListener="#{cc.attrs.loginAction}"
            />

そして、submit 関数内で copyValue を実行できます。

function submit()
{
    copyValue('userText_a', 'userText');
    copyValue('passValue_a', 'passValue');
}

このようにして、最も互換性のあるコードを可能な限り得ることができます。

繰り返しますが、可能であれば copyValue を避けてください。乾杯

于 2013-01-20T14:38:21.757 に答える