I have a weird problem with jsf components (h:inputFile & h:selectBooleanCheckbox).
Both components receive focus, even when my mouse is somewhere else on the page. Here is the code:
<h:form id="logoUpload" enctype="multipart/form-data">
<div>
<h:outputLabel rendered="true">
<h:inputFile id="companyLogo" label="file" value="#{fileHandlerBean.part}" >
<f:validator validatorId="FileUploadValidator" />
</h:inputFile>
</h:outputLabel>
</div>
<div class="clear" />
<h:outputLabel rendered="true">
<div>
<div style="width: 5%">
<h:selectBooleanCheckbox id="acceptToULogo" value="#{companyEditController.confirmToU}">
<p:ajax event="change" update="buttonLogo" />
</h:selectBooleanCheckbox>
</div>
<div style="width: 95%">
<h:outputText value="Some Text " />
</div>
<br />
<h:commandButton id="buttonLogo" styleClass="formbutton" value="Upload"
action="#{companyEditController.companyLogoUpload()}"
actionListener="#{fileHandlerBean.uploadCompanyLogo()}"
disabled="#{!companyEditController.confirmToU}"/>
</div>
</h:outputLabel>
</h:form>
If I move the mouse over the h:outputText the checkbox receives focus.
I had the same problem with the h:inputFile tag. I solved it by surrounding it with a h:outputLabel tag, but unfortunately it doesn´t workd with the selectBooleanCheckbox.
Did somebody have the same problem in the past and knows a solution?
This is because everything is wrapped in the h:outputLabel tag. This outputLable is rendered as a plain label html element.
You can see form the W3C specification that anything inside the label will toggle the control
The element does not render as anything special for the user. However, it provides a usability improvement for mouse users, because if the user clicks on the text within the element, it toggles the control
To fix this, you need to replace the h:output label tag using a h:panelGroup layout="block" which renders a <div>:
<h:panelGroup layout="block" rendered="true">
<div>
<div style="width: 5%">
<h:selectBooleanCheckbox id="acceptToULogo" >
<p:ajax event="change" update="buttonLogo" />
</h:selectBooleanCheckbox>
</div>
<div style="width: 95%">
<h:outputText value="Some Text " />
</div>
<br />
<h:commandButton id="buttonLogo" styleClass="formbutton" value="Upload"/>
</div>
</h:panelGroup>
Related
I have such code as follow in my input.xhtml file which takes input from user. But this BootsFaces code is not working, Please Someone help me to solve this problem if any one faced it Before.
<b:form id="studentForm" styleClass="form-horizontal">
<h:panelGrid columns="1" cellpadding="5">
<b:inputText label="E-mail:" labelStyle="width:80px;">
<f:facet name="prepend">
<h:inputText value="#{studentBean.firstName}" styleClass="form-control" />
</f:facet>
</b:inputText>
</h:panelGrid>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<b:commandButton value="Create" action="#{studentBean.createStudentForm}" styleClass="btn btn-default" />
</div>
</div>
</b:form>
You are using the b:inputText incorrectly. You should not wrap a h:inputText in it. You can bind the value using the b:inputText tag:
<b:inputText label="First name:"
labelStyle="width:80px;"
value="#{studentBean.firstName}"/>
See also:
https://showcase.bootsfaces.net/forms/inputText.jsf (documentation).
https://github.com/TheCoder4eu/BootsFacesWeb (if you want to download the showcase and its examples).
Here is my view
<h:body>
<div id="header"></div>
<div id="upload">
<h:form id="frmMain" enctype="multipart/form-data">
<p:inputTextarea id="text" style="width: 99%" value="#{uploadfile.content}" placeholder="What are you thinking?"></p:inputTextarea>
<p:fileUpload auto="true" oncomplete="input()" id="fileIdPhoto" previewWidth="200" style="width: 100%" messageTemplate="{name}" fileUploadListener="#{uploadfile.upload}" mode="advanced" dragDropSupport="true"
multiple="true" update="messages" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
<p:messages id="messages" autoUpdate="true" closable="true" />
<p:menubar autoDisplay="false">
<p:menuitem />
<f:facet name="options">
<p:commandButton value="Publish" update="fileIdPhoto" icon="ui-icon-extlink" actionListener="#{uploadfile.uploadPhoto}">
</p:commandButton>
</f:facet>
</p:menubar>
</h:form>
</div>
<div id="body">
<div id="post_container">
<ul>
<ui:repeat value="#{image.allpost}" var="value">
<h:form id="form">
<li>
<div id="post">
<p:commandButton rendered="false" id="dynaButton" process="#this,form" value="Show" type="button" icon="ui-icon-extlink"/> cant not trigger it so I set render false
<p:menu overlay="true" trigger="dynaButton" my="left top" at="left bottom">
<p:submenu label="Ajax">
<p:menuitem value="Delete" icon="ui-icon-disk"/>
<p:menuitem value="Update" icon="ui-icon-arrowrefresh-1-w"/>
</p:submenu>
</p:menu>
<b>#{value.content}</b> <br/>
#{value.createtime} <br/>
<br />
<p:galleria value="#{image.getImgByID(value.id)}" rendered="#{not empty image.getImgByID(value.id)}" var="a" panelWidth="720" panelHeight="400" showCaption="true">
<h:graphicImage value="data:image/jpeg;base64,#{a.imgUrl}" style="width:100%;height:100% " alt="Image Description for #{a.imgName}" title="#{a.imgName}"/>
</p:galleria>
<p:rating value="#{value.rating}" stars="10" cancel="false"/>cant change those stars by clicking on it
</div>
<div id="post_ceperator"/>
</li>
</h:form>
</ui:repeat>
</ul>
</div>
</div>
</h:body>
What I am trying to do is change the value of p:rating tag and p:menu to trigger but its seem like my page is only submitting the first form. Also how can I submit a post and div that contains my post will automatically update?
In my opinion the problem is that your components inside of the ui:repeat have all the time the same id's for each iteration.
The way i used to define ids in loops like that was to add some sort of unique prefix or suffix to them based on some field of the data over which i am iterating:
<ui:repeat value="#{image.allpost}" var="value">
<h:form id="form_#{value.id}">
<li>
<div id="post_#{value.id}">
Now each of your components, including the form, which is highly likely to be the cause of your problem, will have its unique id for each of the loop repetition.
I am writing a composite component that is intended to wrap an input element, and augment it with an 'optional field' designation and h:message element below it.
Here is the component (in input.xhtml file):
<composite:interface/>
<composite:implementation>
<div>
#{component.children[1].setStyleClass(component.children[1].valid ? '' : 'inputError')}
<composite:insertChildren/>
</div>
<h:panelGroup styleClass="optional"
rendered="#{!component.parent.children[1].required}"
layout="block" >
#{msgs['common.optional.field']}
</h:panelGroup>
<h:message id="msgId"
for="#{component.parent.children[1].id}" errorClass="error"/>
</composite:implementation>
Again, the intended usage of the component is to wrap an h:input* element which is expected to be the first and immediate child of it in a using page.
In a using page I would then write:
<h:form id="f1">
<h:panelGrid border="0" columns="2" style="width: 80%">
<f:facet name="header">
<col width="40%" />
<col width="60%" />
</f:facet>
<h:outputLabel styleClass="sectionBody" for="i1"
value="Input 1"></h:outputLabel>
<my:input id="ii1">
<h:inputText id="i1" size="20" maxlength="20" tabindex="0"
required="true" label="Input 1">
</h:inputText>
</my:input>
<h:outputLabel styleClass="sectionBody" for="i2"
value="Input 2"></h:outputLabel>
<my:input id="ii2">
<h:inputText id="i2" size="20" maxlength="20" tabindex="0"
label="Input 2">
</h:inputText>
</my:input>
</h:panelGrid>
<br />
<h:commandButton value="Submit" tabindex="1">
<f:ajax listener="#{terminalImportBean.addTerminal}"
execute="#form" render="#form"/>
</h:commandButton>
</h:form>
This would work just fine using normal posts.
However if I add add f:ajax validation for "Input 1" (id="i1") and try to re-render the composite (ii1) using the following:
...
<h:outputLabel styleClass="sectionBody" for="i1"
value="Input 1"></h:outputLabel>
<my:input id="ii1">
<h:inputText id="i1" size="20" maxlength="20" tabindex="0"
required="true" label="Input 1">
<f:ajax listener="#{myBean.checkInput1}"
event="blur"
render="ii1"/>
</h:inputText>
</my:input>
...
I gen an error in the browser during ajax response processing:
malformedXML: During update: f1:ii1 not found
I tried using f1:ii1, :f1:ii1, but to no avail. When I use msgId or :f1:ii1:msgId it works. Does anybody know why?
I am using Mojarra 2.1.3
Thanks
That's because the composite component does by itself not render anything to the HTML. Only its children are been rendered to HTML. There does not exist any HTML element with ID f1:i11 in the generated HTML output. Open the page in browser, rightclick and View Source. Look in there yourself. There's no such element with that ID. JavaScript/Ajax is encountering exactly the same problem. It can't find the element in order to update it.
To solve this, you'd need to wrap the entire composite body in a HTML <div> or <span> and assign it an ID of #{cc.clientId} which basically prints UIComponent#getClientId().
<cc:implementation>
<div id="#{cc.clientId}">
...
</div>
</cc:implementation>
Then you can reference it as below:
<my:input id="foo" />
...
<f:ajax ... render="foo" />
You can even reference a specific composite component child.
<f:ajax ... render="foo:inputId" />
See also:
Is it possible to update non-JSF components (plain HTML) with JSF ajax?
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
I've comments that are displayed from an <ui:repeat> tag. An user can reply to to all comments with input fields that are displayed individually for each comment. However I can't manage to pass the value of the comment to the bean that deals with it. I thought about passing the UIInput value as described in the first answer [by balusC here][1]. The problem is that the content is empty because the action button is bound to every UIInput ( I believe so). I should sort of have a personal bound between each button and my UIInput. I think the code is gonna be more self-explanatory hopefully. :
<ui:repeat var="post" value="#{watchThread.listeFirstPosts}">
<h:outputText value="#{post.user.username}"/>
<div class="postContent">
<h:outputText value="#{watchThread.sanitize(post.content)}" />
</div>
<div class="replyAction">
<h:form>
<div class="inputAreaPostFast">
<p:inputTextarea id="reply2" value="#{watchThread.replyContent}" binding="#{inputReply}"/>
<div class="replyBtn">
---------- Here the third param is the issue --------------
<p:commandButton action="#{watchThread.sendReply(userNav.user, post, inputReply.value)}"/>
</div>
</div>
</h:form>
</div>
</ui:repeat>
Edit: This is the code that worked for me. (I think) I had a form that had no business of being in my ui:repeat tag. Also to bind the input see the answer/comment of balusC below. However I had to let the form tags inside and not outside as suggested.
<ui:repeat var="post" value="#{watchThread.listeFirstPosts}">
<div class="replyBlock">
<h:panelGroup id="username" style="cursor:pointer;">
<div class="profileimgForum">
<h:graphicImage styleClass="profilepicForum" value="/images/#{post.user.profilePic}" rendered="#{!empty post.user.profilePic}"></h:graphicImage>
<h:graphicImage styleClass="profilepicForum" library="images" name="profilepic1.jpg" rendered="#{empty post.user.profilePic}"></h:graphicImage>
</div>
<span class="posterTitle">
<h:outputText value="#{post.user.username}"></h:outputText> </span>
<h:outputText value=" #{watchThread.formatTimeReply(post.datePost)}"/>
</h:panelGroup>
<div class="replyContent">
<h:outputText value="#{watchThread.sanitize(post.content)}" style="pointer:cursor;"/>
</div>
<div class="replyAction">
<p:inplace id="facet" effect="none">
<f:facet name="output">
#{strings.Reply}
</f:facet>
<f:facet name="input">
<h:form>
<div class="inputAreaPostFast">
<p:inputTextarea id="reply2" cols="70" rows="7" value="#{watchThread.replyContent}" binding="#{inputReply}" maxlength="500"/>
<div class="replyBtn">
<p:commandButton update="growl" style=" margin-right: 2em;" value="#{strings.Reply}" action="#{watchThread.sendReply(userNav.user, post, inputReply)}"/>
</div>
</div>
</h:form>
</f:facet>
</p:inplace>
</div>
<ui:repeat var="areply" value="#{post.posts}">
#{areply.content} ----
</ui:repeat>
</div>
<!-- ####### Dialog username ######## -->
<p:overlayPanel for="username" id="usernamePanel" dynamic="true" showCloseIcon="true" appendToBody="1" dismissable="false">
<div class="dlgTopBlock">
<div class="dlgPicBlock">
<h:graphicImage styleClass="profilePicDialog" value="/images/#{post.user.profilePic}" rendered="#{!empty post.user.profilePic}"/>
<h:graphicImage styleClass="profilePicDialog" library="images" name="profilepic1.jpg" rendered="#{empty post.user.profilePic}"/>
</div>
<div class="dlgTopSubBlock"><div class="dlgTopTitle">
<h:graphicImage styleClass="flag" library="images/flags"
name="#{post.user.countryBean.iso2}.png"
rendered="#{! empty post.user.countryBean.iso2}"/>
<h:link value="#{post.user.username}" outcome="/user.xhtml">
<f:param name="username" value="#{post.user.username}"></f:param>
</h:link>
</div>
<div class="dlgRep">
<h:outputText value="#{post.user.reputation} #{strings.repPoints} "></h:outputText>
</div>
<div class="dlgTopStatus">
<h:outputText value="#{post.user.status}"/></div>
</div>
</div>
<div class="btnDlg">
<h:panelGroup rendered="#{userNav.isUserConnected and userNav.username != post.user.username}">
<p:commandButton value="#{usernavmsg.SendPM}" icon="ui-icon-mail-closed" onclick="PF('sendMsgDlg').show();"></p:commandButton>
<p:commandButton id="addFriend" value="#{friendBean.btnText}" action="#{friendBean.addFriend()}" update="growl addFriend" icon="#{friendBean.icon}"
rendered="#{friendBean.rendered}"/>
</h:panelGroup>
</div>
<p:dialog header="#{usernavmsg.SendingTo}: #{post.user.username}"
dynamic="true" modal="false" widgetVar="sendMsgDlg" minHeight="40">
<h:form>
<p:inputTextarea value="#{pMbean.title}" rows="1" cols="110" id="title" >
<f:passThroughAttribute name="placeholder" value="#{usernavmsg.Title}"/>
</p:inputTextarea><br/><br/>
<p:inputTextarea value="#{pMbean.message}" id="msg" rows="10" cols="110" autoResize="true">
<f:passThroughAttribute name="placeholder" value="#{usernavmsg.YourMsg}"/>
</p:inputTextarea><br/>
<p:commandButton style="float:right;" value="#{usernavmsg.Send}" action="#{pMbean.send(post.user)}"
onclick="PF('sendMsgDlg').hide();" icon="ui-icon-mail-closed" update="growl"></p:commandButton>
</h:form>
</p:dialog>
</p:overlayPanel>
<!-- ######### End of dialog user ######## -->
</ui:repeat>
The only visible mistake is the below:
<ui:repeat value="#{watchThread.listeFirstPosts}" var="post" ...>
<p:inputTextarea ... value="#{watchThread.replyContent}">
You're basically binding the value of the input field of every iteration to one and same backing bean property. So, every iteration round will override the value of the previous iteration round. This is not right. The value of the input field must be bound to the current iteration round. I.e. it should basically have been as below:
<ui:repeat value="#{watchThread.listeFirstPosts}" var="post" ...>
<p:inputTextarea ... value="#{post.replyContent}">
But, in this construct you actually don't need it. Just get rid of the value attribute altogether and rely on binding as you initially wanted to use.
Then, there's another mistake as pointed out in the comments: nesting forms. This is illegal in HTML. Don't write JSF code in such way that it produces illegal HTML. There would be another potential cause in form of a bug in Mojarra which only exposes in case you're using <f:ajax> in a nested <ui:repeat>. The solution to that would be using a fullworthy UIData component, such as <h:dataTable> or one of PrimeFaces grids.
I am writing a composite component that is intended to wrap an input element, and augment it with an 'optional field' designation and h:message element below it.
Here is the component (in input.xhtml file):
<composite:interface/>
<composite:implementation>
<div>
#{component.children[1].setStyleClass(component.children[1].valid ? '' : 'inputError')}
<composite:insertChildren/>
</div>
<h:panelGroup styleClass="optional"
rendered="#{!component.parent.children[1].required}"
layout="block" >
#{msgs['common.optional.field']}
</h:panelGroup>
<h:message id="msgId"
for="#{component.parent.children[1].id}" errorClass="error"/>
</composite:implementation>
Again, the intended usage of the component is to wrap an h:input* element which is expected to be the first and immediate child of it in a using page.
In a using page I would then write:
<h:form id="f1">
<h:panelGrid border="0" columns="2" style="width: 80%">
<f:facet name="header">
<col width="40%" />
<col width="60%" />
</f:facet>
<h:outputLabel styleClass="sectionBody" for="i1"
value="Input 1"></h:outputLabel>
<my:input id="ii1">
<h:inputText id="i1" size="20" maxlength="20" tabindex="0"
required="true" label="Input 1">
</h:inputText>
</my:input>
<h:outputLabel styleClass="sectionBody" for="i2"
value="Input 2"></h:outputLabel>
<my:input id="ii2">
<h:inputText id="i2" size="20" maxlength="20" tabindex="0"
label="Input 2">
</h:inputText>
</my:input>
</h:panelGrid>
<br />
<h:commandButton value="Submit" tabindex="1">
<f:ajax listener="#{terminalImportBean.addTerminal}"
execute="#form" render="#form"/>
</h:commandButton>
</h:form>
This would work just fine using normal posts.
However if I add add f:ajax validation for "Input 1" (id="i1") and try to re-render the composite (ii1) using the following:
...
<h:outputLabel styleClass="sectionBody" for="i1"
value="Input 1"></h:outputLabel>
<my:input id="ii1">
<h:inputText id="i1" size="20" maxlength="20" tabindex="0"
required="true" label="Input 1">
<f:ajax listener="#{myBean.checkInput1}"
event="blur"
render="ii1"/>
</h:inputText>
</my:input>
...
I gen an error in the browser during ajax response processing:
malformedXML: During update: f1:ii1 not found
I tried using f1:ii1, :f1:ii1, but to no avail. When I use msgId or :f1:ii1:msgId it works. Does anybody know why?
I am using Mojarra 2.1.3
Thanks
That's because the composite component does by itself not render anything to the HTML. Only its children are been rendered to HTML. There does not exist any HTML element with ID f1:i11 in the generated HTML output. Open the page in browser, rightclick and View Source. Look in there yourself. There's no such element with that ID. JavaScript/Ajax is encountering exactly the same problem. It can't find the element in order to update it.
To solve this, you'd need to wrap the entire composite body in a HTML <div> or <span> and assign it an ID of #{cc.clientId} which basically prints UIComponent#getClientId().
<cc:implementation>
<div id="#{cc.clientId}">
...
</div>
</cc:implementation>
Then you can reference it as below:
<my:input id="foo" />
...
<f:ajax ... render="foo" />
You can even reference a specific composite component child.
<f:ajax ... render="foo:inputId" />
See also:
Is it possible to update non-JSF components (plain HTML) with JSF ajax?
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"