Dan*_*man 11 javascript primefaces composite-component jsf-2 twitter-bootstrap
我有一个登录我的网站的问题,似乎在移动Chrome浏览器中显示(但适用于某些手机中提供的Web工具包浏览器).我正在努力尝试在平板电脑上进入"开发者模式",但我希望其他人遇到这个问题并且可以指出我正确的方向,同时我弄清楚如何实际调试它.
它是一个JSF2应用程序(Primefaces over Bootstrap2.2)作为UI.
我的表单看起来像这样(第二组'onblur'调用是故意看看是否有帮助 - 它没有):
<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>
Run Code Online (Sandbox Code Playgroud)
为了清楚起见,我可以使用Chrome/IE8 +/Firefox/Opera和移动设备登录桌面我只有Chrome的问题(我还没有尝试过iOS浏览器).密码提交不会复制到帖子之前隐藏输入的值.
这可能不是最好的设计,我愿意接受建议.拖动<h:inputText />组件会使样式变得复杂,因为我已经在Primefaces/Bootstrap上大量回复并搞砸了布局,因此这种"解决方案".
代替
<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');"
/>
Run Code Online (Sandbox Code Playgroud)
尝试不要在用户名和密码输入中设置 onblur 属性,因为 onBlur 属性在手机中可能会变得棘手。
相反,尝试在 onClick 事件中执行所有操作。我会在一个函数内完成所有操作:
<h:commandButton
class="btn"
value="Sign in"
actionListener="#{cc.attrs.loginAction}"
onclick="submitForm()"
/>
Run Code Online (Sandbox Code Playgroud)
以及函数内部:
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)
}
Run Code Online (Sandbox Code Playgroud)
我认为这将在移动版本中毫无问题地提交值。
顺便问一下,为什么要重复 _e 变量中的输入值?你不能使用原来的_b吗?有很多重复,很抱歉,如果我不明白你为什么这样做。
边注:
其他形式的 id“登录”也是如此
在 onClick 事件中,只需执行一项操作。某些浏览器不执行多个操作,因此,插入:
<h:commandButton
class="btn"
value="Sign in"
onclick="copyValue('userText_a', 'userText'); copyValue('passValue_a', 'passValue');"
actionListener="#{cc.attrs.loginAction}"
/>
Run Code Online (Sandbox Code Playgroud)
做这个:
<h:commandButton
class="btn"
value="Sign in"
onclick="submit()"
actionListener="#{cc.attrs.loginAction}"
/>
Run Code Online (Sandbox Code Playgroud)
您可以在提交函数中执行 copyValue 操作:
function submit()
{
copyValue('userText_a', 'userText');
copyValue('passValue_a', 'passValue');
}
Run Code Online (Sandbox Code Playgroud)
这样您将获得尽可能跨浏览器兼容的代码。
再次,如果可能的话,尽量避免使用 copyValue。干杯