JSF and Ajax update ui:repeat not working without loading the data from database - jsf-2

I am using Mojarra 2.3 JSF on tomcat with Weld. My problem is whenever i save a data to the database, the newest data being save doesn't show up, expert i load the data after saving it then it works. Below are my code.
//This is my jsf page
<h:panelGroup layout="block" id="panelBlock">
<ui:repeat value="#{projectBean.projectList}" var="project">
<h:outputText value="#{project.title}" />
<h:outputText value="#{project.content}" />
</ui:repeat>
</h:panelGroup>
<h:commandLink action="#{ProjectBean.save()}">
<f:ajax execute="#form" render="panelBlock" />
</h:commandLink>
#This is my ViewScoped
private Project project
private List<Project> projectList;
#PostConstruct
private void init() {
projectList = projectService.findAll();
}
# Setter and getter
public void save() {
projectService.save(project)
}
#it works only after saving it i load the data from the database
public void save() {
projectService.save(project)
projectList = projectService.findAll();
}

You can use primefaces poll https://www.primefaces.org/showcase/ui/ajax/poll.xhtml for update data periodically.

Related

Save and update on same xhtml is not working in primefaces

Hi i tried the following functionality using primefaces.
In my xhtml i have a input field which takes input and saves into db.After completion of save i display the saved data in data table of primefaces.
Upto now works fine.now i add single selection to datatable .when user click on the row i update the same input column with selected data.
For this i use the following code
<h:form id="form">
<p:growl id="messages" />
<p:panel id="panel" header="Currency">
<h:panelGrid columns="2" id="currencyGrid">
<p:outputLabel value="Currency :"/>
<p:inputText value="#{currencyBean.currencyMaster.currDesc}"/>
</h:panelGrid>
<p:commandButton value="Add" action="#{currencyBean.saveCurrency}"
update="currencytable">
</p:commandButton>
<p:dataTable id="currencytable" var="cur"
value="#{currencyBean.currencyList}" widgetVar="dlg"
selection="#{currencyBean.currencyMaster}"
selectionMode="single" rowKey="#{cur.currId}">
<p:ajax event="rowSelect" listener="#{currencyBean.onRowSelect}"
update=":form:currencyGrid" />
<p:column headerText="ID" style="font-size:12px;">
<h:outputText value="#{cur.currId}" />
</p:column>
<p:column headerText="Description" style="font-size:12px;">
<h:outputText value="#{cur.currDesc}" />
</p:column>
</p:dataTable>
</h:form>
And My Bean code is:
#managedBean
#viewScoped
#component
public class CurrencyBean implements Serializable{
private static final long serialVersionUID = 1L;
#Autowired
private CurrencyMaster currencyMaster;
private List<CurrencyMaster> currencyList;
public CurrencyMaster getCurrencyMaster() {
return currencyMaster;
}
public void setCurrencyMaster(CurrencyMaster currencyMaster) {
this.currencyMaster = currencyMaster;
}
public void saveCurrency(){
try{
currencyService.saveCurrency(currencyMaster);
}catch(Exception e){
e.printStackTrace();
}
}
#PostConstruct
public void currencyList(){
setCurrencyList(currencyService.getCurrencyList());
}
public void onRowSelect(SelectEvent event) {}
public void onRowUnselect(UnselectEvent event) {}
}
So when i click on currrencytable row the input field populated properly and update operation also.
The problem is when i directly enter the data into input column my globalMaster property is going to be null.
And the following error is occured;
attempt to create saveOrUpdate event with null entity
I change the scopes of the bean but i did not find the solution.
And i find more solutions for the above exception but my problem is the new values are does not set to currencymaster.
Is there any mistake i done in this context.please guide me..

#viewScoped data bean survives after navigation to another pages (views) with Spring Web Flow and JSF-2

I'm using Spring Web Flow and JSF-2.
The fact is strange and incomprehensible to me.
I have a main page, a typical index.
And I have and actionView with some filters (filtering will be made with an ajax calling) and a table for displaying the results according to filter info.
The back bean for this action is definied as #ViewScoped.
If, at first, I navigate to index after filtering some data and then, later, I return to the action view I don't expect to found the last search displayed, I expect an empty view, but the filters are not empty and data result is filtered.
Why? If I'm defining a #ViewScope is due to I expect the back bean information has to be deleted when I change the view (and index is another view in my case) but I must be making some mistake.
Here is my code:
My parent-flow (simpifying):
<view-state id="index" view="../index.xhtml" redirect="true" popup="true"/>
<view-state id="action1Flow" view="flowRedirect:action1-flow" />
<global-transitions>
<transition on="home" to="index" />
<transition on="action1" to="action1Flow" />
</global-transitions>
action1-flow: (start-state="action1View")
<view-state id="action1View" view="../views/action1View.xhtml" redirect="true" popup="true"/>
action1View.xhtml: (Simplifying, one filter -> table results)
...
<p:panel id="filter" header="Filter example">
<h:panelGrid columns="2">
<h:outputLabel for="dataFilter" value="Filter"/>
<p:inputText id="dataFilter" value="#{action1View.dataValue}"/>
<p:ajax event="keyup" listener="#{action1View.filterData()}" update="table"/>
</p:inputText>
</h:panelGrid>
</p:panel>
<p:panel id="display" header="Data filtered">
<p:dataTable id="table" var="data" value="#{action1View.resultData"
selection="#{action1View.selectedData}" rowKey="#{data.dataValue}">
<p:column headerText="#{msg.id}" sortBy="#{data.dataValue}">
<h:outputText value="#{data.dataValue}" />
</p:column>
</p:dataTable>
</p:panel>
...
<p:commandButton value="Go to index" action="home"/>
...
and action1View.java, the back bean:
#ManagedBean
#ViewScoped
#Component("action1View")
public class Action1View implements Serializable {
static final long serialVersionUID = 42L;
List<ExampleBean> resultData = null;
ExampleBean selectedData = null;
Integer dataValue;
public ExampleBean getSelectedData() {
return selectedData;
}
public void setSelectedData(ExampleBean selectedData) {
this.selectedData = selectedData;
}
public Integer getDataValue() {
return dataValue;
}
public void setDataValue(Integer dataValue) {
this.dataValue = dataValue;
}
public void filterData() {
// Some logic
resultData = xxxxx;
}
}
index.xhtml:
...
<p:commandButton value="Go to index" action="action1"/>
...
Sorry for my english and ...
Greetings!
I have found the GAP!
My bean, apart from #ViewScoped annotation, is also defining (as you can see in the code) with this annotation: #Component("action1View") without apparent reason.
The fact is by removing this annotation I got everything to work properly.
I think that is because the Component behaviur overlays ViewScoped one doing that only one bean for each defined class can be created, and, becauso of this, information stays in time (until the session ends or the application was closed).
But it would be great if someone give more and richer information about it.

Selection doesn't propagate to backing bean with PrimeFaces datatable

I just started learning JSF and PrimeFaces, and I'm having a hard time trying to get PrimeFaces' datatable to work. I have a checkbox-based selection mechanism (more than one row can be selected at the same time), so that clicking on the "Delete selected users" button triggers a method call to the backing bean to delete the corresponding users from the database.
The problem is that the selected rows are not stored in the backing bean's selectedUsers array, and I can't understand why, since my code is exactly the same as the one hosted on PrimeFaces' ShowCase. As a consequence, the button successfully triggers the confirmation dialog, but no user ever gets deleted from the system. Does anyone have any advice?
Thank you in advance!
xhtml file
<h:form id="tableForm">
<p:dataTable id="userList" var="user" value="#{userListBean.userList}"
selection="#{userListBean.selectedUsers}" rowKey="#{user.username}">
<f:facet name="header">User list</f:facet>
<p:column selectionMode="multiple" style="width:2%"/>
<!-- data columns here, working just fine -->
<f:facet name="footer">
<p:commandButton value="Delete selected users" icon="ui-icon-trash" action="#{userListBean.deleteSelectedUsers()}">
<p:confirm header="Deletion confirmation" message="Are you sure you want to delete #{fn:length(userListBean.selectedUsers)} users?" icon="ui-icon-alert" />
</p:commandButton>
Registered users: #{fn:length(userListBean.userList)}
</f:facet>
</p:dataTable>
<p:confirmDialog global="true" showEffect="fade">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:form>
Backing Bean
(userMgr handles persistence on the server, it should have nothing to do with my issue)
#ManagedBean(name="userListBean")
#ViewScoped
public class UserListBean {
#EJB
private UserManager userMgr;
private List<UserDTO> userList;
private UserDTO[] selectedUsers;
public UserListBean() {
}
public void deleteSelectedUsers() {
for(UserDTO u : selectedUsers)
userMgr.deleteUser(u.getUsername());
setUserList(userMgr.retrieveAllUsersDTO());
}
public List<UserDTO> getUserList() {
if(userList == null)
setUserList(userMgr.retrieveAllUsersDTO());
return userList;
}
public void setUserList(List<UserDTO> userList) {
this.userList = userList;
}
public List<UserDTO> retrieveUserList() {
return userMgr.retrieveAllUsersDTO();
}
public UserDTO[] getSelectedUsers() {
return selectedUsers;
}
public void setSelectedUsers(UserDTO[] selectedUsers) {
this.selectedUsers = selectedUsers;
}
}
(As a side question: the #{fn:length(userListBean.selectedUsers)} EL expression always returns 0. I used to think it was because of the broken selection mechanism, but could it be because the array is still empty when the confirmation dialog is rendered?)
You need to activate event rowSelect by adding <p:ajax event="rowSelect"/> to dataTable.

f:ajax not re rendering target DOM element (JBoss error?)

I am running JBoss 7.1.0.Final with the default JSF 2.1 .
I have been having problems getting the render attribute of a f:ajax to work
Here is my code
<h:form>
<h:panelGrid>
<h:inputText value="#{bean.text}" >
<f:ajax event="keyup" render="text"/>
</h:inputText>
<h:outputText id="text" value="#{bean.text}" />
</h:panelGrid>
</h:form>
With a bean:
#ManagedBean(name = "bean")
public class Bean
{
private String text;
public String getText()
{
return text;
}
public void setText(String text)
{
this.text = text;
}
}
The page renders but the value entered in the inputtext does not render as outputtext.
There does seem to be some interaction with the server as I get
JBAS010152: APPLICATION ERROR: transaction still active in request with status 0
happening on each keyup event?
Note that I am running this within Seam 2.3

dynamic adding radio and InputText in jsf

i am getting problem in editing in textBox which are generated dynamically.
see my code.
<h:form>
<h:panelGroup>
<h:panelGrid columns="2">
<h:panelGrid columns="1">
<h:selectOneRadio id="radio1" value="#{dynamicBean.radiovalue}" layout="pageDirection" >
<f:selectItems value="#{dynamicBean.objectList}" var="k1" itemValue="#{k1.value}" itemLabel="" />
</h:selectOneRadio>
</h:panelGrid>
<h:panelGrid columns="1" rowClasses="raw1">
<c:forEach items="#{dynamicBean.objectList}" var="k3">
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" >
</p:inputText>
</c:forEach>
</h:panelGrid>
<h:commandButton value="add new" action="#{dynamicBean.addNew}"/>
</h:panelGrid>
</h:panelGroup>
</h:form>
and this is my bean.
#ManagedBean
#ViewScoped
public class DynamicBean implements Serializable{
private String radiovalue;
private List<Pojo> objectList=new ArrayList<Pojo>();
int i=0;
private Pojo single=new Pojo();
public DynamicBean() {
System.out.println("In Cons");
if(objectList.isEmpty())
{
Pojo p1=new Pojo();
p1.setName("Name-"+i);
p1.setValue("Value-"+i);
p1.setTextvalue("Text-"+i);
objectList.add(p1);
i++;
setRadiovalue(p1.getValue());
}
}
public void addNew()
{
Pojo p1=new Pojo();
p1.setName("Name-"+i);
p1.setValue("Value-"+i);
p1.setTextvalue("Text-"+i);
objectList.add(p1);
i++;
setRadiovalue(p1.getValue());
}
public void ajaxEvent(ValueChangeEvent e)
{
System.out.println("New:"+e.getNewValue());
System.out.print("Old:"+e.getOldValue());
}
following are three variable in Pojo with getter and setter
private String name;
private String value;
private String textvalue;
biggest confusion is i can change first object value on in text box but i cant change the value of new generated objects.
Thanks.
Your concrete problem is caused because you're using JSTL <c:forEach> tag which runs during view build time while you're using a view scoped bean. View scoped beans are stored in the view state. When you submit the form to the server, the view state will be restored, but the original view scoped bean isn't available yet at that moment and thus a new one will be created (thus, with all properties set to default!). After restoring the view, the original view scoped bean will be put back in scope, overriding the temporary one.
You need a fullworthy JSF UI component instead of a JSTL tag. For this particular purpose, you need the <h:dataTable>.
Replace
<h:panelGrid columns="1" rowClasses="raw1">
<c:forEach items="#{dynamicBean.objectList}" var="k3">
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" >
</p:inputText>
</c:forEach>
</h:panelGrid>
by
<h:dataTable value="#{dynamicBean.objectList}" var="k3" rowClasses="raw1">
<h:column>
<p:inputText value="#{k3.textvalue}" valueChangeListener="#{dynamicBean.ajaxEvent}" />
</h:column>
</h:dataTable>
See also:
JSTL in JSF2 Facelets... makes sense?
Unrelated to the concrete problem, you've some code duplication there in the constructor. Just call addNew() method in there. I'd also remove the instance variable i as that makes no sense. Just use a local one instead which get initialized with List#size().
public DynamicBean() {
addNew();
}
public void addNew() {
Pojo p1 = new Pojo();
int i = objectList.size();
p1.setName("Name-" + i);
p1.setValue("Value-" + i);
p1.setTextvalue("Text-" + i);
objectList.add(p1);
setRadiovalue(p1.getValue());
}

Resources