We have a old application running with JSF 1.1, cannot upgrade due to client specification.
I would like to know is it possible to have a datatable with JSF 1.1 and upon clicking a button or link in datatable row open a dialog popup and do CRUD operation?
Thanks
Edit 1
I guess Apache Trinidad supports JSF 1.1. Can I do CRUD operation with Trinidad?
I think using Richfaces 3.1.6 (JSF 1.1 compatible) with the great A4J, will help you doing so:
<h:form id="myForm">
<rich:dataTable width="100%" style="border:none;margin-left:15px;" id="tableId" columnClasses="colClass"
value="#{managedBean.someList}" var="someVar">
<h:column> some content for this column </h:column>
<h:column>
<a4j:commandLink styleClass="linkClass" value="Delete" reRender="myForm:myModal" ajaxSingle="true" oncomplete="#{rich:component('myForm:myModal')}.show()" actionListener="#{managedBean.someMethodToUpdateDTO}">
<a4j:actionparam value="#{someVar.idForExample}" name="someName" assignTo="#{managedBean.someDTOObjectToBeUpdated.id}"/>
</a4j:commandLink>
</h:column>
</rich:dataTable>
<rich:modalPanel id="panel" width="350" height="100">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Are you really, really sure to delete this one!!! #{managedBean.someDTOObjectToBeUpdated.name}"></h:outputText>
</h:panelGroup>
</f:facet>
<a4j:commandButton styleClass="btnClass" value="Oui" ajaxSingle="true" oncomplete="#{rich:component('myForm:myModal')}.hide()" reRedner="myForm:tableId" action="#{managedBean.deleteIt}">
</rich:modalPanel>
</h:form>
someMethodToUpdateDTO is a method, in your managed bean that looks like this:
public void someMethodToUpdateDTO(ActionEvent event){
//In this method I just load the object from somewhere else
someDTOObjectToBeUpdated = someDAO.getObject(someDTOObjectToBeUpdated.getId());
//someDTOObjectToBeUpdated is an attribute of your managed bean, of course with its getter and setter
}
Hope this helps,
Cheers
Related
Assume we have the following JSP code:
<c:forTokens items="${someBean.aStringOfIntNumbersSeparatedBySemicolons}"
delims=";"
var="item"
varStatus="stat">
${item}
<c:if test="${!stat.last}">;</c:if>
<c:if test="${stat.count %5 == 0}">
<br/>
</c:if>
</c:forTokens>
Of which the output is rendered in rows with 5 columns each, like so:
How can I possibly do this with the JSF or Primefaces tags?
There is no direct equivalent, you should transform your token into a list in the managed bean and consume the list in the framework components.
List<String> tokens = Arrays.asList("car1,car2,car3,car4".split(","));
For such simple scenario you might not need the primefaces components. When you go for a Object Oriented model, you can take advantage of PF components to iterate through the list and present its fields using data binding. For instance:
DataList - For each Car type in the cars1 list, a line will be added in the list.
<p:dataList value="#{dataListView.cars1}" var="car" type="ordered">
<f:facet name="header">
Basic
</f:facet>
#{car.brand}, #{car.year}
</p:dataList>
DataTable - For each car in cars list, a row is added to the table component.
<p:dataTable var="car" value="#{dtBasicView.cars}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
Using such component framework you might speed your development focusing on the business logic instead of UI design.
The only working solution I've found
For now, the only working solution I've found lies partly in the JSF and partly in the back-end code:
Edit the back-end code so that it adds a <br/> after every fifth element of that String field aStringOfIntNumbersSeparatedBySemicolons.
Add escape="false" to the <h:outputText> tag that holds the data on the front end. (The default value is escape="true", which renders <br/> as <br/>)
In an edit screen, I'm using p:ajax to grab the selected value in an autocomplete field and fill in other fields in the form. But when ajax is running in question it is updating the information in the database table (update). How do I block this behavior? After all I should only do this when I clicked the save button.
Code:
<h:panelGroup>
<p:autoComplete id="demandaBeanDemandaLogradouroNome" value="#{demandaBean.demanda.logradouro}"
var="_item" minQueryLength="3" maxResults="15" required="true"
itemLabel="#{_item.nome}" itemValue="#{_item}" converter="#{logradouroBean.converter}"
completeMethod="#{logradouroBean.buscaLogradouro}" title="Busca pelo Logradouro">
<p:column>
<h:outputText value="#{_item.categoria.descricao}"/>
</p:column>
<p:column>
<h:outputText value="#{_item.nome}"/>
</p:column>
<p:ajax partialSubmit="true" immediate="true" event="itemSelect" update="demandaBeanDemandaBairro demandaBeanDemandaCruzamento"
listener="#{logradouroBean.buscaComplementoSelectEvent}"/>
</p:autoComplete>
<p:message for="demandaBeanDemandaLogradouroNome" styleClass="error"/>
</h:panelGroup>
I have found that what happens is that Hibernate synchronizes the persistent objects and if you change it it automatically updates in the database. To solve, I used an auxiliary object with the #Transient tag. Thanks.
I have a dynamic dataTable that adds and removes objects. This works fine when I don't use ajax. However, when I use ajax, a problem occurs. Adding values initially is fine. However, when I start deleting objects, when I delete the last object, the items list gets deleted as well and becomes null. I am using jsf 2.2 with primefaces. I'm not sure what's causing this problem. My code is as follows.
item.xhtml
<h:panelGroup id="list">
<h:dataTable value="#{item.items}" var="object">
<h:column>
<!-- Figure out what these facets are or delete them -->
<f:facet name="keys">Keys</f:facet>
<p:inputText value="#{object.x}" />
</h:column>
<h:column headerText="Values">
<f:facet name="values">Values</f:facet>
<p:inputText value="#{object.y}" />
</h:column>
<h:column>
<h:commandLink value="Delete" action="#{user.removeObject(object)}">
<f:ajax execute="#form" render="#form" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:commandButton value="add" action="#{user.addObject}">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
</h:panelGroup>
item.java
#ManagedBean
#ViewScoped
public class Item implements Serializable{
public void addObject(){
Pair<String,String> tempPair = new Pair<String,String>("","");
items.add(tempPair);
return;
}
public void removeObject(Pair<String,String> i){
items.remove(i);
return;
}
}
UPDATE 1
I tried using jsf 2.1 instead, changing my viewAction to preRenderView, and my code works fine.
I think ajax is missing update properties. Try this:
<f:ajax execute="#form" render="#form" update="#form"/>
This is a bug in jsf 2.2.0. I replaced javax-faces-2.2.0.jar with javax-faces-2.2.1.jar and the issue disappeared.
Alternatively, another solution is to replace the <f:ajax> above with:
<f:ajax execute="#form" render=":form:list">
Apparently, the ajax call works fine in jsf 2.2.0 as long as the the whole form is not rendered.
Richfaces 3.3.3, Jsf 1.2:
I have a a4j:form that uses some simple validation, mainly required="true" to ensure the form does not get submitted without some necessary data.
I also have some complex data to add (optionally) to the form, so I thought the best way to do this is to have a a4j:commandButton that displays a rich:modalPanel where the user can create the complex data set.
The created data is also displayed in a h:selectManyListbox that is reRendered when the modalPanel is closed.
That's the plan, at least. I have the following problems:
reRender works, but only if I prevent validation via immediate="true" - which in turn seems to prevent the selected data from the modalPanel to be present in the backing Bean
if I remove the immediate tag, the data gets updated, but only if there are no validation errors
What is the best way to get this to work the way I want? Is there another, better way?
UPDATE:
The Validation that fails is in some different part of the form, not in the data entered via the modalPanel, which is displayed in the Listbox
CODE:
modalPanel:
<rich:modalPanel id="addTrimming" domElementAttachment="parent" width="150" height="130">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Define Filter" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/images/close.gif" styleClass="hidelink" id="hidelinkAddTrimming"/>
<rich:componentControl for="addTrimming" attachTo="hidelinkAddTrimming" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<h:panelGrid id="trimsettings" columns="3">
<h:outputText value="Target:" style="font-weight:bold"/>
<h:inputText id="target" label="XML Filename" required="true" value="#{xmlCreator.trimTarget}">
</h:inputText>
<h:outputText value=""/>
<h:outputText value="Mode:"/>
<h:selectOneMenu value="#{xmlCreator.trimMode}">
<f:selectItem itemLabel="Quality" itemValue="quality"/>
<f:selectItem itemLabel="after Primer" itemValue="afterPrimer"/>
<f:selectItem itemLabel="fixed" itemValue="fixed"/>
<f:selectItem itemLabel="Median length" itemValue="median"/>
<f:selectItem itemLabel="Motif" itemValue="motif"/>
</h:selectOneMenu>
<h:outputText value=""/>
</h:panelGrid>
<h:panelGroup>
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" onclick="from:submit()">
<a4j:support event="oncomplete" ajaxSingle="true" immediate="true" reRender="trimsPanel"/>
</a4j:commandButton>
</h:panelGroup>
</rich:modalPanel>
relevant form part:
<h:outputText value="Trimming:"/>
<a4j:outputPanel id="trimsPanel">
<h:selectManyListbox id="trims" value="#{xmlCreator.selectedTrimmings}">
<f:selectItems value="#{si:toSelectTrimmingList(xmlCreator.trimmings)}"/>
</h:selectManyListbox>
</a4j:outputPanel>
<a4j:commandButton id="addTrimButton" immediate="true" value=" + Trimming">
<rich:componentControl for="addTrimming" attachTo="addTrimButton" operation="show" event="onclick"/>
</a4j:commandButton>
If you do it in one form than you should separate it into two: one will be your main form and another will be form inside modal panel. Thus you'll be able to submit modal panel independently of main form and your submit button in modal panel will look like this:
<a4j:commandButton value="OK" action="#{xmlCreator.createTrimming}" reRender="trimsPanel"/>
you should use process with immediate to send modalpanel's data to bean when closing panel with a a:commandButton or a:commandLink.
for this, modal panel data has to be valid as expected, so you will get valid new data and add it to h:selectManyListBox 's bean value and reRender h:selectManyListBox.
this should work. if not please post your a:form and modalPanel code full to check.
Rerendering is not working in my code:
<rich:simpleTogglePanel id="bookIncomeHeader1" value="#{myBean.ftBoookIncomelst}"
label="BOOK INCOME" bodyClass="STP" style="ReptxtBold Reptxt_LtPad"
switchType="server">
<rich:dataTable id="bookIncome" value="#{myBean.ftBoookIncomelst}" var="item"
rowKeyVar="row" first="0" width="100%">
<rich:subTable id="subBookIncome"value="#{item.txIncome}" var="income"
rowKeyVar="row">
<rich:column id="descrtiptionColumn" width="30%">
<h:outputText value="#{income.descriptionCell.value}"
rendered="#{!item.editableRow}"
style="#{income.descriptionCell.boldClass}" />
<rich:inplaceInput layout="block" required="true"
value="#{income.descriptionCell.value}"
rendered="#{item.editableRow}"
requiredMessage="Description at row #{row+1} wasn't filled."
changedHoverClass="hover" viewHoverClass="hover"
viewClass="inplace" changedClass="inplace"
selectOnEdit="true" editEvent="onclick" />
</rich:column>
In the above code I have proper id for datatable and I'm calling my ajax call using:
<rich:menuItem value="Add Manual Adjustment" id="addmanualadjust">
<a4j:support event="onclick" action="#{myBean.addNewDataItem}"
reRender="bookIncome">
<f:param name="rowNum" value="#{item.serialNum}"></f:param>
</a4j:support>
</rich:menuItem>
It's hitting the server and calling proper method and updating the required list, but it's not showing any response. Why is it not rendering? It does not show any exception on console either.
the a4j:support and the dataTable should be in the same <x:form>
try adding immediate="true" to the a4j:support to bypass validation errors.
Does it work if you rerender bookIncomeHeader1?
Max
http://mkblog.exadel.com