I need a way to create editable table like this. I interested is it possible to use h:panelGrid to display and edit the data. From my previews post I saw that it's possible to simple JSF table, but is this possible with h:panelGrid?
<table>
<ui:repeat var="elem" value="#{yourMB.yourDataList}">
<tr>
<td>#{elem.userid}</td>
<td>
<h:outputText value="#{elem.name}"
rendered="#{not elem.editable}" />
<h:inputText value="#{elem.name}" rendered="#{elem.editable}" />
</td>
<td>
<h:outputText value="#{elem.telephone}"
rendered="#{not elem.editable}" />
<h:inputText value="#{elem.telephone}"
rendered="#{elem.editable}" />
</td>
<td>
<h:commandLink value="Edit" rendered="#{not elem.editable}"
action="#{yourMB.editAction(elem)}" />
</td>
</tr>
</ui:repeat>
</table>
<h:commandButton value="Save Changes" action="#{yourMB.saveAction}" />
The answer is "NO". Try to use h:dataTable instead of h:panelGrid.
Related
I am working with JSF 2.2 and Primefaces 6.0. I have a p:dataTable with different p:columns, and each column has many rows. I would like that, whenever column1 input changes, column2 input, in the same row, updates, however, it is not working; it doesn't render.
This is my xhtml code:
<p:dataTable value="#{myBean.objectsList}" var="object">
<p:column headerText="column1">
<table>
<tbody>
<ui:repeat value="#{object.subObjects}" var="object2">
<tr>
<td>
<c:set var="object3" value="#{object2.subObjects}"/>
<h:inputText id="value1#{myBean.toString(object3)}" value="#{object3.value1}">
<f:ajax event="change" listener="#{myBean.doSomething}"
execute="#this" render="#this"/>
</h:inputText>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</p:column>
<p:column headerText="column2">
<table>
<tbody>
<ui:repeat value="#{object.subObjects}" var="object2">
<tr>
<td>
<c:set var="object3" value="#{object2.subObjects}"/>
<h:inputText value="#{object3.value2}" disabled="disabled">
<f:ajax event="change" listener="#{myBean.doSomething2}"
execute="#this" render="value1#{myBean.toString(object3)}"/>
</h:inputText>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</p:column>
</p:dataTable>
Each object has many objects as a List.
In f:ajax tag of the first column (column1), you have given #this as value for the attribute render.
Instead, please try giving id of the component column2 or id of the p:dataTableitself.
I have an inputText and an inputTextArea in JSF (shown below) that I carry out an ajax action on. However, after my ajax event, the values remain in the input boxes. Is there a simple way to refresh these text boxes after the commandButton is involked? Thanks.
<table>
<tr>
<td><div class="white"><H2>Comments</H2></div>
<h:inputText class="inputboxes" id="username"
value="#{commentBean.comment.commentname}" size="20">
</h:inputText><br/><br/>
<h:inputTextarea rows="5" cols="55" id="comment" class="inputbox" value="#{commentBean.comment.commentText}"
size="20" /></td>
</tr>
<tr>
<td></td>
<td><h:commandButton id="update"
action="#{commentBean.addComment(searchBean.companyId)}" class="myButton2" value="Add Comment" >
<f:ajax execute="#form" render=":results"/>
</h:commandButton></td>
</tr>
</table>
</h:form>
<h:form id="results">
<table>
<tr>
<td>
<h:dataTable value="#{commentBean.viewComments(searchBean.companyId)}" var="c">
<h:column>
<div class="commentsbox">#{c.commentText}</div>
</h:column>
<h:column>
<div class="boldfont">#{c.commentdate}</div>
</h:column>
<td><h:column>
<div class="commentname">#{c.commentname}</div>
</h:column>
</td>
</h:dataTable>
</td>
</tr>
</table>
In your view :
<f:ajax execute="#this" render=":results, username, comment"/>
In your backing bean, in the addComment() method :
comment.setCommentname(null);
comment.setCommentText(null);
or simply (I guess only)
comment = null;
I have this JSF table which I use to display data and to edit data:
<table>
<ui:repeat var="ud" value="#{DCProfileTabGeneralController.dcData}">
<tr>
<td>Datacenter Type</td>
<td>
<h:outputText value="#{ud.type}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.type}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Date Added</td>
<td>
<h:outputText value="#{ud.dateAdded}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText styleClass="datepicker" value="#{ud.dateAdded}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Hour Added</td>
<td>
<h:outputText value="#{ud.hourAdded}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.hourAdded}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Date Deployed</td>
<td>
<h:outputText value="#{ud.dateDeployed}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText styleClass="datepicker" value="#{ud.dateDeployed}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
<tr>
<td>Hour Deployed</td>
<td>
<h:outputText value="#{ud.hourDeployed}"
rendered="#{not DCProfileTabGeneralController.editable}" />
<h:inputText value="#{ud.hourDeployed}" rendered="#{DCProfileTabGeneralController.editable}" />
</td>
</tr>
</ui:repeat>
</table>
This solution works fine but I want to extend it this way: I want to click on button which sets the edit flag to true. When I move the mouse over the value of the table the outputText to change to inputText.
And one more simple question. How I can add bottom padding to all fields globally?
I suggest you to use Richfaces library and use <rich:inplaceInput> component as below.
<rich:inplaceInput value="hhhh" editEvent="onmouseover"/>
However if you still like to stick to javascript this is a concept.
<h:form id="myForm">
<h:outputText value="aaa" id="outText"/><br/>
<h:inputText value="aaa" style="display:none;" id="inText" />
</h:form>
This is the javascript code
<script>
window.onload = function() {
var outputText = document.getElementById("myForm:outText");
var inputText = document.getElementById("myForm:inText");
outputText.onmouseover = function() {
outputText.style.display = 'none';
inputText.style.display = '';
}
inputText.onblur = function() {
outputText.style.display = '';
inputText.style.display = 'none';
}
};
</script>
Since you are using a ui:repeat, you should change the javascript code accordingly.
I'm trying to nest a table inside a h:panelGrid component, and h:selectOneMenu is screwing-up the formatting by closing off the cell it appears within and creating a new (and unwanted) row.
My code looks something like this:
<h:panelGrid columns="2">
[Other rows that work just fine]
<h:outputText value="Match [Stuff] to [More Stuff]:" />
<table>
<tr>
<th>[Stuff]</th>
<th>[More Stuff]</th>
</tr>
<tr>
<td>
<h:outputText value="Manually Created First Element of Stuff" />
</td>
<td>
<h:selectOneMenu value="#{bean.moreStuffSetting}">
<f:selectItem itemLabel="--None--" itemValue="" />
<f:selectItem itemLabel="Manual First Choice" itemValue="manual" />
<f:selectItems
value="#{bean.listOfMoreStuff}"
var="moreStuff"
itemLabel="#{moreStuff.name}"
itemValue="#{moreStuff.value}" />
</h:selectOneMenu>
</td>
</tr>
<ui:repeat value="#{bean.listOfStuff}" var="stuff">
<tr>
<td>
<h:outputText value="#{stuff.name}" />
</td>
<td>
<h:selectOneMenu value="#{bean.moreStuffSetting}">
<f:selectItem itemLabel="--None--" itemValue="" />
<f:selectItem itemLabel="Manual First Choice" itemValue="manual" />
<f:selectItems
value="#{bean.listOfMoreStuff}"
var="moreStuff"
itemLabel="#{moreStuff.name}"
itemValue="#{moreStuff.value}" />
</h:selectOneMenu>
</td>
</tr>
</ui:repeat>
</table>
</h:panelGrid>
The problem occurs with that first h:selectOneMenu element. (The h:selectOneMenu element inside ui:repeat is doing exactly what I expect it to, however.) I'm expecting "Manually Created First Element of Stuff" and that drop-down to appear as two cells in the same row. However, this is what's showing up in the generated HTML:
<tr>
<td>Manually Created First Element of Stuff</td>
<td>
</td>
<td></td>
</tr>
<tr>
<td><select...
Two rows. However, in the nested one below, I get this:
<tr>
<td>[Label I'm expecting]
</td>
<td><select...
... which is exactly how I expected it to behave.
What am I doing wrong? Am I misusing JSF somehow? Is there some face-palm-worthy typo in there I'm not seeing?
The <h:panelGrid> picks the first sibling in the JSF component tree to start a new table cell. The plain HTML <table> element which you've there isn't a JSF component.
Wrap it in a <h:panelGroup>.
<h:panelGrid columns="2">
<h:outputText value="Match [Stuff] to [More Stuff]:" />
<h:panelGroup>
<table>
...
</table>
</h:panelGroup>
</h:panelGrid>
An alternative is to just use <h:dataTable> instead.
In my application I have implemented an employee search functionality using the RichFaces 3.3 modal panel on Facelets. I'm trying to make this reusable across my application, so I have added the following code in facelet-taglib_1_0.xml
<tag>
<tag-name>employeeSearch</tag-name>
<source>employee-search.xhtml</source>
</tag>
The xhtml page contains the following components
search input field
search button
result datatable
I have also mapped a backing bean.
My issue is that I'm not able to get the value from the search input field
I wonder whether the approach given above is correct or if there's any better approach for this?
Thanks for your reply Arjan...i tried but result not binding in result datatable list. my code is here.
EmployeeSearchBean is request scope.
Calling reusable tag code :
<foo:employeeSearch orgSearchId="empHistSearch" bean="#{EmployeeSearchBean}" action="findEmployee" renderedVal="#{empHist.editable}" />
Model panel code :
<a4j:jsFunction name="submit" action="#{bean[action]}" />
<rich:modalPanel id="orgUnitSearchPanel_empHistSearch" autosized="true" width="450">
<f:facet name="header">
<h:outputText value="#{messages.mepit_OE_Search}" />
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/pics/buttons/fenster_schliessen.gif" id="hideOrgUnitSearchPanel_#{orgSearchId}" styleClass="hidelink" />
<rich:componentControl for="orgUnitSearchPanel_#{orgSearchId}" attachTo="hideOrgUnitSearchPanel_#{orgSearchId}" operation="hide" event="onclick" />
</h:panelGroup>
</f:facet>
<table class="dispinputTable" cellspacing="2" cellpadding="0">
<tr>
<td style="width: 75px;">
<h:outputText value="#{messages.mepit_OE}" />
</td>
<td>
<h:inputText id="empHist_oeExecutingName" value="#{EmployeeSearchBean.empSearchCriteria}" styleClass="text" size="60" />
</td>
<td>
<a4j:commandButton styleClass="mepitButtons" onclick="submit();" value="#{dbMessages.db_search}" title="#{dbMessages.db_search}" reRender="orgUnitDT#{orgSearchId}" />
</td>
</tr>
<tr>
<td colspan="3" >
<rich:extendedDataTable width="425px" height="150px"
id="orgUnitDT#{orgSearchId}" cellspacing="0" cellpadding="0" border="0"
styleClass="inhalt" var="oeLst" value="#{EmployeeSearchBean.employeeList}" rowClasses="row0, row1">
<rich:column width="370px;" align="left">
<f:facet name="header">
<h:outputText value="#{messages.mepit_OE}" />
</f:facet>
<h:outputText id="empHist_OE" value="#{oeLst.name}" />
</rich:column>
<rich:column width="55px;">
<f:facet name="header">
<h:outputText value="#{messages.mepit_select}" />
</f:facet>
<h:commandLink value="" styleClass="edit">
<f:setPropertyActionListener value="#{oeLst}" target="#{SkillPM.executingOrgUnit}" reRender="empHist_orgUnit" />
</h:commandLink>
<h:commandLink styleClass="edit" onclick="#{rich:component(mepit:concat(orgSearchId,'orgUnitSearchPanel'))}.hide(); submit(); return false;" />
</rich:column>
</rich:extendedDataTable >
</td>
</tr>
</table>
</rich:modalPanel>
One thing that's immediately open for improvement is that you should not add your own tags to what looks like the standard facelets taglib file. Leave that file alone and create your own file.
If you pass a value binding to your tag, and bind your search input field to this, then it should work:
<foo:employeeSearch myValue="#{yourBackingBean.someValue}"/>
And then in employee-search.xhtml:
<h:inputText value="#{myValue}" />
Feel free to use some other name instead of myValue. The point is that the attribute name you use on your custom tag should match what the input text component binds to.